SpringMVC的请求和响应过程
图片来自网络)
1.客户端请求提交到DispatcherServlet
2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller
3.DispatcherServlet将请求提交到Controller
4.Controller调用业务逻辑处理后,返回ModelAndView给DispatcherServlet
5.DispatcherServlet查询一个或多个ViewResolver视图解析器,找到ModelAndView指定的视图
6.视图负责将结果显示到客户端
SpringMVC的核心组件DispatcherServlet、HandlerMapping、Controller、HandlerInterceptor、ViewResolver、View、LocalResolver、HandlerExceptionResolver、ModelAndView、HandlerAdapter
Didspatcher作为前端,也是核心控制器,它拦截匹配的请求,依据HandlerMapping实现类配置的规则转发到相应的Controller中去。
Dispatcher的配置例子:
- <!-- 配置前段控制器 -->
- <servlet>
- <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>dispatcher</servlet-name>
- <url-pattern>*.html</url-pattern>
- </servlet-mapping>
配置DispatcherServlet只需要像配置正常的Servlet即可,<servlet-name>表示该Dispatcher的名称,可以配置多个,但是要用不同的名称进行区分,而<url-pattern>则表示会拦截以.html结尾的请求。
在默认情况下不需要指定特定的配置文件,当应用服务器启动时,DidspatcherServlet它会在web应用的WEB-INF目录下去寻找在web.xml中配置DispatcherServlet的<servlet-name>中名称一致的[servlet-name]-servlet.xml文件,去初实例化文件中配置的Bean,如果此文件不存在,则会抛出异常信息。
信息如下:
- org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/dispatcher-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
如果不想使用默认的配置,也可以进行指定配置文件名称
配置如下:
- <!-- 配置前段控制器 -->
- <servlet>
- <servlet-name>dispatcher</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/extends-bean.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>dispatcher</servlet-name>
- <url-pattern>*.html</url-pattern>
- </servlet-mapping>
如果放置在类路径下,那么也可以使用相应的配置:
配置如下:
- <param-value>classpath:/extends-bean.xml</param-value>
**如果以上两种方式都有多个配置文件,那么可以使用逗号隔开!
**DispatcherServlet的初始化过程可以参考:http://jinnianshilongnian.iteye.com/blog/1602617
DispatcherServlet是一个Servlet,它有自己的上下文,它的上下文继承自Spring容器的上下文。DispatcherServlet的是子上下文,而Spring容器的上下文是父上下文,子上下文可以访问并且重新覆盖父上下文的信息,但是父上下文无法访问子上下文的信息。多个DispatcherServlet的上下文之间也无法互相范文。
子上下文覆盖父上下文的例子:
1.web.xml中的配置
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/dao-bean.xml,/WEB-INF/service-bean.xml</param-value>
- </context-param>
- <!-- 监听spring配置文件 -->
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <!-- 配置前段控制器 -->
- <servlet>
- <servlet-name>dispatcher</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/extends-bean.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
使用ContextLoaderListener加载初始化配置文件。
2.service-bean.xml文件的配置:
- <bean id="service" class="cn.changluo.service.impl.UserServiceImpl">
- <property name="userDao" ref="dao"></property>
- <property name="username" value="lisi"></property>
- </bean>
此service Bean属于spring容器的上下文,为bean的username属性设置值为lisi
3.extends-bean.xml文件的配置:
- <bean id="service" class="cn.changluo.service.impl.UserServiceImpl">
- <property name="username" value="zhangsan"></property>
- <property name="userDao" ref="dao"></property>
- </bean>
此service Bean属于DispatcherServlet的上下文,同时为username属性设置值为zhangsan。
执行了相应的方法之后,发现输出为:
也就是说,子上下文中的bean覆盖了父上下文中的bean。
正确的理解和使用上下文可以帮助我们较好的分层,当分为多个层时,各个层之间该放置于那个上下文中,可以更好的管理和维护。如果不想使用父上下文,那么只需要使用子上下文即可。
SpringMVC将请求映射到处理程序的方法
在SpringMVC中,Web请求被应用程序的上下文中声明的一个或者多个处理程序映射到处理程序上。这些Bean都必须实现了HandlerMapping接口,这样DispatcherServlet才能自动侦测他们。
1.按Bean名称映射请求
最简单的策略就是按照处理程序的Bean名称进行映射,这也是默认的策略。为了让这个策略生效,必须将每个处理程序的Bean名称声明成URL模式的形式。可以使用通配符。
XML配置文件示例:
- <bean name="/hello" class="mvcdemo.controller.HelloWorldController"/>
SpringMVC提供了几个HandlerMapping实现,可以根据不同的策略来映射。默认情况下,如果你没有显示的配置处理程序映射,DispatcherServlet将利用BeanNameUrlHandlerMapping作为它的默认处理程序,它根据Bean名称中指定的Url模式将请求映射到处理程序上。
使用此映射策略是时,必须通过name属性设置处理程序的名称。
2.按控制器类名称映射请求
它根据Web应用的上下文中声明的控制器的类名称,自动生成映射。Spring有提供一个专门的类ControllerClassNameHandlerMapping,它实现了Controller接口的处理程序生成处理程序的映射。
XML配置文件示例:
- <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
- <!—让URL遵守JAVA的变量命名约定-->
- <property name="caseSensitive" value="true"></property>
- <!--
- <property name="pathPrefix" value="/testproject"></property>
- <property name="basePackage" value="mvcdemo.controller"></property>
- -->
- </bean>
- <bean class="mvcdemo.controller.HelloWorldController"/>
对于HelloWorldController这个Bean,ControllerClassNameHandlerMapping会移除类名称中的Controller后缀,并将其他部分转换成小写字母,以此来生成处理程序映射。
HelloWorldController---------/helloworld*
加上了以上的property后,变为
HelloWorldController---------/helloWorld*
使用此方法时,必须在XML中显示注册ControllerClassNameHandlerMapping这个类,并且控制处理程序必须以Controller结尾。
3.用户定制的映射定义来映射请求
将请求映射到处理程序最直接最灵活的策略,是显式的指定URL模式和处理程序之间的映射定义,可以通过SimpleUrlHandlerMapping来做到。
XML配置文件示例:
- <!-- 配置请求的Controller的业务类 -->
- <bean id="loginController" class="cn.changluo.controller.HelloWorldController">
- <property name="failView" value="login"></property>
- <property name="successView" value="success"></property>
- </bean>
- <!-- 配置Controller和URL的映射关系 -->
- <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="mappings">
- <props>
- <prop key="/login.html">loginController</prop>
- </props>
- </property>
- </bean>
SimpleUrlHandlerMapping接受Properties对象形式的映射定义。属性是URL模式,而属性值则是处理器ID或者名称。URL模式也可以接受通配符,让处理程序处理多个URL。
HandlerInterceptor是SpringMVC提供的拦截器,你可以通过处理拦截器,拦截Web请求,进行前置处理和后置处理。拦截器是在SpringMVC应用程序的上下文中配置的,因此它们可以利用各种容器特性,并引用容器中声明的任何bean。处理拦截是针对特殊的处理程序映射进行注册的,因此它只拦截通过这些处理程序映射的请求。
每个拦截器都必须实现HandlerInterceptor这个接口,它有三个方法:preHandler()、postHandler()、afterCompletion()。第一个和第二个方法分别是在处理程序处理请求之前和之后被调用的。第二个方法还允许访问返回的ModelAndView对象。最后一个方法是在所有请求处理完之后被调用的,也就是呈现视图之后。
preHandler()方法返回true时,继续处理请求,否则直接将响应返回给用户。
SpringMVC允许拦截器继承自HandlerInterceptorAdapter,实现HandlerInterceptor需要实现所有的方法,当我们仅仅需要实现其中的某个方法时,则可以继承HandlerInterceptorAdapter
拦截器示例:
1.拦截器类:
- public class MyInterceptor implements HandlerInterceptor {
- @Override
- public void afterCompletion(HttpServletRequest request,
- HttpServletResponse response, Object handler, Exception exception)
- throws Exception {
- System.out.println("afterCompletion");
- }
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response,
- Object handler, ModelAndView mv) throws Exception {
- System.out.println("postHandle");
- }
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
- Object handler) throws Exception {
- System.out.println("preHandle");
- return true;
- }
- }
第二个拦截器类同上,只是输出内容不同
2.interceptor-bean.xml配置
- <!-- 配置Controller和URL的映射关系 -->
- <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="interceptors">
- <list>
- <ref bean="myInterceptor1"/>
- <ref bean="myInterceptor3"/>
- </list>
- </property>
- <property name="mappings">
- <props>
- <!-- 通配符 -->
- <prop key="/context.html">contextController</prop>
- </props>
- </property>
- </bean>
- <bean id="myInterceptor1" class="cn.changluo.interceptor.MyInterceptor"></bean>
- <bean id="myInterceptor3" class="cn.changluo.interceptor.MyInterceptor3"></bean>
执行之后的结果如下:
- preHandle
- preHandle3
- contextcontroller
- postHandle3
- postHandle
- afterCompletion3
- afterCompletion
如果你在控制器返回的视图中输出一句话,就会发现,它是在afterCompletion这个方法输出之前调用
SpringMVC的重定向和转发
转发:将请求转发到另外一个Action中进行处理
重定向:重定向到应用或者其他外部资源,可以防止表单重复提交
转发和重定向的区别在于:
1.重定向时,浏览器上的地址栏改变,而转发时,浏览器的地址栏不变
2.重定向其实是产生了两次请求,没有,而转发只有一次请求
3.重定向可以到任何网址,转发必须是本站点的网址
在SpringMVC中,对于转发和重定向的写法有如下几种:
转发:
- return new ModelAndView("forward:/context.html")
重定向:
- ModelMap model = new ModelMap();
- model.addAttribute("param1", "param1");
- model.addAttribute("param2", "param2");
- return new ModelAndView("redirect:/index.jsp",model); //http://localhost:8083/mvcdemo/index.jsp?param1=param1¶m2=param2
- //添加了参数之后,会在URL重定向到相应的界面,并且后面加了一串参数
- //下面的这种方式结果和上面的一致
- RedirectView rv = new RedirectView("index.jsp");
- ModelMap model = new ModelMap();
- model.addAttribute("param1", "data1");
- model.addAttribute("param2", "data2");
- rv.setAttributesMap(model);
- return new ModelAndView(rv);
SpringMVC使用PDF和Excel视图
具体的解释可以参考Spring的文档
示例:
1.controller控制类
1)ExcelController类:
- public class ExcelController extends AbstractController{
- @SuppressWarnings("unchecked")
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request,
- HttpServletResponse response) throws Exception {
- List<String> list = getModelData();
- Map model = new HashMap();
- model.put("data", list);
- return new ModelAndView("exl",model);
- }
- public List<String> getModelData(){
- List<String> list = new ArrayList<String>();
- for(int i = 0 ;i<10;i++){
- list.add("this demo"+i);
- }
- return list;
- }
- }
2)PdfController类:
- public class PdfController extends AbstractController {
- @SuppressWarnings("unchecked")
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
- HttpServletResponse arg1) throws Exception {
- List<String> list = getModelData();
- Map model = new HashMap();
- model.put("data", list);
- return new ModelAndView("pdf", model);
- }
- public List<String> getModelData() {
- List<String> list = new ArrayList<String>();
- for (int i = 0; i < 10; i++) {
- list.add("this demo" + i);
- }
- return list;
- }
- }
2.demoview-bean.xml的配置
- <bean id="viewRosolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
- <!--
- ResourceBundleViewResolver视图解析器会在classpath中寻找properties属性文件,根据此bean配置的
- <property name="basename" value="view" />
- 说明寻找的properties文件名为view.properties
- -->
- <property name="basename" value="view"></property>
- <property name="order" value="2"></property>
- </bean>
- <!-- 配置Controller和URL的映射关系 -->
- <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="mappings">
- <props>
- <prop key="/show_excel.html">excelController</prop>
- <prop key="/show_pdf.html">pdfController</prop>
- </props>
- </property>
- </bean>
- <bean id="excelController" class="cn.changluo.controller.ExcelController"/>
- <bean id="pdfController" class="cn.changluo.controller.PdfController"/>
4.view.properties属性文件的配置
- exl.(class)=cn.changluo.view.ExcelHomepage
- pdf.(class)=cn.changluo.view.PdfHomepage
5.view.properties文件中配置的两个类的具体实现
1)ExcelHomepage类:
- public class ExcelHomepage extends AbstractExcelView {
- @SuppressWarnings("unchecked")
- @Override
- protected void buildExcelDocument(Map model, HSSFWorkbook wb,
- HttpServletRequest request, HttpServletResponse response)
- throws Exception {
- HSSFSheet sheet = null;
- HSSFCell cell = null;
- sheet = wb.createSheet("springMvc excel view");
- sheet.setDefaultColumnWidth((short)10);
- cell = getCell(sheet, 0, 0);
- setText(cell, "springMVC-excel");
- List<String> list = (List<String>)model.get("data");
- for(int i=0;i<list.size();i++){
- cell = getCell(sheet, 2, i);
- setText(cell, list.get(i));
- }
- }
- }
2)PdfHomepage类:
- public class PdfHomepage extends AbstractPdfView {
- @SuppressWarnings("unchecked")
- @Override
- protected void buildPdfDocument(Map model, Document doc, PdfWriter pw,HttpServletRequest request, HttpServletResponse response)
- throws Exception {
- List<String> words = (List<String>) model.get("data");
- for (int i = 0; i < words.size(); i++)
- doc.add(new Paragraph((String) words.get(i)));
- }
- }
相关推荐
Spring MVC请求参数与响应结果全局加密和解密详解 在本文中,我们将详细介绍Spring MVC请求参数与响应结果全局加密和解密的相关知识点,包括请求参数的加密和解密、响应结果的加密和解密、ContentType的处理等。 ...
"SpringMVC请求/响应乱码问题解决方案解析" SpringMVC请求/响应乱码问题是指在使用...本文对SpringMVC请求/响应乱码问题解决方案进行了详细的分析和介绍,提供了多种解决方法,希望对大家的学习和工作有所帮助。
调试Ajax请求通常涉及检查浏览器的开发者工具,查看网络请求和响应。对于测试,可以使用JUnit结合MockMVC模拟Ajax请求,验证控制器的响应。 总之,Spring MVC中的异步Ajax请求是现代Web应用的重要组成部分,它提高...
springMVC的手动搭建,手动搭建的一些笔记,讲解请求与响应的过程
在开发Web应用时,SpringMVC作为Spring框架的一部分,常被用于处理HTTP请求和响应。在前后端交互中,JSON(JavaScript Object Notation)是一种常用的数据交换格式,它轻量级且易于人阅读和编写,同时也方便机器解析...
结合使用SpringMVC和Ajax,可以实现异步数据交互,提高用户体验。 在SpringMVC中,Ajax请求通常涉及到以下几个关键步骤: 1. **前端准备**: - 首先,你需要在HTML页面中引入jQuery库,因为它是广泛使用的...
POST请求中文乱码可以通过在web.xml配置CharacterEncodingFilter解决,设定请求和响应的编码为UTF-8。对于GET请求,可以通过以下两种方式处理乱码: 1. 修改Tomcat配置文件,设置Connector的URIEncoding属性为"utf-8...
当我们需要在SpringMVC中返回XML响应时,可以结合使用SpringMVC和XStream。 首先,让我们详细了解一下SpringMVC。SpringMVC是Spring框架的一部分,负责处理HTTP请求并生成响应。它通过DispatcherServlet作为入口点...
SpringMVC的请求和响应 请求和响应乱码问题 中文乱码+日期格式转换器配置
【SpringMVC 请求流程】 ...通过以上步骤,你可以了解SpringMVC的基本使用和请求处理流程。SpringMVC提供了许多高级特性,如数据绑定、文件上传下载、异常处理等,可以根据实际需求进一步学习和使用。
SpringMVC 作为 Spring 框架的一部分,提供了处理 HTTP 请求和响应的强大功能。它通过解耦控制器、业务逻辑和服务层,使得开发者能够更加专注于应用的核心功能,而不是繁琐的 web 层实现。SpringMVC 的主要组件包括 ...
SpringMVC是Spring框架的一个模块,专门用于处理Web应用程序的请求和响应。它是一个基于模型-视图-控制器(MVC)设计模式的轻量级Web框架,旨在简化开发过程,提供灵活的控制和强大的功能。在这个“springmvc处理器...
8. **拦截器**: 拦截器可以预处理请求并后处理响应,例如认证、日志记录、性能监控等。自定义拦截器需实现`HandlerInterceptor`接口,然后在`web.xml`或Spring配置中注册。 在实际项目中,SpringMVC可以与其他技术...
开发者需要理解这两个库的基本API,学习如何在Java中创建和格式化表格和文档,以及如何在SpringMVC环境中将这些文件作为HTTP响应的一部分进行处理和发送。这个技能对于构建功能丰富的Web应用,特别是那些需要数据...
SpringMVC和MyBatis是Java Web开发中的两个...SpringMVC处理请求和响应,MyBatis负责数据库操作,Service层作为它们之间的桥梁,实现了业务逻辑。这样的组合提供了良好的分层结构,提高了代码的可维护性和可扩展性。
本入门程序旨在帮助初学者理解并掌握SpringMVC的基本概念和工作流程,通过实现用户在前端页面注册信息并显示的功能,来深入剖析其核心机制。 ### 1. SpringMVC框架概述 SpringMVC是Spring框架的一部分,提供了一个...
SpringMVC 支持文件上传和下载功能,通过 `MultipartFile` 类处理文件上传,而文件下载可以通过设置响应头和流操作来实现。 ### 第 9 章 RESTful 风格 SpringMVC 很好地支持 RESTful 风格的 Web 服务,利用 `@...
通过编写这些组件,我们可以理解SpringMVC如何将请求、业务逻辑和视图分离,以及它们之间的协作过程。此外,这也将帮助我们更好地理解SpringMVC中的一些高级特性,如拦截器、AOP(面向切面编程)、数据绑定和异常...
在实际项目中,我们可能还需要配置拦截器(Interceptor),它们可以对请求和响应进行预处理和后处理,例如实现登录检查、日志记录等功能。通过`@Component`和`@Order`注解,我们可以创建自定义的拦截器类,并通过`...