关于SpringMVC的使用总结
- 简介
springMVC即Spring Web MVC,是spring web模块的一部分,是spring自己的web框架
springMVC对Servlet API 进行了完善的封装,极大的简化了开发人员的编程工作。同时springMVC也提供了友好简便的方式让开发人员可以使用Servlet API,十分灵活。
- Servlet的操作方式
- springMVC的操作方式
maven 依赖和插件配置:
<dependencies>
<!-- spring最基本的环境支持依赖,会传递依赖core、beans、expression、aop等基本组件,以及commons-logging、aopalliance -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency> <!-- 提供了对其他第三方库的内置支持,如quartz等 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency> <!-- spring处理对象关系映射的组件,传递依赖了jdbc、tx等数据库操作有关的组件 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.2.RELEASE</version>
</dependency> <!-- spring对面向切面编程的支持,传递依赖了aspectjweaver -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.2.RELEASE</version>
</dependency> <!-- spring处理前端表现层的组件,即springMVC,传递依赖了web操作有关的组件 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency> <!-- 数据校验,springMVC需要用到 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency> <!-- json解析,springMVC需要用到 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.0</version>
</dependency> <!-- 文件上传,springMVC需要用到 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency> <!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency> <!-- servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency> <!-- jsp依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency> <!-- jstl依赖 -->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> <build>
<plugins>
<!-- 指定JDK编译版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
- 核心控制器——DispatcherServlet
springMVC提供了一个核心控制器(大总管)——DispatcherServlet,负责统一调用springMVC提供的其他组件,按照固定步骤处理请求,生成响应。
在web.xml中配置DispatcherServlet :
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
- DispatcherServlet结构
- springMVC的核心配置文件
springMVC是spring的一部分,需要spring上下文的支持,所以需要一个像beans.xml一样的配置文件,我们把这个配置文件命名为dispatcher-servlet.xml(其他名称也可以)
除了以bean的方式配置、管理springMVC的组件外,springMVC的其他内容也需要在这个文件中配置
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置扫描spring注解时扫描的包,同时也开启了spring注解支持 -->
<context:component-scan base-package="com.rupeng.web" /> <!-- 开启springMVC相关注解支持 -->
<mvc:annotation-driven /> <!-- 视图解析器,视图页面的全路径为 prefix + viewName + suffix -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean> <!-- 文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--整个请求的最大大小,用来限制上传的文件大小-->
<property name="maxUploadSize" value="20971520" />
<property name="defaultEncoding" value="UTF-8" />
<!--延迟解析,以便捕获文件大小超出限制的异常,方便生成错误提示信息-->
<property name="resolveLazily" value="true"/>
</bean> <!-- 资源映射 -->
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/images/" mapping="/images/**" />
</beans>
这个文件中配置的都是和web有关的内容,至于项目的其他部分,比如service、dao等也可以配置在这个文件里面。但更一般的,会初始化两个spring上下文,一个用来管理springMVC有关的内容,另一个用来管理项目其他内容
- 额外的字符编码过滤器
springMVC还提供了一个字符编码过滤器,可以对POST请求和响应设置编码(tomcat8会自动对GET请求进行编码):
<!-- 设置post请求编码和响应编码 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<!-- 为true时也对响应进行编码 -->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- DispatcherServlet处理时序图
URL—handler映射
springMVC通过封装,替开发人员做了很多事情,对于那些必须由开发人员来实现的部分,也提供了一整套机制让开发人员实现起来更加简单
开发人员通过实现自己的handler,对请求进行具体的业务处理。实现方式:
声明一个普通类并使用@Controller(不能使用其他方式)把该类标注成spring的bean
使用@RequestMapping把该类的方法标注为handler
@RequestMapping有两个常用的属性:value和method
value指定匹配的请求路径,单独使用时可省略此属性名
method 指定匹配的请求方法(GET、POST),值为枚举类型RequestMethod
@RequestMapping也可以标注在类上,为此类所有的handler统一指定"父路径"
- handler方法的参数类型
handler方法的参数支持很多类型,不同的类型会有不同的用法和效果
支持Servlet API
即HttpServletRequest、HttpServletResponse、HttpSession等。
如果handler方法声明了以上类型的参数,方法执行时springMVC会把和当前请求相关的这些对象注入到方法参数。
其实只要拿到了request、response对象,完全可以按照普通的Servlet方式处理当前请求,这也体现了springMVC高度的灵活性。
还可以通过RequestContextHolder工具类在任何springMVC环境下访问Servlet API:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
支持常用类型
包括基本类型及其包装类型、String、Date等
如果handler方法有以上类型的参数,再配合使用相关的注解,springMVC可以自动从请求中获取相应的值,并且进行类型转换等。
常用注解:
- @RequestParam 获取指定请求参数,相当于request.getParameter()
- @RequestHeader 获取指定请求头,相当于request.getHeader()
- @CookieValue 获得指定cookie的value值
- @SessionAttribute 获取指定session域的属性值,相当于session.getAttribute()
注意:这几个注解的required属性默认为true,即值不能为null
特别的,新版本的springMVC(比如当前使用的版本),@RequestParam可以省略,springMVC会根据参数名称尝试操作,且允许值为null
对于Date类型的参数,由于springMVC在简体中文环境下默认的日期格式不太适用,可自定义日期格式:
@InitBinder
protected void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
支持pojo类
如果handler方法的参数是pojo类型,可以配合使用@ModelAttribute,springMVC会自动创建此pojo类对象,并尝试从请求参数中获取pojo字段相应的值、类型转换、数据绑定等
特别的,可以省略@ModelAttribute
特别的,可以配合使用@Valid、BindingResult,对pojo类的字段进行有效性校验
支持Map、Model、ModelMap
这三个实际上是一样的。即使不在handler方法中声明Model参数,springMVC内部也会对每个请求创建一个Model对象,而且持有pojo参数(如果有)的引用。
Model中可以存入一些键值对数据,最终Model中的数据会被添加到request中,所以也可以直接把键值对存入request。这么看来Model似乎是多余的,其实Model可以和spring自定义标签配合使用,为其提供pojo对象
此外,handler方法还支持其他类型,如RedirectAttributes、MultipartFile等
- handler方法的返回值类型
支持String、ModelAndView
String类型的返回值表示视图名称
ModelAndView就相当于方法参数Model + 返回值String,比较常用
特别的,视图名称使用redirect: 前缀表示重定向到另一个handler(不使用视图解析器),配合使用RedirectAttrbutes方法参数,springMVC会生成带参数的重定向URL
特别的,视图名称使用forward: 前缀表示转发到另一个handler(不使用视图解析器)
支持pojo类
对于ajax请求来说,一般需要返回json格式的字符串数据。springMVC提供了@ResponseBody注解,当标注在handler方法的返回值之前时,可以自动把返回对象转换为json格式的字符串并发送到客户端。
springMVC把对象转换为json格式字符串使用的是Jackson工具包,maven依赖如下(已配置好):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.0</version>
</dependency>
对于Date类型的字段,可以使用Jackson提供的@JsonFormat指定日期格式(标注在字段上)
支持void
如果handler方法的返回值类型是void,则springMVC会认为开发人员已经使用Servlet API 生成了响应,就不再继续处理了。
特别的,无论返回值类型是什么,return null和void含义是一样的。
- 视图层
可以使用JSP页面作为视图层,常用的技术组合为JSP + EL + JSTL(+ spring form标签库)
spring form标签库
spring提供了两个标签库,主要的是form标签库,常用的有<form>、<input>、<checkboxes>、<radiobuttons>、<select>、<errors>等
在使用这些标签时,要求handler方法需要有pojo参数,并且其他标签需要放到<form>标签内部
- <form>会生成HTML的form标签,主要用来为其他spring标签提供Model中的pojo对象。modelAttribute属性值需要和pojo参数名一致
- <input> 默认生成HTML的input(text)标签,path属性值为pojo类的某个字段名
- <checkboxes> 使用数组、集合生成一组input(checkbox)标签
<form:checkboxes items="${allRoleList }" path="roleList" itemLabel="name" itemValue="id" />
<radiobuttons> 和<checkboxes>用法相似
- <select> 和<checkboxes>用法相似,可以使用multiple="false"属性指定不允许多选
- <errors>可以输出某个字段的验证失败信息,也可以输出全部字段的验证失败信息
<form>的action属性不支持JSP表达式<%= %>,可以使用${pageContext.request.contextPath}的方式取得项目路径
这里对于日期字段来说,可以使用@DateTimeFormat标注在字段上指定日期格式
在实际使用时,既可以使用springMVC提供的这套标签,也可以使用EL+JSTL的方式。如果对页面样式要求较高,可能并不适合使用这些spring form标签
- 数据校验
当handler方法的参数是pojo类时,就可以使用spring提供的一套数据校验方案对pojo类中的字段值进行有效性校验
使用hibernate提供的校验实现
maven依赖(已配置好):
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
把校验器配置为bean,id需要指定为validator:
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
校验相关注解
@Valid 标注在handler方法的pojo参数前面,相当于此pojo对象的校验开关
pojo参数后面需要紧跟BindingResult参数,记录校验结果。
可以使用spring form标签库的<errors>标签把校验失败信息输出在页面上
下面的注解都标注在字段上,表示对标注的字段应用某种校验规则,可以直接在注解上指定校验失败时的错误信息(不指定时使用默认的)
@NotEmpty 此字段不能为null,也不能为空字符串
@Length 可以指定字符串的最小、最大长度
@Min 指定数值的最小值
@Max 指定数值的最大值
@Range 指定数值的范围
@Size 指定数组、集合的元素范围
@AssertTrue 断定boolean值为true
@AssertFalse
@Email 指定字符串符合email格式
@Pattern 字符串符合指定的正则表达式
在实际使用时,既可以采用这种校验方式,也可以使用普通的校验方式,即手动对需要校验的字段进行校验,然后向request中添加校验失败的信息,然后在页面中使用EL表达式把失败信息输出到页面上,普通校验方式大家比较熟悉,而且非常灵活。
- springMVC拦截器
springMVC的interceptor和Servlet的filter非常相似,可以拦截请求进行预处理和后处理
- 实现HandlerInterceptor接口编写自己的拦截器(或者继承HandlerInterceptorAdapter)
- 在dispatcher-servlet.xml文件中配置此拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/xx/*" />
<mvc:exclude-mapping path="/xx/xx.do"/>
<bean class="xx" />
</mvc:interceptor>
</mvc:interceptors>
可以使用若干个<mvc:mapping>指定拦截的请求,支持 * 通配符
也可以使用<mvc:exclude-mapping>指定不拦截的请求,一般和<mvc:mapping>配合使用从拦截的请求中排除某些请求
servlet的filter调用链和springMVC的interceptor调用链执行时候的差别:
- 文件上传
springMVC封装了Commons FileUpload 普通文件上传方式,简化了文件上传操作。(此外还支持servlet3.0方式的文件上传)
普通文件上传方式
maven依赖(已配置好):
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
文件上传解析器,id需要指定为multipartResolver(已配置好):
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--整个请求的最大大小,用来限制上传的文件大小-->
<property name="maxUploadSize" value="20971520" />
<property name="defaultEncoding" value="UTF-8" />
<!--延迟解析,以便捕获文件大小超出限制的异常,方便生成错误提示信息-->
<property name="resolveLazily" value="true"/>
</bean>
接下来在handler方法上使用MultipartFile类型的参数即可(@RequestParam 注解可省略)
MultipartFile 常用方法:
getContentType() 获得上传文件的类型
getOriginalFilename() 获得文件原始名称
getSize() 获得上传文件的大小
getInputStream() 获得上传文件的读取流
transferTo(dest) 把上传的文件复制到目标文件
当然,还对页面的form表单有要求:<form method="post" enctype="multipart/form-data">
处理文件大小超出限制时的错误提示信息:
@ExceptionHandler(MultipartException.class)
public ModelAndView handleException(MultipartException ex) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "上传文件的大小不能超过20M");
return modelAndView;
}
- 异常解析器
通过实现HandlerExceptionResolver接口可以编写自己的异常解析器,注册为bean后可以捕获服务器运行时抛出的异常
通常会在异常解析器中记录异常日志信息,还可以根据请求的类型(普通请求、ajax请求)生成合适的错误提示
@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver { @Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { //实际项目中要改为记录日志
ex.printStackTrace(); //判断请求的类型
if (request.getHeader("X-Requested-With") != null) { //ajax请求
try {
response.getWriter().print("{\"status\":\"error\", \"data\":\"服务器出错了\"}");
} catch (IOException e) {
//实际项目中要改为记录日志
e.printStackTrace();
}
//此处返回没有视图名称的ModelAndView对象表示开发人员自己生成了响应
return new ModelAndView();
} else { //普通请求
return new ModelAndView("500");
}
}
}
关于SpringMVC的使用总结的更多相关文章
- 【分享】标准springMVC+mybatis项目maven搭建最精简教程
文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...
- Springmvc数据校验
步骤一:导入四个jar包 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...
- 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程
本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...
- 快速搭建springmvc+spring data jpa工程
一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...
- redis集成到Springmvc中及使用实例
redis是现在主流的缓存工具了,因为使用简单.高效且对服务器要求较小,用于大数据量下的缓存 spring也提供了对redis的支持: org.springframework.data.redis.c ...
- 流程开发Activiti 与SpringMVC整合实例
流程(Activiti) 流程是完成一系列有序动作的概述.每一个节点动作的结果将对后面的具体操作步骤产生影响.信息化系统中流程的功能完全等同于纸上办公的层级审批,尤其在oa系统中各类电子流提现较为明显 ...
- springMVC学习笔记--知识点总结1
以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...
- springMVC初探--环境搭建和第一个HelloWorld简单项目
注:此篇为学习springMVC时,做的笔记整理. MVC框架要做哪些事情? a,将url映射到java类,或者java类的方法上 b,封装用户提交的数据 c,处理请求->调用相关的业务处理—& ...
- springmvc的拦截器
什么是拦截器 java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...
随机推荐
- Spark笔记(一)
简介 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎.Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop MapR ...
- SHELL学习笔记三
SHELL学习笔记一 SHELL学习笔记二 SHELL学习笔记三 for 命令 读取列表中的复杂值 从变量读取列表 从命令读取值 更改字段分隔符 用通配符读取目录 which 使用多个测试命令 unt ...
- 【剑指Offer】面试题10- I. 斐波那契数列
题目 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项.斐波那契数列的定义如下: F(0) = 0, F(1) = 1 F(N) = F(N - 1) + F(N - 2) ...
- 本地登录ftp的时候报530错误
root@instance-iyi104bj:~# ftp localhost Connected to localhost. (vsFTPd ) Name (localhost:root): roo ...
- 【pwnable.kr】fb
这是pwnable.kr的签到题,记录pwn入门到放弃的第一篇. ssh fd@pwnable.kr -p2222 (pw:guest) 题目很简单,登录上了ssh后,发现了3个文件:fd,fd.c, ...
- BZOJ:2243: [SDOI2011]染色
题解: 树剖,线段树维护区间颜色段数 记录两端点的颜色,做到O(1)合并 问题: 非递归建树实现 #include<iostream> #include<cstdio> #in ...
- 全面掌握Nginx配置+快速搭建高可用架构 一 Nginx的访问控制
语法 示例 allow 127.0.0.1; deny all; 缺点:局限性 如果通过代理就可以绕过访问限制,限制不准确 解决 1. http_x_forwarded_for 2. 结合geo模块作 ...
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring JDK动态代理
JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的.下面通过具体的案例演示 JDK 动态代理的使用. 1. 创建项目 在 MyEclipse 中创建一个名称 ...
- django数据库读写分离
django数据库读写分离 1. 配置数据库 settings.py文件中 用SQLite: DATABASES = { 'default': { 'ENGINE': 'django.db.backe ...
- great vision|be quite honest with you
won a national championship拿到全国冠军 come play for you参加你的队伍 Really not true事实并非如此 Being the Socratic p ...