SpringMVC
Spring MVC简介
Spring MVC为展现层提供的基于MVC设计理念的优秀Web框架,是目前最主流的MVC框架之一
Spring3.0后全面超越了Struts2,称为最优秀的MVC框架
Spring MVC通过一套MVC注解,让POJO称为处理请求的控制器,无需实现任何接口
支持REST风格的Web请求
采用了松散耦合可插拔组件结构,比其它MVC框架更具扩展性和灵活性
搭建Spring MVC环境
基于接口方式搭建MVC环境
通过实现Controllor接口实现MVC
基于注解方式搭建MVC环境
性也得到大大的提高。
推荐使用注解方式。
不管是那种方式都需要在web.xml中添加配置DispacherServlet
记得在头文件中添加:
- 在web.xml中配置DispacherServlet
- 创建请求处理类
- 接口方式
在springmvc配置文件中添加:
二、注解方式
@Controller
public class HelloWorld2 {
@RequestMapping("/helloworld")
public String hello(){
System.out.println("hello spring mvc 注解方式");
return "hello";
}
}
@Controller:修饰类为一个控制器
@RequestMapping("/hello"):修饰方法的请求路径
在springmvc配置文件中添加:
- 配置视图解析器
访问:<a href=”hwlloworld”>点击</a>
SpringMVC核心处理流程
发送请求到DispatcherServlet,然后交给HandlerMapping映射器,HandlerMapping再根据请求路径找到拦截器或Controller,然后返回一个ModelAndView对象,然后视图解析器再解析具体的视图
基本配置
@Controller
作用:将当前类作为一个控制器类
如果使用这个注解方式,必须在Spring中添加自动扫描的路径
如果使用实现接口方式
@RequestMapping
Spring MVC使用@RequestMapping注解为控制器指定请求的URL
在控制器的类定义及方法定义处都可以标记
类定义处:提供初步的映射信息,为该类下所有的请求方法添加前缀
方法定义处:提供进一步的映射信息,提供方法的请求路径
DispacherServlet截获请求后,就通过控制器上的@RequestMapping提供的映射信息确认请求所对应的处理方法
@RequestMapping示例
@RequestMapping("/hw")
@Controller
public class HelloWorld2 {
@RequestMapping("/helloworld2")
public String hello2(){
System.out.println("hello spring mvc 注解方式222");
return "hello";
}
}
访问方式
<a href=”hw/hwlloworld2”>点击</a>
@RequestMapping的value、method、params及heads分别表示请求url,请求方法,请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可以让请求更加精确化。
使用示例:
表示请求的url必须有一个叫username的参数名而且,请求的age参数不能等于10
@RequestMapping(value="/helloworld4",params={"username","age!=10"})
表示提交post请求
@RequestMapping(value="/helloworld3",method=RequestMethod.POST)
表示请求头必须以text开头
@RequestMapping(value="/helloworld3",headers=”contentType=text/*”)
通配符
?:匹配一个字符
*:匹配文件中任意字符
**:匹配多层路径
使用示例:
表示请求路径为”/helloworld5/加一个任意字符”
@RequestMapping(value="/helloworld5/*")
@PathVariable
用来映射URL中的占位符。映射的变量名必须和占位符中的名称一致
public String hello6(@PathVariable("id") Integer id){
System.out.println(id);//打印结果33
return "hello";
}
前台访问
<a href="helloworld6/33">点击跳转......</a>
@RequestParam
获取页面传递过来的参数,GET和POST都支持。
如果url上的参数名和方法上的变量名一致,可以不加这个注解@RequestParam
public String hello11(@RequestParam(value="username")String username){
System.out.println("-----"+username);
return "hello";
}
<a href="hw/helloworld11?username=‘lei’">点击提交....</a>
注意:
请求的URL中没有username这个参数名,会报错,此时可以加一个required=false,这样即使没有提交此参数,也不会报错。还可以加一个默认值,当没有提交这个参数时会给它一个默认值
public String hello11(@RequestParam(value="username",required=false,
defaultValue="xxx")
@RequestHeader
请求头包含了若干的属性,用来获取客户端的信息。通过@RequestHeader可以用来获取请求头中的信息
@CookieValue
用来获取客户端Cookie信息
public String testCookieValue(@CookieValue("JSESSIONID")String sessionid){
System.out.println("sessionid=" + sessionid);
return "hello";
}
实体对象绑定请求参数
Spring MVC会直接将页面元素和实体对象进行匹配,自动转换为实体对象。并且支持级联属性。如address.city等
public String addGrader(GraderVo graderVo){
System.out.println(graderVo.getG_note());
return "GraderOption";
}
<form action="/addGrader" method="post">
年级备注<input type="text" name="g_note" /><br>name名称和实体类属性名一致,就可以在后台获取到值
<input type="submit" >
</form>
Servlet API
Spring MVC可以使用Servlet API作为请求方法的参数。
HttpServletRequest
HttpServletResponse
HttpSession
Local
InputStream
OutputStream
Read
Write
例:
处理模型数据
Spring MVC提供一下几种途径返回模型数据:
ModeAndView:将处理方法的返回类型设置为ModeAndView,方法体即可通过该模型对象添加模型数据。
Map及Model形参:当形参为Map,Model,ModelMap时,处理方法返回时,Map中的数据会自动添加到模型中。
@SessionAttributes:将模型中的某个属性存储到Session中,以便多个请求之间共享这个属性。
@ModelAttribute:方法形参标记该注解后,形参对象就会放到模型中。
@ModeAndView示例:
@Map示例:
@SessionAttributes
注意:只能在类名上使用
表示将names或者String类型的放到session中
@SessionAttributes(value={"names"},types={String.class})
@ModelAttribute
在方法定义上定义此注解:
SpringMVC调用方法前,会自动调用被此注解标注的方法
将此注解中的属性保存到map中,可以在执行表单交生成对象之前,替换执行方法同名的形参
在方法的形参中定义此注解:
可以从隐含对象中获取隐含的模型中获取对象,再将请求参数绑定到对象中,再传入形参
将方法形参对象添加奥模型中。
由@SessionAttributes引发的异常
当类使用@SessionAttributes修饰,而方法中使用了和SessionAttributes修饰同名的映射参数,却没有添加@ModelAttribute修饰时,则会报错。
视图、REST
什么是视图解析器
SpringMVC用于处理视图最重要的两个接口是ViewResolver和View
ViewResolver的主要作用是把一个逻辑上的视图名称解析为一个真正的视图,SpringMVC中用于把View对象呈现给客户端的是View对象本身,而ViewResolver只是把逻辑视图名称解析为对象的View对象
View接口的主要作用是用于处理视图,然后返回给客户端
视图解析器的解析流程
视图(View)
视图的作用是渲染模型数据,将模型里面的数据以某种形式呈现给客户
为了实现视图模型和具体实现技术的解耦,Spring定义了一个View接口
视图对象由视图解析器负责实例化,由于视图是无状态的,所以它们不会有线程安全问题
常用的视图实现类
大类 | 视图类型 | 说明 |
URL视图 | InternalResourceView | 将JSP资源封装成一个视图,是springmvc默认使用的视图解析器。 |
JstlView | 如果jsp项目中导入了jstl标签的jar包,则springmvc会自动使用该视图解析器。 | |
文档视图 | AbstractExcelView | Excel文档视图的抽象类,该视图基于POI构造Excel文档 |
AbstractPdfVIew | PDF文档视图的抽象类,该视图基于iText构建Pdf文档 | |
报表视图 | ConfigurableJsperReportsView | 几个使用JasperReports报表技术的视图 |
JasperReportsCsvView | ||
JasperReportsMultiFormatView | ||
JasperReportsHtmlView | ||
JasperReportsPdfView | ||
JasperReportsXlsView | ||
JSON视图 | MapingJacksonJsonView | 将模型通过Jackson开源框架的ObjectMapper以Json方式输出 |
视图解析器(ViewResolver)
Spring MVC为逻辑视图名的解析提供了不同的策略,可以在Spring Web上下文中配置一种或多种解析策略,并指定它们之间的先后顺序。每一种策略对应一个具体视图解析器的实现类。
所有的视图解析器都必须实现ViewResolver接口
常用的视图解析器实现类
大类 | 视图类型 | 说明 |
解析为Bean的名字 | BeanNameViewResolver | 将逻辑视图名解析为一个Bean,Bean的id等于逻辑视图名。 |
解析为URL文件 | InternalResourceViewResolver | 将视图名解析为一个URL文件,一般使用该解析器将视图名映射为一个保存在WEB-INF目录下的程序文件(如JSP文件)。 |
JasperReportsViewResolver | JasperReports是一个基于Java的开源报表工具,该解析器将视图名解析为报表文件对应的URL。 | |
模板文件视图 | FreeMarkerViewResolver | 解析基于FreeMarker模版技术的模板文件 |
VelocityViewResolver | 解析基于Velocity模板技术的模板文件 | |
VelocityLayoutViewResolver |
JstlView
只要项目中引用了jstl标签,则Spring MVC会自动把视图由InternalResourceView转换为JstlView
JstlView是InternalResourceView的子类
常用的视图解析器的实现类
程序员可以选择一种视图解析器或混用多种视图解析器。
每个视图解析器都实现了Ordered接口并开放出了一个order属性,可以通过order属性设置解析器的优先级,order越小,优先级越高。
Spring MVC会按视图解析器顺序的优先级对逻辑视图名进行解析,直到解析成功并返回视图对象,否则会抛出ServletException异常。
重定向和转发
一般情况下,控制器返回字符串类型的值会被当成逻辑视图名进行处理。
如果返回字符串中带有forward:或者redirect:前缀时,SpringMVC会将其进行特殊处理。将forward:和redirect:作为指示符,其后面字符串作为url来处理
例:
forward
redirect
Spring表单标签
通过SpringMVC表单标签可以实现将模型数据中的属性和HTML表单元素进行绑定,以实现表单数据更便携编辑和回显。
使用Spring表单标签之前必须导入指令:
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
注意:要想使用这种标签必须先进入一个方法(如上图所示,先进入上图这个方法,然后return到index2页面,index2页面为下图页面),要在这个方法中绑定参数后,才能跳转到有这种标签的页面,否则直接进入有这种标签的页面会报错
还有一个问题需要注意:
对象类型的属性名一定得和类名一致(第一个字母小写,ps:见下图的commandName属性值和上图的user形参)属性否则会报错
Form的绑定问题
From默认自动绑定的是Model的command属性值,那么当我的form对像对应的属性名称不是command的时候,应该怎么办呢?
Spring给我们提供了一个commandName属性,我们可以通过该属性来指定我们将使用Model中的哪个属性作为form需要绑定的command对象。
也可以指定modelAttribute属性也可以达到相同的效果。
表单标签的通用属性
SpringMVC提供了多个表单标签,用以绑定表单字段的属性值,它们共有的属性如下。
path:表单字段,对应html中的name属性,支持级联属性。
htmlEscape:是否对表单的HTML特殊字符进行转换,默认值为true。
cssClass:对应的css样式。
cssErrorClass:发生错误时,对应的css样式。
Errors标签
form:errors:显示表单组件或数据效验所对应的错误。
<form:errors path="*" />:显示表单中所有的错误。
<form:errors path="user*" />:显示所有以user为前缀的属性对应的错误。
<form:error path="username" />:显示username表单元素的错误。
REST
REST(Representaional State Transfer):即(资源)表现层状态传递。
它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性
资源(Resources):网络上的一个实体,或者说网络上的一段信息。它可以是一段文本,一段歌曲,一张图片等等,可以用一个URL指向它,每个资源都有一个特定的,独一无二的URL,要访问这个资源,直接访问这个URI即可。
表现层(Representation):将资源呈现出来的形式。
状态转化(State Transfer):每发出一个请求,就代表客户端和服务器一次交互。HTTP协议是一个无状态的协议,即所有的状态都保存在服务器端。客户端想要操作服务器,必须通过某些手段,让服务器发生状态转化,而这种转化是建立在表现层之上的,所以就是表现层状态转化。
HTTP请求的四种状态
REST中规定HTTP协议中四个表示操作方式的动词:
GET:获取资源
POST:新建资源
PUT:更新资源
DELETE:删除资源
使用REST风格必须得现在web.xml文件中配置
POST请求
GET请求
注意:由于HTML只支持GET和POST请求,如果需要使用PUT和DELETE请求,还需要做如下修改:
method必须为post请求
需要在post请求中添加一个隐藏域:
Name=”_method”,value=”put/delete”
PUT请求
DELETE请求
乱码问题
提交表单时出现中文乱码,添加过滤器,配置在web.xml中
JS资源文件无法引用
在Springmvc配置文件中添加如下代码
或者在web.xml中添加如下代码
提交表单的路径问题
表单映射实体对象的问题
select标签绑定部门,无法直接映射问dept对象,需要映射id,然后根据id转换为部门对象
SpringMVC数据绑定流程
SpringMVC将ServletRequest对象及目标方法的形参实例传给WebDataBinderFactory实例,以创建DataBinder实例对象。
DataBinder调用装配在SpringMVC上下文中的ConversionService组件进行类型转换和数据格式化工作,将Servlet请求信息填充到形参对象中。
调用Validator组件对已经绑定了请求信息的形参对象进行数据有效性验证,并最终生成数据绑定结果BindingData对象。
SpringMVC抽取BindingResult中的形参对象和校检错误对象,将他们赋给处理方法的相应参数。
SpringMVC数据绑定的流程
SpringMVC通过反射机制对目标处理方法进行解析,将请求的消息到处理方法的形参中,数据绑定核心组件是DataBinder,运行机制如下。
DataBinder中有三个比较重要的属性
bindingResult:绑定的数据及错误结果对象
conversionService:类型转换及数据格式化对象
validators:数据验证对象
Spring支持的转换器
Spring定义了3中类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到ConversionServiceFactoryBean中
Converter<S,T>:将S类型转换为T类型。
ConverterFactory:将相同系列的多个“同质”Converter封装在一起,如果希望一种类型转换成另一种类型及其子类对象(例如:String转换为Number及Number的子类),可以使用该转换器工厂
GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型转换
自定义类型转换器
一、自定义类型转换器
- 配置SpringMVC.xml文件
利用ConversionServiceFactoryBean在Spring的IOC容器中定义一个ConversionService。Spring将自动识别出IOC容器中的ConversionService,并在Bean属性配置对应的类型转换器的实现类,SpringMVC处理方法的形参绑定时就会自动调用该类型转换器。
注意:ref中的bean属性为自定义类型转换器的类名(首字母小写)
三、编写jsp页面
在提交到add方法之前,会自动进入类型转换器,并把提交的数据切割好后,传给user对象。
四、后台获取值
关于mvc:annotation-driven
<mvc:annotation-driven />会自动注册以下三个Bean对象。
RequestMappingHandlerMapping
RequestMappingAdapter
ExceptionHandlerExceptionResolver
还将提供一下支持
支持使用ConversionService实例对表单参数进行实例转换。
支持使用@NumberFormatannotation、@DataFormatannotation注解完成数据类型的格式化。
支持使用@Valid注解对JavaBean实例进行JSR303验证。
支持使用@ReuqestBody和@ResponseBody注解
直接配置视图访问
<!--配置直接访问页面-->
<!--可以直接相应的转发页面,而无需再经过控制器-->
<mvc:view-controller path="/viewpath" view-name="viewname" />
<!--实际开发中通常都需要配置mvc:annotation-driven标签-->
<mvc:annotation-driven />
数据格式化
对属性的输入/输出格式化,其本质来讲依然属于类型转发的范畴
Spring在格式化模块中定义了一个实习ConversionService接口的FormattingConversionService实习类,该实现类扩展了GenericConversionService,因此它即具有类型转换的功能又具有格式化的功能
FormattingConversionService拥有一个FormattingConversionServiceFactoryBean工厂类,后者用于构造前者
FormattingConversionServiceFactoryBean内部已经注册了:
支持数字类型的属性用@NumberFormat注解
支持日期类型的属性使用@DateTimeFormat注解
装配了FormattingConversionServiceFactoryBean后,就可以在SpringMVC形参绑定及模型数据输出时使用注解驱动了。
@DateTimeFormat注解
可以对日期类型进行格式化。
Pattern属性:类型为字符串,指定解析/格式化字段的数据的模式。如“yyyy-MM-dd”
Iso属性:解析格式化的iso模式。
Iso.DATE(yyy-MM-dd)
Iso.TIME(hh:mm:ss.SSSZ)
ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ)
ISO.NONE(不使用)
Style属性:字符串类型,通过样式指定日期时间的格式,由两位字符组成,第一位表示日期的格式,第二位表示时间的格式。
S:短日期时间格式
M:中日期时间格式
L:长日期时间格式
F:完整日期时间格式
-:忽略日期时间格式
@NumberFormat
可对类似数字类型的属性进行标注,它拥有两个互斥的属性
Patten:类型为String,自定义样式,如“#,###”,#代表数字
Style:类型为NumberFormat.Style。用于指定样式类型,包括三种
Style.NUMBER:正常数字类型。
Style.CURRENCY:货币类型
Style.PERCENT:百分比类型
使用数据格式化
- 在实体类中使用数据格式化注解
- 配置SpringMVC.xml文件
方式一:
直接将画红色线条部分的代码删掉,就能使用数据格式化了,但是这样类型转换器就不能用了
方式二:
使用FormattingConversionServiceFactoryBean工厂类,这样既能使用类型转换器,又能使用数据格式化了
数据校验
JSR303
JSR303是Java为Bean数据合法性效验提供的标准框架,它已经包含在JavaEE6.0中。
JSR303通过在Bean属性上标注类似@NotNull、@Max等标准的注解指定验证规则,并通过标准的验证接口对Bean进行验证。
JSR303常用注解
注解 | 说明 |
@Null | 必须为null |
@NotNull | 必须不为null |
@AssertTrue | 必须为true |
@AssertFalse | 必须为false |
@Min(value) | 必须为一个数字,其值必须大于等于指定的最小值 |
@Max(value) | 必须为一个数字,其值必须小于等于指定的最小值 |
@DecimalMin(value) | 必须为一个数字,其值必须大于等于指定的最小值 |
@DecimalMax(value) | 必须为一个数字,其值必须小于等于指定的最小值 |
@Size(max,min) | 元素的大小必须在指定范围内 |
@Digits(int,fraction) | 必须是一个数字,其值必须在可接受范围内 |
@Past | 必须是一个过去的日期 |
@Future | 必须是一个将来的日期 |
@Pattern(value) | 其值必须符合指定的正则表达式 |
hibernate Validator扩展注解
Hibernate Validator是JSR3.0的一个扩展组件,除支持所有标准的效验注解外,它还支持以下扩展注解
注解 | 说明 |
| 被修饰的元素必须是电子邮件 |
@Length | 被修饰的元素长度必须在指定的范围内 |
@NotEmpty | 被修饰的元素必须非空 |
@Range | 被修饰的元素必须在合适的范围内 |
使用数据校验
一、导入jar包
配置SpringMVC.xml文件
和数据格式化配置一样
- 在实体类中添加验证注解
- 在目标方法Bean类型的前面添加@Valid注解。
注意:@Valid注解必须反正Bean类型参数的前面
SpringMVC的数据校验
<mvc:annotation-driven/>会默认装配好一个LocalValidator FactoryBean,通过在处理方法的入参上标注@valid注解即可让SpringMVC完成数据绑定后执行数据效验工作。
在已经标注了JSR303注解的表单/命令对象前标注一个@Valid,SpringMVC框架在将请求参数绑定到该形参对象后,就会调用效验框架根据注解声明的校检规则进行校检。
SpringMVC是通过对处理方法签名的规定来保存效验结果的,前一个表单/命令对象的效验结果,保存到随后的入参中,这个保存了效验结果的入参必须是BindingResult或者Error类型,这两个类都位于org.springframework.validation包中。
需效验的Bean对象和其绑定结果对象或错误对象是成对出现的,它们之间不允许声明其它入参。
Errors接口提供了获取错误信息的方法,如getErrorCount()或 getFieldErrors(String field)
BindingResult扩展了Errors接口。
在目标方法中获取效验结果
在表单/命令对象类的属性中标注效验注解,在处理方法对应的入参前添加@Valid,SpringMVC就会实施效验,并将效验结果保存被效验入参之后的BindingResult或Errors中。
常用方法 | 说明 |
FieldError getFieldError(String field) | 获取错误对象 |
List<FieldError> getFieldErrors() | 获取错误集合 |
Object getFieldValue(String field) | 获取单个错误的值 |
int getErrorCount() | 获取错误总数 |
在页面上显示错误信息
SpringMVC除了会将表单/命令对象的效验结果保存到对应的BindingResult或Errors对象中外,还会将所有效验结果保存到”隐含模型”中。
表单的名称必须和实体类的名称一致,小写开头。
即使处理方法的签名中没有对应于表单/命令对象的结果入参,效验结果也会保存在“隐含模型”中。
隐含模型中的所有数据最终将通过HttpServletRequest传递到JSP视图中,因此在JSP视图可以获取错误信息。
在JSP页面上可通过<form:errors path="username" />显示错误信息。
form:errors:显示表单组件或数据效验所对应的错误。
<form:errors path="*" />:显示表单中所有的错误。
<form:errors path="user*" />:显示所有以user为前缀的属性对应的错误。
<form:error path="username" />:显示username表单元素的错误。
如果没有配置国际化,那么它显示的是默认的提示消息
提示消息的国际化
首先需要在SpringMVC中配置
配置i18n.properites文件
用注解名.类名(第一个字母小写).属性名
若数据类型转换和数据格式化时发生了错误,或该有的参数不存在,或调用处理方法时发生错误,都会在隐含模型中创建错误信息。其错误代码前缀如下:
required:必要的参数不存在。
typeMismatch:在数据绑定时,发生数据类型不匹配的问题。
methodInvocation:SpringMVC调用处理方法时发生错误。
国际化
一、注册国际化资源文件
如果要使用语言切换的话,还得配置以下内容
- 在控制器中使用国际化
三、配置国际化文件
中文文件
用文件名前部分.属性名
英文文件
四、编写前台页面
导入spring标签
注意:使用了spring标签的页面不能直接进入,要通过其它页面跳转到这个页面来,否则会报错
用code=文件名前半部分.属性名
SpringMVC国际化工作原理
本地化解析器和本地化拦截器
AcceptHeaderLocalResolver:根据HTTP请求头的Accept-Language参数确定本地化类型,如果没有显示定义本地化解析器,SpringMVC使用该解析器。
CookieLocalResolver:根据指定的Cookie值确定本地化类型。
SessionLocalResolver:根据Session中特定的属性确定本地化类型。
LocaleChangeIntercepter:本地化拦截器,从请求参数中获取本次请求对应的本地化类型。
文件上传
SpringMVC为文件上传提供了直接的支持,这种支持是通过即插即用的MultipartResolver接口实现的,Spring用它的实现类CommonsMultipartResolver来实现
SpringMVC上下文中没有装配任何的MultipartResolver,因此默认情况下SpringMVC不能处理文件的上传操作,如果需要使用上传功能,需要手动配置MulitpartResolver。
- 在springmvc.xml文件中配置
- 编写前台页面
表单提交必须用post方式,否则报错
三、在后台保存上传文件
MultipartFile属性
MultipartFile可以获取表单提交过来的文件域
常用方法
isEmpty();判断是否提交文件
getContentType();获取文件类型
getName();获取表单元素名称
getOriginalFilename();获取提交的文件名称
getInputStreanm();获取文件流
getSize();获取文件大小
getBytes();获取字节数组
多个文件上传
多个文件其实SpringMVC会帮我们合并为一个MultipartFile[]数组,循环遍历就可以了
拦截器
SpringMVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义拦截器必须实现HandlerInterceptor接口。
perHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求的request进行处理。如果拦截器对请求进行拦截处理后还要调用其他拦截器,或者是业务处理器去进行处理,则返回true,如果不需要再调用其他的组件处理请求,则返回false。
postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet向客户端返回响应前被调用。在该方法对用户请求的数据进行处理。
afterCompletion():这个方法在DispatcherServlet完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
拦截器的执行顺序
多个拦截器的执行顺序
配置自定义拦截器
一、定义拦截器类继承HandlerInterceptor接口
- 配置springMVC.xml文件
异常处理
SpringMVC通过HandlerExceptionResolver处理程序异常,包括Handler映射、数据绑定以及目标方法执行时发生的异常。
SpringMVC提供的HandlerExceptionResolver实现类。
异常处理有三种方式
全局异常处理
SimpleMappingExceptionResolver
@ResponseStatus
全局异常处理
在普通的控制类也可以定义@ExceptionHandler注解方法,如果在当前内部出错的控制类找不到被@ExceptionHandler修饰的方法,则会去找@ControllerAdvice中的@ExceptionHandler注解方法
异常方法不能通过参数方式保存map信息,只能通过ModelAndView返回异常信息
@ExceptionHandler注解定义的方法优先级的问题
例如发生NullPointerException,但是声明的异常有RuntimeException和Exception,此时,会根据异常的最近继承关系找到继承关系最浅的那个@ExceptionHandler注解方法。也就是说会去找声明了RuntimeException方法
SimpleMappingExceptionResolver
@ResponseStatus
- 添加一个异常类,并使用@ResponseStatus注解
- 在方法中抛出异常
AJax和Json
在现在的项目中Ajax可以说是必须使用的技术,SpringMVC框架作为目前最受欢迎的框架,和Ajax的集成非常的友好,可以说是非常傻瓜式的。
当客户单使用ajax向服务器发送请求,服务器返回对应格式的数据,一般常见的数据格式有string,json,xml等。那么使用SpringMVC返回这些数据格式就是关键了。
处理json格式步骤
- 在目标方法前添加@ResponseBody注解
SpringMVC实现Json的原理
在SpringMVC中内置了一个HttpMessageConverter<T>接口,用来处理返回的数据格式。
HttpMessageConverter<T>是Spring3.0新添加的一个接口,负责将请求信息转换为一个对象(类型为T),将对象输出为响应信息
HttpMessageConverter<T>解析过程
当请求从客户端发送时,为一个HttpInputMessage请求对象,HttpMessageConverter将提交的请求转换为Java对象。传给SpringMVC的控制器方法。当返回数据时为Java对象时,HttpInputMessage又会将Java对象转换为HttpOutputMessage对象返回给客户端。
HttpInputMessage
当用户提交请求时,SpringMVC会将用户提交的请求转换为一个HttpInputMessage对象,这个对象器本质就是一个InputStream文件流对象。然后传递到给HttpMessageConverter进行转换成需要的对象,然后再传递给对应的服务器。
它继承了HttpMessage有一个InputStream getBody() throws IOException;抽象方法
HttpOutputMessage
当服务器返回数据时,也会先将数据交由HttpMessageConverter进行转换,生成一个HttpOutputMessage对象,这个对象也相当于OutputStream,然后再将这个对象发送到客户端
它继承了HttpMessage有一个OutputStream getBody() throws IOException;抽象方法
HttpMessageConverter实现类
实现类 | 说明 |
StringHttpMessageConverter | 将请求信息转换为字符串。 |
FormHttpMessageConverter | 将表单数据读取到MultiValueMap中。 |
ResourceHttpMessageConverter | 读写Resource对象。 |
XmlAwareFormHttpMessageConverter | 扩展于FormHttpMessageConverter,如果部分表单属性是XML数据,可用该转换器进行读取。 |
BufferedImageHttpMessageConverter | 读写BufferedImage对象。 |
ByteArrayHttpMessageConverter | 读写二进制数据。 |
SourceHttpMessageConverter | 读写Source类型的数据。 |
MarshallingHttpMessageConverter | 通过String的Marshaller和Unmarshaller读写XML信息。 |
Jaxb2RootElemengHttpMessageConverter | 通过Jaxb2读写XML信息,将请求信息转换到标注XmlRootElement和XmlType的类中。 |
MappingJacksonHttpMessageConverter | 利用Jackson开源包的ObjectMapper读写Json数据。 |
RssChannelHttpMessageConverter | 能够读写RSS种子信息。 |
AtomFeedHttpMessageConverter | 读写Atom格式的RSS信息。 |
@RequestBody
该注解用于读取Request请求的body部分数据,使用系统默认该配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上,再把HttpMessageConverter返回的对象数据绑定到controller中方法的参数上。
HttpEntity
HttpEntity和@RequestBody注解功能类似,都是将请求的参数转换为对应的对象
ResponseEntity
ResponseEntity和@ResponseBody功能一致,不过是做为返回类型
文件下载
使用ResponseEntity<byte[]>来实现文件下载。文件下载只需要将文件输出类型该为可以被下载的文件类型设置为ResponseEntity<byte[]>即可。
定时任务
当我们需要在特定的时间需要让某件事情去执行,在这期间做的一个计划就是一个定时任务。
它可以让计划的程序任务在一个预定义的日期和时间运行
Spring定时任务介绍
对于Spring3.0以前来说做定时任务是一件非常简单的事情,它内部集成了task的实现。Spring主要对一下几块做了抽象:
TaskExecutor :用来做Executors(线程池)相关的处理。
TaskScheduler:spring3.0以后才有的,主要用于定时启动。
Tigger:主要解决,有一些任务的执行,是由过去的执行结果或任意条件来决定时产生tigger ,通过TiggerContext来获取以前的执行信息。
TriggerContext:获取以前的执行信息
Spring4.X自带的定时任务无需其他JAR支持
Xml方式
一、导入头文件
二、配置springmvc.xml文件
三、后台
注解方式
fixedDelay:等待固定时长执行。下一个任务总是等上一个任务结束之后,并等待固定时延之后才开始。
initialDelay = 1000配置了initialDelay,任务的第一次运行会是在进程启动的1000ms之后在执行固定等待时长。
Cron:很多时候,仅仅有时间间隔和频率是不够的,我们需要一个比较灵活的,复杂的配置去控制定时任务,这时,我们就可以使用cron 表达式: @Scheduled(cron = "0 15 10 15 * ?")
Spring4.X+Quartz整合
什么是Quarzt?
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。
为什么要用Quartz?
它是一个任务调度框架。比如你遇到这样的问题:
想每月25号,信用卡自动还款;
想每年4月1日自己给当年暗恋女神发一封匿名贺卡;
想每隔1小时,备份一下自己的VR或学习笔记到云盘。
这些问题总结起来就是:在某一个有规律的时间点干某件事。
并且时间的触发的条件可以非常复杂(比如每月最后一个工作日的17:50),
复杂到需要一个专门的框架来干这个事。
Quartz就是来干这样的事,你给它一个触发条件的定义,
它负责到了时间点,触发相应的Job起来干活。
使用Quartz
导入Quartz2.X Jar包quartz-2.2.1.jar
使用简单定时任务
使用定时任务
不管是简单任务还是定时任务,最后都要在调用器工厂中引用,否则都无效