一、前言
前一章节对springMVC初步讲解了,我们得知它由C-Dispatcher;M-HanlderMapping、HandlerAdapter、Handler;V-ViewResolver三部分组成;其中我们加入了一个spring的字符集拦截器CharacterEncodingFilter在我们的Web.xml里面,构成为SpringMVC。我们只有记住spring的这几个大结构,即使其中的某个部分换了组件,依然能够知道怎么去配置,例如struts2的整合。接下来首先讲一下映射器HandlerMapping与HandlerAdapter。
二、非注解处理器映射器与适配器
2.1 BeanNameUrlHandlerMapping与SimpleUrlHanlderMapping映射器
2.1.1 BeanNameUrlHandlerMapping
匹配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两者同时配置,那么两者同时有效。
2.2 SimpleControllerHandlerAdapter与HttpRequestHandlerAdapter适配器
2.2.1 SimpleControllerHandlerAdapter
<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;
}
}
2.2.2 HttpRequestHandlerAdapter
要求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);
}
}
三、注解处理器映射器与适配器
3.1注解映射器
在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"/>
3.2注解适配器
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"/>
3.3Controler
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总结分析
<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>
执行流程:
我们进入该类看到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