核心类

DispatcherServlet 前端控制器,一个Servlet,配置在web.xml中初始化,所有的请求由它来分发给其他Controller

     <servlet><servlet-name>spring</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/springMvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>spring</servlet-name><url-pattern>*.shtml</url-pattern></servlet-mapping>

默认在DispatcherServlet的初始化过程中,框架会在web应用的 WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml 的配置文件,生成文件中定义的bean,由spring统一管理,这里我们自定义为springMvc.xml,并匹配以shtml后缀的请求。

具体匹配有多种方式

1./WEB-INF/<servlet-name>-servlet.xml
2.WEB-INF/classes/springMVC.xml
3.classpath*:springmvc-mvc.xml
4.classpath*: springmvc*.xml

匹配规则

一般模式
接受定义为*.do ,*.jsp,*.html,*.shtml等请求,如上述配置*.shtml,这是最传统的方式,当然不会拦截js,css,jpg等静态文件
REST风格
接受如ProductDetail/xxxxxx  Product/add 等请求

视图解析器

视图解析器主要是对视图中的Model数据的解释,如PDF EXCEL 等 ,在jsp中常用的视图解析器是InternalResourceViewResovler,它会要求一个前缀和一个后缀

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/page/" p:suffix=".jsp" />

属性编辑器

表单数据的自动装入,但一些特殊情况下 如 整型(1355xx),new Date() ,外键对象 就需要自定义编辑器来处理数据。自定义springMVC的属性编辑器主要有两种方式,一种是使用@InitBinder标签在运行期注册一个属性编辑器,这种编辑器只在当前Controller里面有效;还有一种是实现自己的 WebBindingInitializer,然后定义一个 AnnotationMethodHandlerAdapter的bean,在此bean里面进行注册 ,这种属性编辑器是全局的。

@InitBinder

如对日期格式的处理,只对当前Controller有效

    @InitBinderpublic void initBinder(WebDataBinder binder) {binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));}

PropertyEditor 是一个接口,要实现自己的 PropertyEditor 类我们可以实现这个接口,然后实现里面的方法。但是 PropertyEditor 里面定义的方法太多了,这样做比较麻烦。在 java 中有一个封装类是实现了 PropertyEditor 接口的,它是 PropertyEditorSupport 类。所以如果需要实现自己的 PropertyEditor 的时候只需要继承 PropertyEditorSupport 类,然后重写其中的一些方法。一般就是重写 setAsText 和 getAsText 方法就可以了, setAsText 方法是用于把字符串类型的值转换为对应的对象的,而 getAsText 方法是用于把对象当做字符串来返回的。在 setAsText 中我们一般先把字符串类型的对象转为特定的对象,然后利用 PropertyEditor 的 setValue 方法设定转换后的值。在 getAsText 方法中一般先使用 getValue 方法取代当前的对象,然后把它转换为字符串后再返回给 getAsText 方法。

    @InitBinderpublic void initBinder(WebDataBinder binder) {binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), false));// 定义一个 User 属性编辑器PropertyEditor userEditor = new PropertyEditorSupport() {@Overridepublic String getAsText() {User user = (User) getValue();return user.getDepart().getName();}@Overridepublic void setAsText(String text) throws IllegalArgumentException {setValue(text);  }};// 使用 WebDataBinder 注册 User 类型的属性编辑器binder.registerCustomEditor(User.class, userEditor);}

WebBindingInitializer

如果需要定义全局的类型转换器就需要实现自己的 WebBindingInitializer 对象,然后把该对象注入到 AnnotationMethodHandlerAdapter 中,这样 Spring 在遇到自己不能解析的对象的时候就会到全局的 WebBindingInitializer 的 initBinder 方法中去找,每次遇到不认识的对象时, initBinder 方法都会被执行一遍。

public class MyWebBindingInitializer implements WebBindingInitializer {@Overridepublic void initBinder(WebDataBinder binder, WebRequest request) {binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));}}

定义WebBindingInitializer 对象之后 Spring 还是不能识别其中指定的对象,这是因为我们只是定义WebBindingInitializer 对象,还没有把它交给 Spring,Spring 不知道该去哪里找解析器。要让 Spring 能够识别还需要我们在 SpringMVC 的配置文件中定义一个 AnnotationMethodHandlerAdapter 类型的 bean 对象,然后利用自己定义的 WebBindingInitializer 覆盖它的默认属性 webBindingInitializer。

  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"><property name="cacheSeconds" value="0" /><property name="webBindingInitializer"><bean class="cn.base.web.initializer.MyWebBindingInitializer" /></property>
</bean>

拦截器

SpringMVC 中的Interceptor 拦截器是相当重要,它的主要作用是拦截用户的请求并进行相应的处理,比如通过它来进行权限验证,全局日志的控制等。
Interceptor

SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。

    public class LoginInterceptor implements HandlerInterceptor {@Overridepublic void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception {// TODO Auto-generated method stub
}@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2, ModelAndView arg3) throws Exception {// TODO Auto-generated method stub
}@Overridepublic boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2) throws Exception {// TODO Auto-generated method stubreturn false;}

HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。

1.preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,顾名思义,该方法将在请求处理之前进行调用。SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

2.postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行,这和Struts2 里面的Interceptor 的执行过程有点类型。Struts2 里面的Interceptor 的执行过程也是链式的,只是在Struts2 里面需要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序执行的,而invoke 方法之后的内容就是反向的。

3.afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。

WebRequestInterceptor

WebRequestInterceptor 中也定义了三个方法,我们也是通过这三个方法来实现拦截的。这三个方法都传递了同一个参数WebRequest ,那么这个WebRequest 是什么呢?这个WebRequest 是Spring 定义的一个接口,它里面的方法定义都基本跟HttpServletRequest 一样,在WebRequestInterceptor 中对WebRequest 进行的所有操作都将同步到HttpServletRequest 中,然后在当前请求中一直传递。

public class MyWebRequestInterceptor implements WebRequestInterceptor {@Overridepublic void afterCompletion(WebRequest arg0, Exception arg1)throws Exception {// TODO Auto-generated method stub
    }@Overridepublic void postHandle(WebRequest arg0, ModelMap arg1) throws Exception {// TODO Auto-generated method stub
    }@Overridepublic void preHandle(WebRequest arg0) throws Exception {// TODO Auto-generated method stub
    }
}

1.preHandle(WebRequest request) 方法。该方法将在请求处理之前进行调用,也就是说会在Controller 方法调用之前被调用。这个方法跟HandlerInterceptor 中的preHandle 是不同的,主要区别在于该方法的返回值是void ,也就是没有返回值,所以我们一般主要用它来进行资源的准备工作,比如我们在使用Hibernate 的时候可以在这个方法中准备一个Hibernate 的Session 对象,然后利用WebRequest 的setAttribute(name, value, scope) 把它放到WebRequest 的属性中。这里可以说说这个setAttribute 方法的第三个参数scope ,该参数是一个Integer 类型的。在WebRequest 的父层接口RequestAttributes 中对它定义了三个常量:

SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以访问。
      SCOPE_SESSION :它的值是1 ,如果环境允许的话它代表的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。
      SCOPE_GLOBAL_SESSION :它的值是2 ,如果环境允许的话,它代表的是一个全局共享的session,否则就代表普通的session,并且在该session 范围内可以访问。

2.postHandle(WebRequest request, ModelMap model) 方法。该方法将在请求处理之后,也就是在Controller 方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型ModelMap 来改变数据的展示。该方法有两个参数,WebRequest 对象是用于传递整个请求数据的,比如在preHandle 中准备的数据都可以通过WebRequest 来传递和访问;ModelMap 就是Controller 处理之后返回的Model 对象,我们可以通过改变它的属性来改变返回的Model 模型。

3.afterCompletion(WebRequest request, Exception ex) 方法。该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。所以在该方法中可以进行资源的释放操作。而WebRequest 参数就可以把我们在preHandle 中准备的资源传递到这里进行释放。Exception 参数表示的是当前请求的异常对象,如果在Controller 中抛出的异常已经被Spring 的异常处理器给处理了的话,那么这个异常对象就是是null 。

mvc:interceptors标签

mvc标签中有一个mvc:interceptors是用于声明SpringMVC的拦截器,利用mvc:interceptors标签声明一系列的拦截器,然后它们就可以形成一个拦截器链,拦截器的执行顺序是按声明的先后顺序执行的,先声明的拦截器中的preHandle方法会先执行,postHandle与afterCompletion方法后执行。。

    <mvc:interceptors><!-- 直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 --><bean class="cn.base.web.Interceptor.LoginInterceptor" /><mvc:interceptor><mvc:mapping path="/admin/" /><!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 --><bean class="cn.base.web.Interceptor.MyWebRequestInterceptor" /></mvc:interceptor></mvc:interceptors>

文件上传

没有什么好说的,导入包common-upload 与common-io包

配置

<!-- 文件上传 --><bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- one of the properties available; the maximum file size in bytes --><property name="maxUploadSize" value="-1" /><property name="defaultEncoding" value="UTF-8"></property><property name="maxInMemorySize" value="10240"></property><property name="uploadTempDir" value="/WEB-INF/upload/uploadTempDir"></property></bean>

代码

@RequestMapping("/user_add.shtml")public String user_add(String username, MultipartHttpServletRequest mutiRequest, HttpServletRequest request, HttpServletResponse response)throws IOException {String date = request.getParameter("adddate");System.out.println("username : " + username + "adddate : " + date);MultipartFile uploadFile = mutiRequest.getFile("photo");if (uploadFile != null) {String filename = uploadFile.getOriginalFilename();InputStream in = uploadFile.getInputStream();int len = 0;byte buffer[] = new byte[1024];FileOutputStream out = new FileOutputStream(request.getRealPath("/WEB-INF/upload") + "\\" + filename);while ((len = in.read(buffer)) > 0) {out.write(buffer, 0, len);}out.flush();out.close();in.close();logger.info("文件名称:[" + filename + "]: 上传成功啦!");}return "/user/user_add";}

JSON视图

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"><!-- 配置JSON视图解析--><beanclass="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"><property name="messageConverters"><list><ref bean="mappingJacksonHttpMessageConverter" /></list></property></bean><bean id="mappingJacksonHttpMessageConverter"class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>application/json;charset=UTF-8</value></list></property></bean><!-- 配置JSP视图解析。prefix:前缀, suffix:后缀 --><bean id="jspView"class="org.springframework.web.servlet.view.InternalResourceViewResolver"p:prefix="/WEB-INF/page/" p:suffix=".jsp" /><!-- 扫描注解类 --><context:component-scan base-package="cn.base.web.controller" /><context:component-scan base-package="cn.base.web.dao.impl" /><context:component-scan base-package="cn.base.web.service.impl" />
</beans>

异常处理

数据验证

国际化

SpringMVC 快速入门相关推荐

  1. SpringMVC——快速入门

    目录 1.SpringMVC 1.1.回顾MVC架构 1.2.SpringMVC概述 1.3.SpringMVC的特点 1.4.SpringMVC整体架构 2.SpringMVC快速入门 2.1.创建 ...

  2. SpringMVC 快速入门程序

    一.介绍   通过学习了 Spring MVC 框架原理,我们将更好的掌握 Spring MVC.废话不多说,我们现在正式开始 Spring MVC 快速入门程序--以查询商品信息为例. 二.Spri ...

  3. SpringMVC快速入门-代码实现

    ①导入Spring和SpringMVC的坐标.导入Servlet和Jsp的坐标 <!--Spring坐标--><dependency><groupId>org.sp ...

  4. SpringMVC快速入门-开发步骤

    开发步骤 ①导入SpringMVC相关坐标 ②配置SpringMVC核心控制器DispathcerServlet ③创建Controller类和视图页面 ④使用注解配置Controller类中业务方法 ...

  5. SpringMVC快速入门,看这一篇就够了!

    springmvc概述 Springmvc是spring框架的一个模块,spring和springmvc无需中间整合层整合. Springmvc是一个基于mvc的web框架 表现层的三大任务: URL ...

  6. SpringMVC学习----SpringMvc快速入门

    SpringMVC简介 它是基于MVC开发模式的框架,用来优化控制器.它是Spring家族的一员.它也具备IOC和AOP. 什么是MVC? 它是一种开发模式,它是模型视图控制器的简称.所有的web应用 ...

  7. SpringMVC:学习笔记(1)——理解MVC及快速入门

    SprigMVC-理解MVC及快速入门 说明: 传统MVC-->JSPModel2-->Front Controller + Application Controller + Page C ...

  8. JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署...

    接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...

  9. SpringBoot系列: RestTemplate 快速入门

    ==================================== 相关的文章 ==================================== SpringBoot系列: 与Sprin ...

最新文章

  1. 【BZOJ-2427】软件安装 Tarjan + 树形01背包
  2. FI 与MM SD的接口配置基本方法
  3. gridView删除提示框
  4. Lombok介绍、附比较好用的几种注释推荐
  5. scss-字符串连接符
  6. android js调试
  7. bat随机打开目录下的一个音乐文件_Tomcat bin目录详解
  8. FJ集团企业级邮件服务器——Exchange服务器安装与配置(边缘传输服务器)
  9. 王朔:中国文化沉淀了大量腐烂变质垃圾
  10. CSS 居中 可随着浏览器变大变小而居中
  11. springboot+redis实现微博热搜排行榜
  12. hdwiki 编码规范
  13. ROS到ROS2的多节点组合运行
  14. 模拟电路 二极管门电路(二)
  15. c语言int型是什么意思,在c语言中,int代表什么意思
  16. 开始搞点其他的事-成立北京租房群(霍营、回龙观、西二旗、望京)
  17. 模拟用户登录过程,验证用户名、密码和校验码,如果全部正确提示用户登录成功,否则,提示用户相关输入错误
  18. 会导致肝损伤的保健品和中草药
  19. 怎么搭建一个C语言的开发环境?
  20. 哈理工OJ-1584-青蛙过河【贪心+二分】

热门文章

  1. 在线CSV转YAML工具
  2. linux之软连接和硬连接的区别
  3. SEO关键词优化:如何理解被百度快速索引?
  4. 【ThinkPHP 开发辅助系统】问答
  5. require.js的AMD规范详解
  6. 类查找android中跨项目的数据库操作ContentProvider的使用
  7. web javascript开发 之Response.Write 与document.writ...
  8. 2021副高考试成绩查询荆州,湖北荆州2021年4月自考成绩查询入口开通
  9. android异步任务更新进度条,Android的AsyncTask异步任务浅析
  10. php编码机器语言,机器语言使用的编码是