知识清单
基础知识清单
SpringMVC框架(重点)
- MVC在B/S系统中的应用方式
- SpringMVC框架原理(DispatcherServlet前端控制器、处理器映射器、处理器适配器、视图解析器)
SpringMVC入门程序
- 需求:商品列表查询
- 常用的处理器映射器,处理器适配器
- 注解的处理器映射器,处理器适配器用于注解开发(重点)
注解开发基础
SpringMVC与Struts的区别
高级知识清单(第二部分)
使用SpringMVC上传图片
集合参数的绑定
validation校验器
异常处理器的使用(用于系统异常处理)
Restful支持
拦截器
SpringMVC框架
SpringMVC是什么?
springmvc是Spring的一个模块,提供web层解决方案(就与MVC设计架构)
MVC在B/S系统中的应用
MVC是一种设计模式,在B/S中的应用如下图所示:
SpringMVC的框架
执行过程大致如下:
第一步:用户发起request请求,请求至DispatcherServlet前端控制器。
第二步:DispatcherServlet前端控制器请求HandlerMapping处理器映射器查找Handler。
DispatcherServlet: 前端控制器,相当于中央调度器,各个组件都和前端控制器进行交互,降低了各个组件之间的耦合度。
第三步:HandlerMapping处理器映射器,根据url及一些配置规则(xml配置、注解配置)查找Handler,将Handler返回给DispatcherServlet前端控制器。
第四步:DispatcherServlet前端控制器调用适配器执行Handler,有了适配器通过适配器去扩展对不同Handler执行方式(比如:原始servlet开发,注解开发)
第五步:适配器执行Handler;
Handler是后端控制器,可以当成模型。
第六步:Handler执行完后后返回ModelAndView。ModelAndView: SpringMVC的一个对象,对model和view进行封装。
第七步:适配器将ModelAndView返回给DispatcherServlet前端控制器。
第八步:DispatcherServlet调用视图解析器进行视图解析,解析后生成view,视图解析器根据逻辑视图名解析出真正的视图。
view:SpringMVC视图封装对象,提供了很多view,比如jsp、freemarker、pdf、execel.......。
第九步:ViewResolver视图解析器给前端控制器返回view。
第十步:DispatcherServlet调用view的渲染视图的方法,将模型数据填充到request域。
第十一步:DispatcherServlet向用户响应结果(jsp页面、json数据......).
DispatcherServlet:前端控制器,由SpringMVC提供。
HandlerMapping:处理器映射器,由SpringMVC提供。
HandlerAdapter:处理器适配器,由SpringMVC提供。
Handler:处理器,需要程序员开发。
ViewResolver:视图解析器,由SpringMVC提供。
view:真正的视图页面,由程序员编写。
入门程序
需求
实现商品列表查询
需要的jar包
使用spring3.2.0(带springmvc模块)
如下图所示
前端控制器
在web.xml中进行配置
-
- <servlet>
- <servlet-name>springmvc</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-
- <init-param>
-
- <!-- 如果不配置contextConfigLocation,
- 默认查找的配置文件名称classpath下的: servlet名称+"servlet.xml"即springmvc-servlet.xml
- -->
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:springmvc.xml</param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>springmvc</servlet-name>
- <!--
- 可以配置/, 此工程 所有请求全部由springmvc解析,此种方式可以实现
- RESTful方式,需要特殊处理对静态文本的解析不能由springmvc解析
- 可以配置*.do或*.action, 所有请求的url扩展名为.do或.action由springmvc解析,此种方法
- 不可以使用/*,如果配置/*,返回的jsp也由springmvc解析,这是不对的
- -->
- <url-pattern>*.action</url-pattern>
- </servlet-mapping>
springmvc.xml
在springmvc.xml中配置springmvc架构的三大组件(处理器映射器、处理器适配器、视图解析器)
工程结构
处理器映射器
在springmvc.xml中进行配置:
BeanNameURLHandlerMapping:根据url( xxx.action ) 匹配Spring容器的name。
找到对应的Bean(程序员编写的Handler)
-
- <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
注意:所有处理器映射器都实现HandlerMapping接口。
处理器适配器
在springmvc.xml中配置:
-
- <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
注意:所有的适配器都是实现了HandlerAdapter接口。
程序员编写Handler要根据所配置的适配器的要求编写。
SimpleControllerHandlerAdapter适配器要求:通过supports方法知道Handler必须要实现哪个接口
查看HandlerAdapter(适配器接口)源代码如下:
- public interface HandlerAdapter {
-
- boolean supports(Object handler);
-
- ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
-
- long getLastModified(HttpServletRequest request, Object handler);
-
- }
查看SimpleControllerHandlerAdapter适配器源码如下:
- public class SimpleControllerHandlerAdapter implements HandlerAdapter {
-
- public boolean supports(Object handler) {
- return (handler instanceof Controller);
- }
-
- public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
-
- return ((Controller) handler).handleRequest(request, response);
- }
-
- public long getLastModified(HttpServletRequest request, Object handler) {
- if (handler instanceof LastModified) {
- return ((LastModified) handler).getLastModified(request);
- }
- return -1L;
- }
-
- }
可以发现SimpleControllerHandlerAdapter类型的处理器适配器通过support方法根据Handler对象是否实现了Controller接口来进行判断是否支持Handler,凡是实现了Controller接口的类都可以被简单类型的处理器适配器匹配调用,简单处理器适配器通过在handle方法中调用Handler实现Controller接口的HandleRequest方法向前端控制器返回ModelAndView。
Handler的编写
需要实现Controller接口
- public class ItemController1 implements Controller {
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
-
- List<Items> itemsList = new ArrayList<Items>();
-
- Items items_1 = new Items();
- items_1.setName("联想笔记本");
- items_1.setPrice(6000f);
- items_1.setCreatetime(new Date());
- items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
-
- Items items_2 = new Items();
- items_2.setName("苹果手机");
- items_2.setPrice(5000f);
- items_2.setDetail("iphone6苹果手机!");
-
- itemsList.add(items_1);
- itemsList.add(items_2);
-
- ModelAndView modelAndView = new ModelAndView();
-
-
- modelAndView.addObject("itemsList", itemsList);
-
- modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
- return modelAndView;
- }
-
- }
配置Handler
在springmvc.xml中配置Handler,由Spring管理Handler。
-
- <bean name="/itemList.action" class="lx.springmvc.first.ItemController1"/>
配置视图解析器
配置视图解析,能够解析jsp视图
-
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- </bean>
工程部署
访问:http://localhost:8080/springmvc_first/itemList.action
异常
地址中Handler名称输入错误
HandlerMapping没有找到Handler,message中不显示jsp路径,这种错误一般是由于输入地址操作导致
要转向的JSP页面不存在
其它非注解处理器映射器和适配器
BeanNameUrlHandlerMapping(映射器)
根据请求url (xxx.action)匹配Spring容器中bean的name
找到对应的bean(程序编写的Handler)
SimpleUrlHandlerMapping(映射器)
-
- <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="mappings">
- <props>
- <prop key="itemsTest1.action">itemController1</prop>
- <prop key="itemsTest2.action">itemController1</prop>
- </props>
- </property>
- </bean>
注意:在springmvc.xml中配置了多个处理器映射器,多个处理器映射器就可以共存,不会排斥。
SimpleControllerHandlerAdapter(适配器)
要求程序编写的Handler (controller)需要实现Controller接口。
HttpRequestHandlerAdapter(适配器)
在springmvc.xml中配置:HttpRequestHandlerAdapter
要求编写的Handler实现 HttpRequestHandler接口
配置HttpRequestHandlerAdapter适配器
-
- <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
开发Handler
- public class ItemController2 implements HttpRequestHandler {
-
- public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
-
- List<Items> itemsList = new ArrayList<Items>();
-
- Items items_1 = new Items();
- items_1.setName("联想笔记本");
- items_1.setPrice(6000f);
- items_1.setCreatetime(new Date());
- items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
-
- Items items_2 = new Items();
- items_2.setName("苹果手机");
- items_2.setPrice(5000f);
- items_2.setDetail("iphone6苹果手机!");
-
- itemsList.add(items_1);
- itemsList.add(items_2);
-
- request.setAttribute("itemsList", itemsList);
- request.getRequestDispatcher("/WEB-INF/jsp/itemsList.jsp").forward(request, response);
- }
-
- }
可以发现。HttpRequestHandler的开发方式和原始的Servlet开发方式很相近
配置Handler
-
- <bean id="itemController2" class="lx.springmvc.first.ItemController2" />
使用简单URL映射器
-
- <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="mappings">
- <props>
- <prop key="itemsTest1.action">itemController1</prop>
- <prop key="itemsTest2.action">itemController2</prop>
- </props>
- </property>
- </bean>
DispatcherServlet.properties
DispatcherServlet前端控制器加载DispatcherServlet.properties配置文件,从而默认加载各个组件。
如果在springmvc.xml中配置了处理器映射器和适配器,以springmvc.xml的为准。
注解映射器和适配器
注解映射器
Spring3.1之前默认加载器是org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping,3.1之后要使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping。
在springmvc.xml中配置RequestMappingHandlerMapping:
-
- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
使用RequestMappingHandlerMapping 注解映射器需要在Handler中使用@Controller标识此类是一个控制器,使用@RequestMapping指定Handler方所对应的url。
注解适配器
Spring3.1之前默认加载映射器是org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter,3.1之后要使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
RequestMappingHandlerAdapter 注解适配器不要求Handler实现任何接口,但它需要和RequestMappingHandlerMapping注解映射器配对使用,主要解析Handler方法中的形参。在springmvc.xml中配置RequestMappingHandlerAdapter如下:
-
- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
注解开发Handler
- @Controller
- public class ItemController3 {