前一章节对springMVC初步讲解了,我们得知它由C-Dispatcher;M-HanlderMapping、HandlerAdapter、Handler;V-ViewResolver三部分组成;其中我们加入了一个spring的字符集拦截器CharacterEncodingFilter在我们的Web.xml里面,构成为SpringMVC。我们只有记住spring的这几个大结构,即使其中的某个部分换了组件,依然能够知道怎么去配置,例如struts2的整合。接下来首先讲一下映射器HandlerMapping与HandlerAdapter。
匹配Spring容器Bean的Name找到的Bean(程序员编写Hanlder)
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <!-- 2.1 BeanNameUrlHandlerMapping controller配置 --> <bean name="/items1" id="itemList1" class="com.ycy.controller.ItemController"/>
2.1.2 SimpleUrlHandlerMapping
BeanNameHandlerMapping的升级版,因为它可以统一配置Controller里面对应Url
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" > <property name="mappings"> <props> <prop key="/simpleItems1" >simpleController1</prop> <prop key="/simpleItems2" >simpleController1</prop> </props> </property> </bean> <bean id="simpleController1" class="com.ycy.controller.ItemController"/>注意:benaname与simple两者同时配置,那么两者同时有效。
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"> </bean>
要求程序编写的Handler(Controller)需要实现 Controller接口。
package com.ycy.controller; import com.ycy.model.Items; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Created by Administrator on 2015/9/17 0017. */ public class ItemController implements Controller { public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { //商品列表 List<Items> itemsList = new ArrayList<Items>(); Items items_1 = new Items(); items_1.setName("联想笔记本"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); items_1.setCreatetime(new Date()); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!"); items_2.setCreatetime(new Date()); itemsList.add(items_1); itemsList.add(items_2); //创建modelAndView准备填充数据、设置视图 ModelAndView modelAndView = new ModelAndView(); httpServletRequest.setCharacterEncoding("utf-8"); //填充数据 modelAndView.addObject("itemsList", itemsList); //视图 modelAndView.setViewName("order/itemsList"); return modelAndView; } }
要求Handler 实现 HttpRequestHandler接口
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"> </bean>提醒:我用的时候需要加全路径
package com.ycy.controller; import com.ycy.model.Items; import org.springframework.web.HttpRequestHandler; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Created by Administrator on 2015/9/17 0017. */ public class ItemController2 implements HttpRequestHandler { @Override public void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException { //商品列表 List<Items> itemsList = new ArrayList<Items>(); Items items_1 = new Items(); items_1.setName("联想笔记本"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); items_1.setCreatetime(new Date()); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!"); items_2.setCreatetime(new Date()); itemsList.add(items_1); itemsList.add(items_2); //创建modelAndView准备填充数据、设置视图 ModelAndView modelAndView = new ModelAndView(); httpServletRequest.setCharacterEncoding("utf-8"); httpServletRequest.setAttribute("itemsList", itemsList); httpServletRequest.getRequestDispatcher("pages/jsp/order/itemsList.jsp").forward(httpServletRequest,httpServletResponse); } }
在springmvc.xml中配置RequestMappingHandlerMapping:
使用RequestMappingHandlerMapping需要在Handler 中使用@controller标识此类是一个控制器,使用@requestMapping指定Handler方法所对应的url。
<!-- 2.3使用注解RequestMappingInfoHandlerMapping映射器 注解映射器配对使用,主要解析Handler方法中的形参 单个: <bean class="com.ycy.controller.ItemController3"/> --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> </bean> <context:component-scan base-package="com.ycy.controller"/>
spring3.1版本之前org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
spring3.1版本之后org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter
<!-- 3.3 RequestMappingHandlerAdapter:注解适配器,与RequestMappingInfoHandlerMapping配对使用 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
package com.ycy.controller; import com.ycy.model.Items; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Created by Administrator on 2015/9/17 0017. */ @Controller public class ItemController3 { @RequestMapping("/queryItems")//建议与方法名称一致 public ModelAndView queryItems(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { //商品列表 List<Items> itemsList = new ArrayList<Items>(); Items items_1 = new Items(); items_1.setName("联想笔记本"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); items_1.setCreatetime(new Date()); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!"); items_2.setCreatetime(new Date()); itemsList.add(items_1); itemsList.add(items_2); //创建modelAndView准备填充数据、设置视图 ModelAndView modelAndView = new ModelAndView(); httpServletRequest.setCharacterEncoding("utf-8"); //填充数据 modelAndView.addObject("itemsList", itemsList); //视图 modelAndView.setViewName("order/itemsList"); return modelAndView; } }
四、SpringMVC总结分析
前面我们清楚了一下流程,现在我们看看spring源码分析,到底这些流程是怎么来的。DispatcherServlet:前端控制器,中央指挥机器,降低组件之间的耦合度。HandlerMappring: 负责处理器映射,根据url找到HandleHandlerAdapter:处理器适配器,根据处理器需求执行适配器。可以通过扩展适配器支持不同类型的Handler 例如:Struts2ViewResolver:视图解析器,根据逻辑视图解析为真正的视图。视图地址=前缀+逻辑视图名+后缀视图解析器配置:<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/pages/jsp/"/> <property name="suffix" value=".jsp"/> </bean>执行流程:1、DispatcherServlet我们进入该类看到doDispatch这个方法有个注释:
Process the actual dispatching to the handler 翻译:进程调度的实际处理程序。
这个就是我们的中心处理程序方法:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Error err) { triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } } }1】 Dispatcher通过Hander查询handle
3】得到ModelAndView,解析视图
2】Dispatcher 通过适配器执行Handler,得到ModelAndView
解析视图最里层我们看看。再往里,其实就是网request里面放置属性了。
jiangmodle数据填充到request中