SpringMVC笔记
springmvc概述
- spring mvc属于springframework的后续产品
- spring 框架提供了构建 web 应用程序的全功能 mvc 模块
- 使用 spring 可插入的 mvc 架构,从而在使用spring进行web开发时,
- 可以选择使用spring的springmvc框架或集成其他mvc开发框架
- spring web mvc和struts2都属于表现层的框架
流程图
入门程序
- 创建 maven web工程
- 导入jar包
<dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>4.11</version> <scope>test</scope> </dependency> <!--c3p0--> <dependency> <groupid>com.mchange</groupid> <artifactid>c3p0</artifactid> <version>0.9.5.2</version> </dependency> <!-- aopalliance --> <dependency> <groupid>org.aopalliance</groupid> <artifactid>com.springsource.org.aopalliance</artifactid> <version>1.0.0</version> </dependency> <!-- dbcp--> <dependency> <groupid>commons-dbcp</groupid> <artifactid>commons-dbcp</artifactid> <version>1.4</version> </dependency> <!-- fileupload --> <dependency> <groupid>commons-fileupload</groupid> <artifactid>commons-fileupload</artifactid> <version>1.3.3</version> </dependency> <!-- commons-io --> <dependency> <groupid>commons-io</groupid> <artifactid>commons-io</artifactid> <version>2.4</version> </dependency> <!-- commons-logging --> <dependency> <groupid>commons-logging</groupid> <artifactid>commons-logging</artifactid> <version>1.2</version> </dependency> <!-- commons-pool --> <dependency> <groupid>commons-pool</groupid> <artifactid>commons-pool</artifactid> <version>1.6</version> </dependency> <!-- log4j --> <dependency> <groupid>log4j</groupid> <artifactid>log4j</artifactid> <version>1.2.17</version> </dependency> <!--aspectj.weaver --> <dependency> <groupid>org.aspectj</groupid> <artifactid>com.springsource.org.aspectj.weaver</artifactid> <version>1.6.4.release</version> </dependency> <!-- spring-aop --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-aop</artifactid> <version>5.2.5.release</version> </dependency> <!-- spring-aspects --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-aspects</artifactid> <version>5.2.2.release</version> </dependency> <!-- spring-beans --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-beans</artifactid> <version>5.2.5.release</version> </dependency> <!-- spring-context --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-context</artifactid> <version>5.2.5.release</version> </dependency> <!-- spring-core --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-core</artifactid> <version>5.2.5.release</version> </dependency> <!--spring-expression --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-expression</artifactid> <version>5.2.5.release</version> </dependency> <!-- spring-jdbc --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-jdbc</artifactid> <version>5.2.5.release</version> </dependency> <!-- spring-test --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-test</artifactid> <version>5.2.3.release</version> <scope>test</scope> </dependency> <!-- spring-test --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-test</artifactid> <version>5.2.3.release</version> <scope>test</scope> </dependency> <!--spring-web --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-web</artifactid> <version>5.2.5.release</version> </dependency> <!-- spring-webmvc --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-webmvc</artifactid> <version>5.2.5.release</version> </dependency> </dependencies>
- 在resources目录添加配置文件 springmvc.xml
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" 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/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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> </beans>
- 配置前端控制器
在web.xml当中配置前端控制器
<?xml version="1.0" encoding="utf-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 配置springmvc前端控制器 --> <servlet> <servlet-name>myspringmvc</servlet-name> <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class> <!-- 指定springmvc配置文件 --> <!-- springmvc的配置文件的默认路径是/web-inf/${servlet-name}-servlet.xml --> <init-param> <param-name>contextconfiglocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!--服务器启动加载spring控制器--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>myspringmvc</servlet-name> <!-- 设置所有以action结尾的请求进入springmvc --> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
- 创建控制器
/** * @author joker_dj * @create 2020-04-21日 22:15 */ @controller public class firstcontroller { @requestmapping("/first.action") public modelandview show(){ modelandview modelandview = new modelandview(); modelandview.addobject("name","joker_dj"); modelandview.setviewname("/first.jsp"); return modelandview; } }
- 在springmvc.xml添加注解扫描
<!--注解扫描--> <context:component-scan base-package="com.dj.controller"/>
- 创建jsp文件
<%@ page iselignored="false" %> <%@ page contenttype="text/html;charset=utf-8" language="java" %> <html> <head> <title>title</title> </head> <body> 跳转 <a href="${pagecontext.request.contextpath}/first.action">点击</a> controller的数据:${name} </body> </html>
- 配置tomcat
运行启动
点击超链接
详细执行流程
架构流程
- 用户发送请求至前端控制器dispatcherservlet
- dispatcherservlet收到请求调用handlermapping处理器映射器。
- 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给dispatcherservlet。
- dispatcherservlet通过handleradapter处理器适配器调用处理器
执行处理器(controller,也叫后端控制器)。 - controller执行完成返回modelandview
- handleradapter将controller执行结果modelandview返回给dispatcherservlet
- dispatcherservlet将modelandview传给viewreslover视图解析器
viewreslover解析后返回具体view - dispatcherservlet对view进行渲染视图(即将模型数据填充至视图中)。
- dispatcherservlet响应用户
流程图
组件说明
- dispatcherservlet
前端控制器
用户请求到达前端控制器,它就相当于mvc模式中的c dispatcherservlet是整个流程控制的中心由它调用其它组件处理用户的请求 dispatcherservlet的存在降低了组件之间的耦合性
- handlermapping
处理器映射器
handlermapping负责根据用户请求url找到handler处理器
springmvc提供了不同的映射器实现不同的映射方式 handlermapping会把找到映射返回给前端控制器
- handler
后端控制器
在dispatcherservlet的控制下handler对具体的用户请求进行处理。
- handladapter
通过handleradapter对处理器进行执行 处理器适配器
- viewresolver
视图解析器
view resolver负责将处理结果生成view视图
- view
springmvc框架提供了很多的view视图类型的支持,
包括:jstlview、freemarkerview、pdfview等。我们最常用的视图就是jsp。
默认加载组件
1. 处理器映射器
- @requestmapping:定义请求url到处理器功能方法的映射
- 注解式处理器映射器,对类中标记了@resquestmapping的方法进行映射。
- 根据@resquestmapping定义的url匹配@resquestmapping标记的方法
- 匹配成功返回handlermethod对象给前端控制器。
- handlermethod对象中封装url对应的方法method。
2. 处理器适配器
- 对标记@resquestmapping的方法进行适配
- 解析对应的方法
3. 视图解析器
- 视图解析器使用springmvc框架默认的internalresourceviewresolver
- 这个视图解析器支持jsp视图解析
配置视图解析器
当一个页面存放目录结构比较多时,就可以配置目录
在springmvc.xmll中添加
请求转发与重定向
转发:
重定向:
接收参数
-
使用传统request对象接收参数
springmvc框架会自动把request对象传递给方法。 -
不使用request接收简单类型参数
当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。
@requestparam
形参的类型与绑定的类型不一致时,可以使用@requestparam进行匹配
- value:请求参数名字
- required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错
- defaultvalue:默认值,表示如果请求中没有同名参数时的默认值
以一个javabean对象接收
要求对象当中的属性要和表单当中的名称一致
list集合接收数据
自定义参数绑定
根据业务需求自定义数据显示格式
需求:
修改商品日期
由于日期数据有很多种格式,springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。
分析:
- 前端控制器接收到请求后,找到注解形式的处理器适配器
- 对requestmapping标记的方法进行适配,并对方法中的形参进行参数绑定。
- 内部已经定义了很多的转换器,比如可以直接使用int类型来接收字符串
- 日期类型与字符串比较特殊,字符串的日期格式,有很多种.可以自己来定义是哪种格式的转换
- 可以在springmvc处理器适配器上自定义转换器converter进行参数绑定。
-
把发布时间对象的字符串转换成日期接收
-
创建转换器
-
在springmvc核心配置文件当中自定义转换器
post请求中文参数乱码
当发送post请求时,带有中文的参数会发生乱码
<!-- 解决post乱码问题 --> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.characterencodingfilter</filter-class> <!-- 设置编码参是utf8 --> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
@requestmapping相关属性
- value属性
- 用来设置请求路径
- 值是一个字符串数组
- 可以设置多个路径共同访问对应方法
- method属性
- 用来设置映射的请求方式
- 值是requestmethod类型的数组
- 如果没有写,则没有限制,post与get都可以请求到对应的方法
- 如果指定了请求类型,则必须得是相应的请求才能访问到对应的方法
- params属性
必须设置对应的请求参数和请求值才能访问到对应的内容
- headers属性
发送的请求头必须要与设置的请求相同时,才能够访问到对应的方法
- ant风格地址
- ant风格:请求路径的一种匹配方法
- 通配符:
1. ?:一个?匹配一个字符
2. *:匹配任意字符
3. **:匹配多重路径
@pathvariable
- rest风格
资源定位及资源操作的风格
不是协议,可以遵循,也可以不遵循
- rest风格请求
- rest 即 representational state transfer (资源)表现层状态转化
- 用url定位资源,用http描述操作
- 是目前最流行的一种互联网软件架构
- 它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用
- 使用post, delete, put, get 分别对应 crud
- spring3.0 开始支持 rest 风格的请求
- 传统的操作资源
查询 get
新增 post
修改 post
删除 post
- restful操作资源
查询get
新增post
更新put
删除delete
使用@pathvariable接收restful风格参数
- 发送put与delete请求
- 默认情况下form表单是不支持put请求和delete请求的
- spring3.0添加了一个过滤器hiddenhttpmethodfilter
- 可以将post请求转换为put或delete请求
配置过滤器 web.xml
发送请求
服务器接收处理
注意事项
- 从tomcat8开始,如果直接返回jsp页面,会报405错误 jsps only permit get post or head
- 使用重定向的形式跳转到对应jsp
- 或者是直接把对应jsp的 iserrorpage="true"
- 过滤器hiddenhttpmethodfilter源码分析 (了解)
@requestheader
作用:在方法中接收请求头当中的信息
@cookievalue
作用:用来接收浏览发送过来的cookes值
传值方式
1. modelmap
- modelmap对象主要用于传递控制方法处理数据到结果页面
- 也就是说我们把结果页面上需要的数据放到modelmap对象中即可
- request对象的setattribute方法的作用: 用来在一个请求过程中传递处理的数据。
- 使用方法与model一样
2. model
- model 和 modelmap 的实例都是spirng mvc框架来自动创建并作为控制器方法参数传入,用户无需自己创建
- 可以简单地将model的实现类理解成一个map
- request级别的模型数据
- model 是一个接口, 其实现类为extendedmodelmap,继承了modelmap类
方法介绍:
1. model addattribute(string attributename, object attributevalue);
添加键值属性对
2. map<string, object> asmap();
将当前的model转换成map
3. model addallattributes(map<string, ?> attributes);
将attributes中的内容复制到当前的model中
如果当前model存在相同内容,会被覆盖
4. model addallattributes(collection<?> attributevalues);
以集合中数据的类型做为key,
将所提供的collection中的所有属性复制到这个map中,
如果有同类型会存在覆盖现象
5. model mergeattributes(map<string, ?> attributes);
将attributes中的内容复制到当前的model中
如果当前model存在相同内容,不会被覆盖
6. boolean containsattribute(string attributename);
3. modelandview
- 需要自己创建
- 既包含模型也包含视图
4. @sessionattributes注解
将模型中的某个属性暂存到 httpsession 中,以便多个请求之间可以共享这个属性
- value:通过指定key将model数据放到session域当中
原来存入session:
通过注解
获取session
- type:把指定类型的模型数据放到session域当中
5. @sessionattribute注解
使用@sessionattribute来访问预先存在的全局会话属性
6. @modelattribute
作用:
- 修改处理方法的参数时,自动把该参数放到model当中
在方法定义上使用 @modelattribute 注解,spring mvc 在调用目标处理方法前,
会先逐个调用在方法级上标注了@modelattribute 的方法。
mvc:view-controller
当我们发送一个请求时,如果没有找到对应的mapping
则会对配置文件当中匹配mvc:view-controller
注意点:使用时要添加后面的内容
<mvc:annotation-driven />
<mvc:annotation-driven /> 是一种简写形式
会自动注册三个bean:
- requestmappinghandlermapping、
- requestmappinghandleradapter
- exceptionhandlerexceptionresolver
并提供了 数据绑定支持,
@numberformatannotation支持,
@datetimeformat支持,
@valid支持,读写xml的支持(jaxb),
读写json的支持(jackson)。
form标签
简介
在使用springmvc的时候我们可以使用spring封装的一系列表单标签,这些标签都可以访问到modelmap中的内容
作用
- 第一是它会自动的绑定来自model中的一个属性值到当前form对应的实体对象
- 第二是它支持我们在提交表单的时候使用除get和post之外的其他方法进行提交,包括delete和put等
使用场景
- 当编辑时, 跳转到form表单页,传统模式要在跳转前先到数据库查询数据,然后进行表单数据回显
- 使用form之前一定要保证有对应的bean,没有对应的bean时, 会自动以command为key到request域中查询,当找不到的时候, 会报异常
使用方式
- 引入标签库
<%@taglib uri="http://www.springframework.org/tags/form" prefix="fm" %>
- 创建表表单
处理请求
页面处理
服务器表单校验
为什么后端要做表单的校验
如果只使用前端校验的话 如果浏览器把js给禁用掉,就弯度子啦
jsr
jsr 303 是 java 为 bean 数据合法性校验提供的标准框架,它已经包含在 javaee 6.0 中 jsr 303 通过在 bean 属性上标注类似于 @notnull、@max 等标准的注解 指定校验规则,并通过标准的验证接口对 bean 进行验证
hibernate validator
是 jsr 303 的一个参考实现, 除支持所有标准的校验注解外,它还支持以下的扩展注解
常用校验规则
-
bean validation 中内置的约束
1. @null 被注释的元素必须为 null
2. @notnull 被注释的元素必须不为 null
3. @asserttrue 被注释的元素必须为 true
3. @assertfalse 被注释的元素必须为 false
4. @min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
5. @max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
6. @decimalmin(value) 被注释的元素必须是一个数字,其值必须大于 等于指定的最小值
7. @decimalmax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
8. @size(max=, min=) 被注释的元素的大小必须在指定的范围内
9. @digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
10. @past 被注释的元素必须是一个过去的日期
11. @future 被注释的元素必须是一个将来的日期
12. @pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式 -
hibernate validator 附加的约束
- @notblank(message =) 验证字符串非null,且长度必须大于0
- @email 被注释的元素必须是电子邮箱地址
- @length(min=,max=) 被注释的字符串的大小必须在指定的范围内
- @notempty 被注释的字符串的必须非空
- @range(min=,max=,message=) 被注释的元素必须在合适的范围内
使用hibernate-validator导入jar包
- 在配置文件当中写上
<mvc:annotation-driven/>
-
在模型当中添加对应的校验规则
-
在处理器方法的入参标记@valid注解即可
-
错误信息页面回显
使用原始表单错误信息写到model中
使用form标签
<fm:error path="username"></fm:error>
访问静态资源
概述
在进行spring mvc的配置时,通常我们会配置一个dispatcher servlet用于处理对应的url
在设置url-pattern时可以设置三种形式
- /*:拦截所有 jsp js png .css 真的全拦截.不建议使用
- /:拦截所有,不包括jsp,包含.js .png.css 建议使用
- *.action *.do:拦截以do action 结尾的请求
url-pattern为/时访问静态资源
方式1-
<mvc:default-servlet-handler/>
方式2- 采用spring自带方法
<mvc:resources>
配置
<mvc:annotation-driven /> <mvc:resources location="/img/" mapping="/img/**"/> <mvc:resources location="/js/" mapping="/js/**"/> <mvc:resources location="/css/" mapping="/css/**"/>
描述
location元素表示webapp目录下的static包下的所有文件;
mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b;
该配置的作用是:dispatcherservlet不会拦截以/static开头的所有请求路径,并当作静态资源 交由servlet处理。
json处理
概述
当前端使用ajax发送请求时,服务器要以json的数据格式响应给浏览器
使用方式
@responsebody来实现;注解方式
@responsebody**
- 添加json处理相关jar包
- 在配置文件当中写上
<mvc:annotation-driven/>
- 设置映射方法的返回值为@responsebody
-
方式1-直接返回一个对象
-
方式2-返回一个list集合
-
方式3-返回一个map集合
-
表单序列化
序列化方式
<form id="myform"> user:<input type="text" name="username"><br> age:<input type="text" name="age" ><br> 爱好:<input type="checkbox" name="hobby" value="篮球"> 篮球 <input type="checkbox" name="hobby" value="乒乓球"> 乒乓球 <input type="checkbox" name="hobby" value="足球"> 足球 </form> <input type="button" id="formbtn" value="发送form">
序列化转json
(function($){ $.fn.serializejson=function(){ var serializeobj={}; var array=this.serializearray(); var str=this.serialize(); $(array).each(function(){ if(serializeobj[this.name]){ if($.isarray(serializeobj[this.name])){ serializeobj[this.name].push(this.value); }else{ serializeobj[this.name]=[serializeobj[this.name],this.value]; } }else{ serializeobj[this.name]=this.value; } }); return serializeobj; }; })(jquery);
@requestbody
作用
- 默认情况下我们发送的都是content-type: 不是application/x-www-form-urlencoded
- 直接使用@requestparam接收参数
- 如果不是content-type: 不是application/x-www-form-urlencoded编码的内容,例如application/json,
application/xml等;- 使用@requestbody接收
使用
发送json参数
发送二进制流
视图解析器
视图解析器
- 请求处理方法执行完成后,最终返回一个 modelandview 对象
- 对于那些返回 string,view 或 modemap 等类型的处理方法
- spring mvc 也会在内部将它们装配成一个 modelandview 对象 它包含了逻辑名和模型对象的视图
- spring mvc 借助视图解析器(viewresolver)得到最终的视图对象(view),最终的视图可以是 jsp
视图
- 视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户
- 视图对象由视图解析器负责实例化
- 在org.springframework.web.servlet 包中定义了一个高度抽象的 view 接口
常见实现类
internalresourceview
将jsp或其它资源封装成一个视图 是internalresourceviewresoler默认使用的实现类
文件下载
文件上传
概述
- spring mvc 为文件上传提供了直接的支持
- 是通过即插即用的 multipartresolver 实现的
- multipartresolver是一个接口
- spring mvc 上下文中默认没有装配 multipartresovler
- 如果想使用 spring 的文件上传功能
- 就必须得要自己下载相关jar包
- 自己到配置文件当中装配到springmvc当中
上传步骤
- 导入相关jar包
- 在springmvc配置文件当中装配multipartresovler
- 实现上传代码
多文件上传
webuploader是由baidu webfe(fex)团队开发的一个简单的以html5为主,flash为辅的现代文件上传组件
异常
概述
- spring mvc 通过 handlerexceptionresolver 处理程序的异常,包括 handler 映射、数据绑定以及目标方法执行时发生的异常。
- springmvc 提供的 handlerexceptionresolver 的实现类
异常处理
处理 handler 中用 @exceptionhandler 注解定义的方法。
@exceptionhandler优先级
根据继承关系 找继承关系比较近的那一个
@controlleradvice
如果在当前类中没有找到@exceptionhanler
则会到@controlleradvice 中的@exceptionhandler 注解方法
国际化
概述
- springmvc 根据 accept-language 参数判断客户端的本地化类型
- 当接受到请求时,springmvc 会在上下文中查找一个本地化解析器(localresolver),
- 找到后使用它获取请求所对应的本地化类型信息。
默认实现过程
-
要先创建国际化的资源文件
-
添加配置文件
-
添加jstl jar包
-
在页面当中编写标签
原理
如果没有显式定义本地化解析器
springmvc 会使用 acceptheaderlocaleresolver:根据 http 请求头的 accept-language 参数确定本地化类型
切换中英文切换
- 默认情况是通过accepheaderlocaleresolver来从浏览器当中获取语言信息
- 可以从请求参数中获取本次请求对应的本地化类型。
- 获取到本地类型后, 给写入到session当中
实现
- 配置文件
- 属性文件
- 页面信息
拦截器
概述
- java 里的拦截器是动态拦截 action 调用的对象。
- 可以controller中的方法执行之前与执行之后, 及页面显示完毕后, 执行指定的方法
- 自定义的拦截器必须实现handlerinterceptor接口
方法介绍
prehandle(): 在业务处理器处理请求之前被调用
posthandle: 在业务处理器处理完请求后
aftercompletion: 在 dispatcherservlet 完全处理完请求后被调用
springmvc拦截器使用
- 拦截所有请求
创建一个类实现handlerinterceptor接口
配置文件当中添加拦截器
- 拦截指定请求
上一篇: C# FileStream类