use of org.axe.bean.mvc.Handler in project Axe by DongyuCai.
the class DispatcherServlet method service.
@Override
public void service(HttpServletRequest request, HttpServletResponse response) {
String contentType = ContentType.APPLICATION_JSON.CONTENT_TYPE;
String characterEncoding = CharacterEncoding.UTF_8.CHARACTER_ENCODING;
List<Filter> doEndFilterList = null;
try {
//获取请求方法与请求路径
String requestMethod = RequestUtil.getRequestMethod(request);
String requestPath = RequestUtil.getRequestPath(request);
if (requestPath != null && requestPath.equals("/favicon.ico")) {
return;
}
//获取 Action 处理器
Handler handler = ControllerHelper.getHandler(requestMethod, requestPath);
if (handler != null) {
//获取 Controller 类和 Bean 实例
Class<?> controllerClass = handler.getControllerClass();
Method actionMethod = handler.getActionMethod();
Object controllerBean = BeanHelper.getBean(controllerClass);
contentType = handler.getContentType();
characterEncoding = handler.getCharacterEncoding();
//##1.创建你请求参数对象
Param param;
if (FormRequestHelper.isMultipart(request)) {
//如果是文件上传
param = FormRequestHelper.createParam(request, requestPath, handler.getMappingPath());
} else {
//如果不是
param = AjaxRequestHelper.createParam(request, requestPath, handler.getMappingPath());
}
// List<Object> actionParamList = this.convertRequest2RequestParam(actionMethod, param, request, response);
// param.setActionParamList(actionParamList);
//##2.先执行Filter链
List<Filter> filterList = handler.getFilterList();
boolean doFilterSuccess = true;
if (CollectionUtil.isNotEmpty(filterList)) {
for (Filter filter : filterList) {
//被执行的Filter,都添加到end任务里
if (doEndFilterList == null) {
doEndFilterList = new ArrayList<>();
}
doEndFilterList.add(filter);
doFilterSuccess = filter.doFilter(request, response, param, handler);
//执行失败则跳出,不再往下进行
if (!doFilterSuccess)
break;
}
}
//##3.执行Interceptor 列表
List<Interceptor> interceptorList = handler.getInterceptorList();
boolean doInterceptorSuccess = true;
if (CollectionUtil.isNotEmpty(interceptorList)) {
for (Interceptor interceptor : interceptorList) {
doInterceptorSuccess = interceptor.doInterceptor(request, response, param, handler);
if (!doInterceptorSuccess)
break;
}
}
//##4.执行action
if (doFilterSuccess && doInterceptorSuccess) {
//调用 Action方法
List<Object> actionParamList = this.convertRequest2RequestParam(actionMethod, param, request, response);
Object result = ReflectionUtil.invokeMethod(controllerBean, actionMethod, actionParamList.toArray());
if (result != null) {
if (result instanceof View) {
handleViewResult((View) result, request, response);
} else if (result instanceof Data) {
handleDataResult((Data) result, response, handler);
} else {
Data data = new Data(result);
handleDataResult(data, response, handler);
}
}
}
} else {
//404
throw new RestException(RestException.SC_NOT_FOUND, "404 Not Found");
}
} catch (RedirectorInterrupt e) {
//被中断,跳转
View view = new View(e.getPath());
try {
handleViewResult(view, request, response);
} catch (Exception e1) {
LOGGER.error("中断,跳转 error", e);
}
} catch (RestException e) {
//需要返回前台信息的异常
writeError(e.getStatus(), e.getMessage(), response, contentType, characterEncoding);
} catch (Exception e) {
LOGGER.error("server error", e);
//500
writeError(RestException.SC_INTERNAL_SERVER_ERROR, "500 server error", response, contentType, characterEncoding);
try {
//邮件通知
MailHelper.errorMail(e);
} catch (Exception e1) {
LOGGER.error("mail error", e1);
}
} finally {
//##5.执行Filter链各个节点的收尾工作
if (CollectionUtil.isNotEmpty(doEndFilterList)) {
for (Filter filter : doEndFilterList) {
try {
filter.doEnd();
} catch (Exception endEx) {
LOGGER.error("filter doEnd failed", endEx);
}
}
}
}
}
use of org.axe.bean.mvc.Handler in project Axe by DongyuCai.
the class ControllerHelper method generateActionMap.
@SuppressWarnings("unchecked")
private static void generateActionMap(String nodeName, Map<String, Object> node, Class<?> controllerClass, Method actionMethod, String[] subNodeNameLineAry, String requestMethod, String mappingPath) {
//如果nodeName中有pathParam,全部替换成占位符?
nodeName = RequestUtil.castPathParam(nodeName);
if (subNodeNameLineAry.length > 0) {
Object nodeValue = null;
if (node.containsKey(nodeName)) {
nodeValue = node.get(nodeName);
} else {
nodeValue = new HashMap<String, Object>();
node.put(nodeName, nodeValue);
}
String nodeName_next = subNodeNameLineAry[0];
String[] subNodeNameLineAry_next = new String[subNodeNameLineAry.length - 1];
for (int i = 0; i < subNodeNameLineAry_next.length; i++) {
subNodeNameLineAry_next[i] = subNodeNameLineAry[i + 1];
}
generateActionMap(nodeName_next, (Map<String, Object>) nodeValue, controllerClass, actionMethod, subNodeNameLineAry_next, requestMethod, mappingPath);
} else {
//到最后了
nodeName = requestMethod + ":" + nodeName;
if (!node.containsKey(nodeName)) {
//##Filter 链
List<Filter> filterList = new ArrayList<>();
for (Filter filter : FilterHelper.getSortedFilterList()) {
//#首先判断是否匹配mappingPath
if (filter.setMapping() == null) {
throw new RuntimeException("invalid filter[" + filter.getClass() + "] setMapping is null");
}
Matcher mappingPathMatcher = filter.setMapping().matcher(requestMethod + ":" + mappingPath);
if (!mappingPathMatcher.find())
continue;
//还要判断是否在刨除的规则里,此规则可以为null,直接跳过
if (filter.setNotMapping() != null) {
Matcher notMappingPathMatcher = filter.setNotMapping().matcher(requestMethod + ":" + mappingPath);
if (notMappingPathMatcher.find())
continue;
}
//#其次,说明匹配上了,判断controller是否排除了这个Filter
if (controllerClass.isAnnotationPresent(FilterFuckOff.class)) {
FilterFuckOff filterFuckOff = controllerClass.getAnnotation(FilterFuckOff.class);
if (filterFuckOff.value().length == 0)
continue;
boolean findFuckOffFilter = false;
for (Class<?> filterClass : filterFuckOff.value()) {
if (ReflectionUtil.compareType(filter.getClass(), filterClass)) {
findFuckOffFilter = true;
break;
}
}
if (findFuckOffFilter)
continue;
}
//最后,说明Controller上没有排除此Filter,需要判断方法上是否排除
if (actionMethod.isAnnotationPresent(FilterFuckOff.class)) {
FilterFuckOff filterFuckOff = actionMethod.getAnnotation(FilterFuckOff.class);
if (filterFuckOff.value().length == 0)
continue;
boolean findFuckOffFilter = false;
for (Class<?> filterClass : filterFuckOff.value()) {
if (ReflectionUtil.compareType(filter.getClass(), filterClass)) {
findFuckOffFilter = true;
break;
}
}
if (findFuckOffFilter)
continue;
}
//到这里,说明此过滤器匹配上了这个actionMethod,而且没被排除
filterList.add(filter);
}
//##Interceptor 列表
Map<Class<? extends Interceptor>, Interceptor> interceptorMap = new HashMap<>();
//#controller上指定的拦截器
if (controllerClass.isAnnotationPresent(org.axe.annotation.mvc.Interceptor.class)) {
org.axe.annotation.mvc.Interceptor interceptorAnnotation = controllerClass.getAnnotation(org.axe.annotation.mvc.Interceptor.class);
Class<? extends Interceptor>[] interceptorClassAry = interceptorAnnotation.value();
Map<Class<? extends Interceptor>, Interceptor> INTERCEPTOR_MAP = InterceptorHelper.getInterceptorMap();
if (interceptorClassAry != null) {
for (Class<? extends Interceptor> interceptorClass : interceptorClassAry) {
if (INTERCEPTOR_MAP.containsKey(interceptorClass)) {
interceptorMap.put(interceptorClass, INTERCEPTOR_MAP.get(interceptorClass));
}
}
}
}
//#action method上指定的拦截器,注意去重
if (actionMethod.isAnnotationPresent(org.axe.annotation.mvc.Interceptor.class)) {
org.axe.annotation.mvc.Interceptor interceptorAnnotation = actionMethod.getAnnotation(org.axe.annotation.mvc.Interceptor.class);
Class<? extends Interceptor>[] interceptorClassAry = interceptorAnnotation.value();
Map<Class<? extends Interceptor>, Interceptor> INTERCEPTOR_MAP = InterceptorHelper.getInterceptorMap();
if (interceptorClassAry != null) {
for (Class<? extends Interceptor> interceptorClass : interceptorClassAry) {
if (INTERCEPTOR_MAP.containsKey(interceptorClass) && !interceptorMap.containsKey(interceptorClass)) {
interceptorMap.put(interceptorClass, INTERCEPTOR_MAP.get(interceptorClass));
}
}
}
}
List<Interceptor> interceptorList = new ArrayList<>(interceptorMap.values());
Handler handler = new Handler(requestMethod, mappingPath, controllerClass, actionMethod, filterList, interceptorList);
//构建树
node.put(nodeName, handler);
//存根到ACTIN_LIST
ACTION_LIST.add(handler);
} else {
Handler handler = (Handler) node.get(nodeName);
throw new RuntimeException("find the same action: " + actionMethod.toGenericString() + " === " + handler.getActionMethod().toGenericString());
}
}
}
use of org.axe.bean.mvc.Handler in project Axe by DongyuCai.
the class HomeController method action.
@Request(value = "/action", method = RequestMethod.GET)
public void action(@RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response, String basePathHashCode) {
String contextPath = request.getContextPath();
StringBuilder html = new StringBuilder();
html.append("<!DOCTYPE html>");
html.append("<html>");
html.append("<head>");
html.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
html.append("<title>axe action</title>");
html.append("</head>");
html.append("<body>");
html.append("<table width=\"100%\">");
html.append("<tr><td align=\"right\">");
if (ConfigHelper.getAxeSignIn()) {
html.append("<a style=\"font-size: 15px;color: #AE0000\" href=\"" + contextPath + "/axe/sign-out?token=" + token + "\"><b>退出</b></a>");
}
html.append(" <a style=\"font-size: 15px;color: #AE0000\" href=\"" + contextPath + "/axe?token=" + token + "\"><b>首页</b></a>");
html.append("</td></tr>");
List<Handler> handlerList = ControllerHelper.getActionList();
String basePath = "";
if (basePathHashCode != null) {
Map<Class<?>, String> hashCodeMap = new HashMap<>();
List<Handler> controllerHandlerList = new ArrayList<>();
for (Handler handler : handlerList) {
Class<?> controller = handler.getControllerClass();
String hashCode = null;
if (hashCodeMap.containsKey(controller)) {
hashCode = hashCodeMap.get(controller);
} else {
basePath = controller.getAnnotation(Controller.class).basePath();
int code = basePath.hashCode();
if (code < 0) {
hashCode = "_" + Math.abs(code);
} else {
hashCode = String.valueOf(code);
}
hashCodeMap.put(controller, hashCode);
}
if (hashCode.equals(basePathHashCode)) {
controllerHandlerList.add(handler);
}
}
handlerList = controllerHandlerList;
}
basePath = StringUtil.isEmpty(basePath) ? "" : basePath + " - ";
html.append("<tr><td align=\"center\"><font size=\"28\">" + basePath + "Action list x" + handlerList.size() + "</font></td></tr>");
html.append("");
html.append("<tr><td><table cellspacing=\"0px\"><tr><td style=\"background-color: #AE0000\">");
html.append(" <font color=\"white\"><b>Action</b></font> ");
html.append("</td></tr></table></td></tr>");
html.append("");
html.append("<tr><td height=\"2px\" style=\"background-color: #AE0000\"></td></tr>");
html.append("<tr><td>");
html.append("<table width=\"100%\">");
html.append("<tr style=\"background-color: #F0F0F0;\">");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\"><b>Title</b></td>");
html.append("<td align=\"left\"><b>Mapping</b></td>");
html.append("<td align=\"left\"><b>Request-Method</b></td>");
html.append("<td align=\"left\"><b>Controller-Class</b></td>");
html.append("<td align=\"left\"><b>Action-Method</b></td>");
html.append("<td align=\"left\"><b>Filter</b></td>");
html.append("</tr>");
Map<String, List<Handler>> handlerMap = new HashMap<>();
for (Handler handler : handlerList) {
String mappingPath = handler.getMappingPath();
List<Handler> action = new ArrayList<>();
if (handlerMap.containsKey(mappingPath)) {
action = handlerMap.get(mappingPath);
} else {
handlerMap.put(mappingPath, action);
}
action.add(handler);
}
List<String> mappingPathList = StringUtil.sortStringSet(handlerMap.keySet());
int id = 1;
for (String mappingPath : mappingPathList) {
List<Handler> action = handlerMap.get(mappingPath);
for (Handler handler : action) {
Controller controller = handler.getControllerClass().getAnnotation(Controller.class);
int code = controller.basePath().hashCode();
String hashCode = null;
if (code < 0) {
hashCode = "_" + Math.abs(code);
} else {
hashCode = String.valueOf(code);
}
html.append("<tr>");
html.append("<td align=\"left\">" + (id++) + "</td>");
html.append("<td align=\"left\">" + controller.title() + "." + handler.getActionMethod().getAnnotation(Request.class).title() + "</td>");
html.append("<td align=\"left\">" + mappingPath + "</td>");
html.append("<td align=\"left\">" + handler.getRequestMethod() + "</td>");
html.append("<td align=\"left\"><a href=\"" + contextPath + "/axe/controller-" + hashCode + "/action?token=" + token + "\">" + handler.getControllerClass().getName() + "</a></td>");
hashCode = null;
code = mappingPath.hashCode();
if (code < 0) {
hashCode = "_" + Math.abs(code);
} else {
hashCode = String.valueOf(code);
}
html.append("<td align=\"left\"><a href=\"" + contextPath + "/axe/action/" + hashCode + "?token=" + token + "\">" + handler.getActionMethod().getName() + "</a></td>");
html.append("<td align=\"left\">x" + handler.getFilterList().size() + "</td>");
html.append("</tr>");
}
}
html.append("</table>");
html.append("</td></tr>");
html.append("</table>");
html.append("</body>");
html.append("</html>");
printHtml(response, html.toString());
}
use of org.axe.bean.mvc.Handler in project Axe by DongyuCai.
the class HomeController method actionDetail.
@Request(value = "/action/{mappingHashCode}", method = RequestMethod.GET)
public void actionDetail(@RequestParam("mappingHashCode") String mappingHashCode, @RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response) {
String contextPath = request.getContextPath();
do {
if (StringUtil.isEmpty(mappingHashCode))
break;
StringBuilder html = new StringBuilder();
html.append("<!DOCTYPE html>");
html.append("<html>");
html.append("<head>");
html.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
html.append("<title>axe action detail</title>");
html.append("</head>");
html.append("<body>");
html.append("<table width=\"100%\">");
html.append("<tr><td align=\"right\">");
if (ConfigHelper.getAxeSignIn()) {
html.append("<a style=\"font-size: 15px;color: #AE0000\" href=\"" + contextPath + "/axe/sign-out?token=" + token + "\"><b>退出</b></a>");
}
html.append(" <a style=\"font-size: 15px;color: #AE0000\" href=\"" + contextPath + "/axe?token=" + token + "\"><b>首页</b></a>");
html.append("</td></tr>");
List<Handler> handlerList = ControllerHelper.getActionList();
Handler handler = null;
for (Handler handler_ : handlerList) {
String hashCode = null;
int code = handler_.getMappingPath().hashCode();
if (code < 0) {
hashCode = "_" + Math.abs(code);
} else {
hashCode = String.valueOf(code);
}
if (hashCode.equals(mappingHashCode)) {
handler = handler_;
break;
}
}
if (handler == null)
break;
String basePath = handler.getControllerClass().getAnnotation(Controller.class).basePath();
html.append("<tr><td align=\"center\"><font size=\"28\">Action Detail - " + handler.getMappingPath() + "</font></td></tr>");
html.append("");
html.append("<tr><td><table cellspacing=\"0px\"><tr><td style=\"background-color: #AE0000\">");
html.append(" <font color=\"white\"><b>Action Detail</b></font> ");
html.append("</td></tr></table></td></tr>");
html.append("<tr><td height=\"2px\" style=\"background-color: #AE0000\"></td></tr>");
html.append("<tr><td>");
html.append("<table width=\"100%\">");
html.append("<tr style=\"background-color: #F0F0F0;\">");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\"><b>属性</b></td>");
html.append("<td align=\"left\"><b>值</b></td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">action-title</td>");
html.append("<td align=\"left\">" + handler.getActionMethod().getAnnotation(Request.class).title() + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">mapping</td>");
html.append("<td align=\"left\">" + handler.getMappingPath() + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">request-method</td>");
html.append("<td align=\"left\">" + handler.getRequestMethod() + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">content-type</td>");
html.append("<td align=\"left\">" + handler.getContentType() + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">character-encoding</td>");
html.append("<td align=\"left\">" + handler.getCharacterEncoding() + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">action-method</td>");
html.append("<td align=\"left\">" + handler.getActionMethod().toString() + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">controller-title</td>");
html.append("<td align=\"left\">" + handler.getControllerClass().getAnnotation(Controller.class).title() + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">basePath</td>");
html.append("<td align=\"left\">" + basePath + "</td>");
html.append("</tr>");
html.append("<tr>");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\">action-controller</td>");
html.append("<td align=\"left\">" + handler.getControllerClass().getName() + "</td>");
html.append("</tr>");
html.append("</table>");
html.append("</td></tr><tr><td> </td></tr>");
html.append("");
html.append("");
html.append("<tr><td><table cellspacing=\"0px\"><tr><td style=\"background-color: #AE0000\">");
html.append(" <font color=\"white\"><b>Filter list</b></font> ");
html.append("</td></tr></table></td></tr>");
html.append("<tr><td height=\"2px\" style=\"background-color: #AE0000\"></td></tr>");
html.append("<tr><td>");
html.append("<table width=\"100%\">");
html.append("<tr style=\"background-color: #F0F0F0;\">");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\"><b>Level</b></td>");
html.append("<td align=\"left\"><b>Class</b></td>");
html.append("<td align=\"left\"><b>Mapping</b></td>");
html.append("<td align=\"left\"><b>NotMapping</b></td>");
html.append("</tr>");
List<Filter> filterList = handler.getFilterList();
int id = 1;
for (Filter filter : filterList) {
html.append("<tr>");
html.append("<td align=\"left\">" + (id++) + "</td>");
html.append("<td align=\"left\">" + filter.setLevel() + "</td>");
html.append("<td align=\"left\">" + filter.getClass() + "</td>");
Pattern mappingPattern = filter.setMapping();
String mappingRegex = mappingPattern == null ? "" : mappingPattern.toString();
html.append("<td align=\"left\">" + mappingRegex + "</td>");
Pattern notMappingPattern = filter.setNotMapping();
String notMappingRegex = notMappingPattern == null ? "" : notMappingPattern.toString();
html.append("<td align=\"left\">" + notMappingRegex + "</td>");
html.append("</tr>");
}
html.append("</table>");
html.append("</td></tr><tr><td> </td></tr>");
html.append("");
html.append("");
html.append("<tr><td><table cellspacing=\"0px\"><tr><td style=\"background-color: #AE0000\">");
html.append(" <font color=\"white\"><b>Interceptor list</b></font> ");
html.append("</td></tr></table></td></tr>");
html.append("<tr><td height=\"2px\" style=\"background-color: #AE0000\"></td></tr>");
html.append("<tr><td>");
html.append("<table width=\"100%\">");
html.append("<tr style=\"background-color: #F0F0F0;\">");
html.append("<td align=\"left\"> </td>");
html.append("<td align=\"left\"><b>Class</b></td>");
html.append("</tr>");
List<org.axe.interface_.mvc.Interceptor> interceptorList = handler.getInterceptorList();
id = 1;
for (org.axe.interface_.mvc.Interceptor interceptor : interceptorList) {
html.append("<tr>");
html.append("<td align=\"left\">" + (id++) + "</td>");
html.append("<td align=\"left\">" + interceptor.getClass() + "</td>");
html.append("</tr>");
}
html.append("</table>");
html.append("</td></tr><tr><td> </td></tr>");
html.append("</table>");
html.append("</body>");
html.append("</html>");
printHtml(response, html.toString());
} while (false);
}
Aggregations