/ 2018-07-31
SpringMVC是由C-Dispatcher、M-HanlderMapping、HandlerAdapter、Handler、V-ViewResolver三部分组成,我们在Web.xml中加入了一个spring的字符集拦截器CharacterEncodingFilter构成了SpringMVC。
今天我们讲一下映射器HandlerMapping与HandlerAdapter。
1. BeanNameUrlHandlerMapping
匹配Spring容器Bean的Name找到的Bean(程序员编写Hanlder),springmvc.xml中配置如下代码:
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <!-- 2.1 BeanNameUrlHandlerMapping controller配置 --> <bean name="/items1" id="itemList1" class="com.spring.Controller.ItemController"/>
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两者同时配置,那么两者同时有效。
2.SimpleControllerHandlerAdapter
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"> </bean>
要求程序编写的Handler(Controller)需要实现 Controller接口
package
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;
/**
*
*/
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;
}
}HttpRequestHandlerAdapter
要求Handler 实现 HttpRequestHandler接口
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter">
</bean>
package
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);
}
}3.注解处理器映射器与适配器
spring3.1版本之前加载映射器
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
spring3.1之后用org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping
也是源码解读:
/org/springframework/spring-webmvc/4.2.0.RELEASE/spring-webmvc-4.2.0.RELEASE.jar!/org/springframework/web/servlet/DispatcherServlet.properties
里面清楚记载了先加载谁在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"/>
Controler
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;
}
}访问结果url:
http://localhost:8080/spring01/queryItems
4.SpringMVC总结分析
前面我们清楚了一下流程,现在我们看看spring源码分析,到底这些流程是怎么来的!
DispatcherServlet
前端控制器,中央指挥机器,降低组件之间的耦合度。
HandlerMappring
负责处理器映射,根据url找到Handle。
HandlerAdapter
处理器适配器,根据处理器需求执行适配器。可以通过扩展适配器支持不同类型的Handler 例如:Struts2
ViewResolver
视图解析器,根据逻辑视图解析为真正的视图。视图地址=前缀+逻辑视图名+后缀
视图解析器配置:
<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>
执行流程
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

2)Dispatcher 通过适配器执行Handler,得到ModelAndView

3)得到ModelAndView,解析视图

解析视图最里层我们看看。再往里,其实就是网request里面放置属性了

jiangmodle数据填充到request中

(12)