SpringMVC源码(七)Controller控制器5-MultiActionController
来源:互联网 发布:php输出js代码 编辑:程序博客网 时间:2024/06/06 11:50
前面的控制器一般都是对应一个处理方法,如果对数据进行CRUD操作,那么就需要四个控制器,当我们随着方法的增加,控制器的数量便会大幅度增加.增加了项目的臃肿程度,是不可取的.为了解决这个难题,springmvc 的MultiActionController控制器便闪亮登场.MultiActionController是用于处理多个HTTP请求的处理器,支持在一个控制器里面定义多个功能处理方法.
同时MultiActionController 也提供了两个重要属性:
delegate :功能处理的委托对象,即我们要调用请求处理方法所在对象。
methodNameResolver:功能处理方法名解析器,根据请求的url信息来解析它将调用的方法,需要在配置文件中定义此解析器 。
MultiActionController 是如何做到不同的url请求都能得到正确的处理方法呢?
Spring Web MVC提供的MethodNameResolver(方法名解析器) 属性 ,它会根据HTTP请求URL映射得到应该调用的处理器方法.通过反射调用处理器方法,并且封装返回结果作为模型和视图返回给简单控制器适配器。每个处理器方法可以有一个对应的最后修改方法,最后修改方法名是处理器方法名加上LastModified后缀构成的。最后修改方法也是通过反射调用并且返回结果的。
methodNameResolver提供的三种方式:
org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver
org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver
org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver
1.InternalPathMethodNameResolver
MultiActionController的默认实现,提供从请求URL路径解析功能方法的方法名,从请求的最后一个路径(/)开始,并忽略扩展名;如请求URL是“/user/list.html”,则解析的功能处理方法名为“list”,即调用list方法。该解析器还可以指定前缀和后缀,通过prefix和suffix属性,如指定prefix=”test_”,则功能方法名将变为test_list;
2. PropertiesMethodNameResolver
提供自定义的从请求URL解析功能方法的方法名,使用一组用户自定义的模式到功能方法名的映射,映射使用Properties对象存放,
3.ParameterMethodNameResolver(推荐使用)
提供从请求参数解析功能处理方法的方法名。
下面是MultiActionController的核心代码:
//判断方法是否是功能处理方法 private boolean isHandlerMethod(Method method) { //得到方法返回值类型 Class returnType = method.getReturnType(); //返回值类型必须是ModelAndView、Map、String、void中的一种,否则不是功能处理方法 if (ModelAndView.class.equals(returnType) || Map.class.equals(returnType) || String.class.equals(returnType) || void.class.equals(returnType)) { Class[] parameterTypes = method.getParameterTypes(); //功能处理方法参数个数必须>=2,且第一个是HttpServletRequest类型、第二个是HttpServletResponse //且不能Controller接口的handleRequest(HttpServletRequest request, HttpServletResponse response),这个方法是由系统调用 return (parameterTypes.length >= 2 && HttpServletRequest.class.equals(parameterTypes[0]) && HttpServletResponse.class.equals(parameterTypes[1]) && !("handleRequest".equals(method.getName()) && parameterTypes.length == 2)); } return false; }
实现方法:
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)throws Exception {try {String methodName = this.methodNameResolver.getHandlerMethodName(request);return invokeNamedMethod(methodName, request, response);}catch (NoSuchRequestHandlingMethodException ex) {return handleNoSuchRequestHandlingMethod(ex, request, response);}}
通过上面的代码可以很清楚的看到利用反射获取到了方法的名称,然后再去调用这个方法.如果没有这个方法的存在,那么就会抛出handleNoSuchRequestHandlingMethod异常.
invokeNamedMethod的具体方法:
protected final ModelAndView invokeNamedMethod(String methodName, HttpServletRequest request, HttpServletResponse response) throws Exception {Method method = this.handlerMethodMap.get(methodName);if (method == null) {throw new NoSuchRequestHandlingMethodException(methodName, getClass());}try {Class<?>[] paramTypes = method.getParameterTypes();List<Object> params = new ArrayList<Object>(4);params.add(request);params.add(response);if (paramTypes.length >= 3 && paramTypes[2].equals(HttpSession.class)) {HttpSession session = request.getSession(false);if (session == null) {throw new HttpSessionRequiredException("Pre-existing session required for handler method '" + methodName + "'");}params.add(session);}// If last parameter isn't of HttpSession type, it's a command.if (paramTypes.length >= 3 &&!paramTypes[paramTypes.length - 1].equals(HttpSession.class)) {Object command = newCommandObject(paramTypes[paramTypes.length - 1]);params.add(command);bind(request, command);}Object returnValue = method.invoke(this.delegate, params.toArray(new Object[params.size()]));return massageReturnValueIfNecessary(returnValue);}catch (InvocationTargetException ex) {// The handler method threw an exception.return handleException(request, response, ex.getTargetException());}catch (Exception ex) {// The binding process threw an exception.return handleException(request, response, ex);}}
详细请看:
点击打开链接
- SpringMVC源码(七)Controller控制器5-MultiActionController
- 【SpringMVC】控制器Controller(七)
- springMVC源码--Controller控制器
- SpringMVC源码(三)Controller控制器
- SpringMVC—MultiActionController控制器
- SpringMVC的控制器MultiActionController
- SpringMVC源码(五)Controller控制器3-Servlet相关控制器
- springMVC--多动作控制器: MultiActionController
- SpringMVC源码(四)Controller控制器2-AbstractController
- SpringMVC学习之控制器—MultiActionController
- 第四章 SpringMVC--Controller接口控制器详解(5)
- springMVC学习笔记三(controller控制器)
- SpringMVC--Controller接口控制器详解 (4)
- SpringMVC之控制器controller
- SpringMVC源码(六)Controller控制器4-View视图解析器
- SpringMVC--Controller接口控制器详解
- Controller接口控制器(5)
- 跟开涛学SpringMVC(4.5):Controller接口控制器详解(5)
- 说说was的端口
- 判断链表回文
- 双连通分量模板以及对一些不好理解点的解释
- 数据库简单sql语句小总
- An easy problem 思维
- SpringMVC源码(七)Controller控制器5-MultiActionController
- Eclipse去除js验证
- python中编码问题
- ajax的使用及传值
- Add bricks in the wall UVA
- 个人学习笔记1
- 如何去掉BottomNavigationView的Item大于3个时的动画效果
- 线程
- 26. OP-TEE驱动篇----libteec和tee_supplicant调用驱动流程和重要结构体