Spring MVC
1.SpringMVC概述
1)Spring为展现层提供的基于MVC设计理念的优秀的Web框架,是目前最主流的MVC框架之一
2)Spring3.0后全面超越Struts2,成为组优秀的MVC框架
3)SpringMVC通过一套MVC注解,让POJO成为处理请求的控制器,而无需实现任何接口
4)支持REST风格的URL请求
5)采用了松散耦合可插拔组件结构,比其他MVC框架更具扩展性和灵活性
2.SpringMVC:写一个简单的HelloWorld
1)加入jar包
2)在web.xml中配置DispatcherServlet
3)加入SpringMVC的配置文件
4)编写处理请求的处理器,并表示为处理器
5)编写视图
3.RequestMapping:
1)除了修饰方法,还可以来修饰类
2)类定义出:提供初步的请求映射信息。相对于WEB应用的根目录
3)方法处:提供进一步的细分映射信息。
4)相对于类定义处的URL。若类定义处未标注@RequestMapping,则方法处标记的URL相对于WEB应用的根目录
4.RequestMapping中的属性:
1)method:可以用来指定请求方式(常用)
2)params和headers:可以使用params和headers来更加精确的映射请求,params和headers支持简单的表达式。(了解)
3)RequestMapping支持的通配符:*,例子:@RequestMapping("/testAntPath/*/test")
4)PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中,可以来映射URL中的占位符到目标方法的参数中
5.REST(Representational State Transfer)
1)REST(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用
2)资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息(一段文本、一张图片),可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI,要获取这个资源,访问它的URI就可以,因此URI即为每一个资源的独一无二的识别符。
3)表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层,比如文本可以用txt格式、也可以HTML格式表现,甚至可以用二进制格式。
4)状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,就必须通过某种手段,让服务器端发生“状态转化 (State Transfer)”。而这种转化是建立在表现层之上的,所以就是“表现层状态转化”。具体说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:
GET:获取资源
POST:新建资源
PUT:更新资源
DELETE:删除资源
6.Rest风格的URL:
以CRUD为例:
新增:/order POST
修改:/order/1 PUT update?id=1
获取:/order/1 GET get?id=1
删除:/order/1 DELETE delete?id=1
7.如何发送PUT请求和DELETE请求:
1)需要配置HiddenHttpMethodFilter
2)需要发送POST请求
3)需要在发送POST请求时携带一个name="_method"的隐藏域,值为DELETE 或 PUT
在SpringMVC的目标方法中如何得到id呢?
在使用@PathVariable注解
8.@RequestParam来映射请求参数
1)value值:请求参数的参数名
2)required:该参数是否必须,默认为true
3)defaultValue:其你去参数的默认值(注意基本类型一般都需要设置一个默认值)
9.简单了解的注解:
1)@RequestHeader:映射请求头信息(用法基本上和RequestParam一样)
2)@CookieValue:映射cookie信息(用法基本上和RequestParam一样)
10.SpringMVC关于POJO的级联
1)Spring MVC会按照要求参数名和POJO属性名进行自动匹配
2)自动为该对象填充属性值。支持级联属性。
3)如 dept.deptId、dept.address.tel等
11.使用Servlet原生的API作为目标方法的参数,具体支持以下类型
1)HttpServletRequest
2)HttpServletResponse
3)HttpSession
4)java.security.Principal
5)Locale
6)InputStream
7)OutputStream
8)Reader
9)Writer
12.ModelAndView
1)目标方法的返回值可以使ModelAndView类型
2)其中可以包含视图和模型信息
3)SpringMVC会把ModelAndView的model中数据放入到request域对象中.
13.Map及Model
1)Spring MVC在内部使用了一个org.springframework.ui.Model接口存储模型数据
2)具体步骤:
SpringMVC在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器
3).如果方法的入参为Map或Model类型,SpringMVC会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据
14.@SessionAttributes
1)若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个@SessionAttributes,SpringMVC将在模型中对应的属性暂存到HttpSession中
2)SessionAttributes除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
3)例子:@SessionAttributes(value="names",types=User.class)
15.SpringMVC确定目标方法POJO类型入参的过程
1)确定一个key
①若目标方法的POJO类型的参数没有使用@ModelAttribute作为修饰,则key为POHO类名第一个字母的小写
②若使用了@ModelAttribute来修饰,则key为@ModelAttribute注解的value属性值
2)在implicitModer中查找key对应的对象,若存在,则作为入参传入
①若在@ModelAttribute标记的方法中在Map中保存过,且key和1确定的key一直,则会获取到
3)在implicitModel中不存在key对应的对象,则检查当前的Handler是否使用@SessionAttributes注解修饰,若使用了该注解,且@SessionAttributes注解的value属性值中包含了key,则会从HttpSession中来获取key所对应的value值,若存在则直接传入到目标方法的入参中。若不存在则将抛出异常。
4)若Handler没有表示@SessionAttributes注解或@SessionAttributes注解的value值中不包含key,则会通过反射来创建POJO类型的参数,传入为目标方法的参数
5)SpringMVC会把key和value保存到implicitModel中,进而会保护到request中
16.ModelAttribute
1)执行@ModelAttribute注解修饰的方法:从数据库中取出对象,把对象放入到Map中.键为:user
2)SpringMVC从Map中取出User对象,并把表单的请求参数赋给该User对象的对应属性。
3)SpringMVC把上述对象传入目标方法的参数。
4)注意:@ModelAttribute修饰的方法中,放入到Map时的键需要和目标方法入参类型的第一个字母小写的字符串一致。
17.ModelAttribute源代码分析的流程(难):
1)调用@ModelAttribute注解修饰的方法,实际上把@ModelAttribute方法中Map中的数据放在了implicitModel中。
2)解析请求处理器的目标参数,实际上该目标参数来自于WebDataBinder对象的target属性
①创建WebDataBinder对象:
i.确定objectName属性:若传入的attrName属性值为"",则objectName为类名第一个字母小写。
注意:attrName.若目标方法的POJO属性使用了@ModelAttribute来修饰,则attrName值即为@ModelAttribute的value属性值。
ii.确定target属性:
>在implicitModel中查找attrName对应的属性值。若存在,ok
>*若不存在:则验证当前Handler是否使用了@SessionAttributes进行修饰,若使用了,则尝试从Session中获取attrName所对应的属性值.若session中没有对应的属性值,则抛出了异常。
>若Handler没有使用@SessionAttributes进行修饰,或@SessionAttributes中没有使用value值指定的key和attrName相匹配,则通过反射创建了POJO对象。
②SpringMVC把表单的请求参数赋给了WebDataBinder的target对应的属性.
③*SpringMVC会把WebDataBinder的attrName和target给到implicitModel
④把WebDataBinder的target作为参数传递给目标方法的入参.
18.@ModelAttribute(使用简单说明):
1)有@ModelAttribute标记的方法,会在每个目标方法执行之前被SpringMVC调用!
2)@ModelAttribute注解也可以来修饰目标方法POJO类型的入参,其value属性值有如下的作用:
1)SpringMVC会使用value属性值在implicitModel中查找对应的对象,若存在则会直接传入到目标方法的入参中。
2)SpringMVC会以value为key,POJO类型的对象为value,存入到request中。
19.视图和视图解析器
1)请求处理方法执行完成后,最终返回一个ModelAndView对象。对于那些返回String,View或ModeMap等类型的处理方法,SpringMVC也会在内部将它们装配成一个ModelAndView对象,它包含了逻辑名和模型对象的视图
2)SpringMVC借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是JSP,也可能是Excel、JFreeChart等各种表现形式的视图
3)对于最终究竟采取何种视图对象对模型数据进行渲染,处理器并不关心,处理器工作重点聚焦在生产模型数据的工作上,从而实现MVC的充分解耦
20.视图:
1)视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。
2)为了实现视图模型和具体实现技术的解耦,Spring在org.springframework.web.servlet包中定义了一个高度抽象的View接口
3)视图对象由视图解析器负责实例化。由于视图是无状态的,所以他们不会有线程安全问题
21.视图解析器
1)SpringMVC为逻辑视图名的解析提供了不同的策略,可以在SpringWEB上下文中配置一种或多种解析策略,并制定他们之间的先后顺序。每一种映射策略对应一个具体的视图解析器实现类。
2)视图解析器的作用比较单一:将逻辑视图解析为一个具体的视图对象。
3)所有的视图解析器都必须实现ViewResolver接口
22.常用的视图解析器实现类
1)视图类型
①BeanNameViewResolver
②InternalResourceViewResolver
③JasperReportsViewResolver
④FreeMarkerViewResolver
⑤VelocityViewResolver
⑥VelocityLayoutViewResolver
2)程序员可以选择一种视图解析器或混用多种视图解析器
3)每种视图解析器都实现了Ordered接口并开放出一个order属性,可以通过order属性指定解析器的优先顺序,order越小优先级越高。
4)SpringMVC会按视图解析器顺序的优先顺序对逻辑视图名进行解析,知道解析成功并返回视图对象,否则将抛出ServletException异常
5)JSP是最常见的视图技术,可以用InternalResourceViewResolver作为视图解析器。
23.JstlView
1)若项目中使用了JSTL,则SpringMVC会自动把视图由InternalResourceView转为JstlView
2)若使用JSTL的fmt标签则需要在SpringMVC的配置文件中配置国际化资源文件
例子:<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property></bean>
3)若希望直接响应通过SpringMVC渲染的页面,可以使用mvc:view-controller标签实现
例子:<mvc:view-controller path="springmvc/testJstlView" view-name="success"/>
24.mvc_view-controller标签:
1)配置直接转发的页面
2)可以直接转发相应的页面,而无需再经过Handler的方法
例子:<mvc:view-controller path="/success" view-name="success"/>
3)在实际开发中通常都需配置mvc:annotation-driven 标签
例子:<mvc:annotation-driven></mvc:annotation-driven>
25.自定义视图
1)定义一个类,实现View的接口,并将这个类放到bean中
2)在xml文件中配置视图BeanNameViewResolver解析器,使用视图的名字来解析视图
3)通过order属性来定义解析器的优先级order值越小优先级越高
例子:<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="1"></property>
</bean>
26.重定向、请求转发
1)一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理
2)如果返回的字符串中带forward:或redirect:前缀时,SpringMVC会对他们进行特殊处理:将forward:和redirect:当成指示符,其后的字符串作为URL来处理
例子:@RequestMapping("testRedirect")
public String testRedirect() {
System.out.println("testRedirect");
return "redirect:/index.jsp";}
27.form标签
1)为什么使用form标签?
可以更快速的开发出表单页面,而且可以更方便的进行表单值的回显
2)path属性对应html表单标签的name属性值
3)通过SpringMVC的表单标签可以实现将模型数据中的属性和HTML表单元素相绑定,以实现表单数据更便捷的编辑和表单值的回显
4)一般情况下,通过GET请求获取表单页面,而通过POST请求提交表单页面,因此获取表单页面和提交表单页面的URL是相同的。只要满足该最佳条件的契约,<form:form>标签就无需通过action属性指定表单提交的URL
5)可以通过modouAttribute属性指定绑定的模型属性,若没有指定该属性,则默认从request域对象中读取command的表单bean,如果该属性值也不存在,则会发生错误
28.form表单标签
1)SpringMVC提供了多个表单组件标签,如<form:input/><form:select/>等,用以绑定表单字段的属性值,它们的共有属性如下:
①path:表单字段,对应html元素的name属性,支持级联属性
②htmlEscape:是否对表单值的HTML特殊字符进行转化,默认值为true
③cssClass:表单组件对应的CSS样式类名
④cssErrorClass:表单组件的数据存在错误时,采取的CSS样式
⑤textarea:对应HTML表单的text、password、hidden、textarea标签
⑥radiobutton:单选框组件标签,当表单bean对应的属性值的value值相同时,单选框被选中
⑦radiobuttons:单选框组标签,用于构造多个单选框
i.items:可以是一个List、String[]或Map
ii.itemValue:指定radio的value值。可以是集合中bean的一个属性值
iii.itemLabel:指定radio的label值
iiii.delimiter:多个单选框可以通过delimiter指定分隔符
⑧更多:checkbox、checkboxs、radiobuttons、select、option、errors
29.SpringMVC处理静态资源
1)为什么会有这样的问题:
优雅的REST风格的资源URL不希望带.html或.do等后缀,若将DispatcherServlet请求映射配置为/,则SpringMVC将捕获WEB容器的所有请求,包括静态资源的请求,SpringMVC会将他们当成一个普通请求来处理,因找不到对应处理器将导致错误
2)解决:在SpringMVC 配置文件中配置<mvc:default-servlet-handler/>
3)<mvc:default-servlet-handler/>将在SpringMVC上下文中定义一个DefaultServletHttpRequestHandler,它会对进入的DispathcerServlet的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由WEB应用服务器默认的Serlvet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理
4)一般WEB应用服务器默认的Servlet的名称的都是default。若所使用的WEB服务器的默认Servlet名称不是default,则需要通过default-servlet-name属性显式指定
30.数据绑定流程
1)Spring MVC主框架将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象
2)DataBinder调用装配在SpringMVC上下文中的ConversionService组件进行数据类型转换、数据格式化工作。将Servlet中的请求信息填充到入参对象中
3)调用Validator组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData对象
4)Spring MVC抽取BindingResult中的入参对象和校验错误对象,将它们赋给处理方法的响应入参
31.开发注意:
1)数据类型转换
2)数据类型格式化
3)数据校验
32.自定义类型转换器
1)ConversionService是Spring类型转换体系的核心接口
2)可以利用ConversionServiceFactoryBean在Spring的IOC容器中定义一个ConversionService.Spring将自动识别出IOC容器中的ConversionService,并在Bean属性配置及SpringMVC处理方法入参绑定等场合使用它进行数据的转换
3)可通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器
33.关于mvc:annotation-driven配置
1)开发中一般都是需要配置mvc:annotation-driven的
2)<mvc:annotation-driven>会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter与ExceptionHandlerExceptionResolver三个bean。
3)还提供一下支持
①支持ConversionService实例对表单参数进行类型转换
②支持@NumberFormat annotation、@DateTimeFormat注解完成数据类型的格式化
③支持@Valid注解对JavaBean实例进行JSR 303验证
④支持@RequestBody和@ResponseBody注解
34.@InitBinder
1)由@InitBinder标识的方法,可以对WebDataBinder对象进行个初始化。WebDataBinder是DataBinder的子类,用于完成由表单字段到JavaBean属性的绑定
2)@InitBinder方法不能有返回值,它必须声明为void
3)@InitBinder方法的参数通常是WebDataBinder
例子:
//不自动绑定lastName属性,另行处理
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("lastName");}
35.数据格式化
1)对属性对象的输入/输出进行格式化,从其本质上讲一眼属于“类型转换”的范畴
2)Spring在格式化模块中定义了一个实现ConversionService接口的FormattingConversionService实现类,该实现类扩展了GenericConversionService,因此它既具有类型转换的功能,又具有格式化的功能
3)FormattingConversionService拥有一个FormattingConversionServiceFactroyBean工厂类,后者用于在Spring上下文中构造前者
4)FormattingConversionServiceFactroyBean内部已经注册了:
①NumberFormatAnnotationFormatterFactroy:支持对数字类型的属性使用@NumberFormat注解
②JodaDateTimeFormatAnnotationFormatterFactroy:支持对日期类型的属性使用@DateTimeFormat注解
5)装配了FormattingConversionServiceFactroyBean后,就可以在SptingMVC入参绑定及模型数据输入时使用注解驱动了。<mvc:annotation-driven/>默认创建的ConversionService实际即为FormattingConversionServiceFactroyBean
6)如何获得转换错误的消息?
可以在目标方法中加入BindingResult参数,然后打印出错误消息
36.DateTimeFormat注解可对java.util.Date、java.util.Calendar、java.long.Long时间类型进行标注:
1)pattern属性:类型为字符串。指定解析/格式化字段数据的模式,如:“yyyy-MM-dd hh:mm:ss”
2)iso属性:类型为DateTimeFormat.ISO。指定解析/格式化字段数据的ISO模式,包括四种:ISO.NONE(不使用)--默认、ISO.DATE(yyyy-MM-dd)、ISO.TIME(hh:mm:ss.SSSZ)、ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ)
3)style属性:字符串类型。通过样式指定日期时间的格式,由两位字符组成,第一位表示日期的格式,第二位表示时间的格式:S:短日期/时间格式、M:中日期/时间格式、L:厂日期/时间格式、F:完整日期/时间格式、-:忽略日期或时间格式
37.数值格式化
1)@NumberFormat可对类似数字类型的属性进行标志,它拥有两个互斥的属性:
①style:类型为NumberFormat.Style。用于指定样式类型,包括三种:Style.NUMBER(正常数字类型)、Style.CURRENCY(货币类型)、Style.PERCENT(百分比类型)
②pattern:类型为String,自定义样式,如pattern="#,###";
38.数据校验
1)如何校验?注解?
①使用JSR 303验证标准
②加入hibernate validator验证框架的jar包
③在SpringMVC配置文件中添加<mvc:annotation-driven/>
④需要在bean的属性上添加对应的注解
⑤在目标方法的bean类型的前面添加@Valid注解
2)验证除错转向到哪一个页面?
3)错误消息如何显示,如何把错误消息进行国际化?
39.JSR 303
1)JSR 303是Java为Bean数据合法性校验提供的标准框架,已经包含在JavaEE6.0中
2)JSR 303通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则,并通过标准的校验接口对Bean进行校验
3)例子:@Null(要为null)、@NotNull(不能为null)、@AssertTrue(元素必须为true)、@AssertFalse(为false)、@Min(value)(备注是的元素必须是一个数组,其值必须大于等于指定的最小值)、@Min(value)、@Size(max,min)(元素大小必须在指定的范围内)、@Digtis(integer,fraction)(必须是一个数字,其值必须在可接受的范围内)、@Past(必须时一个过去的日期)、@Future(必须时一个将来的日期)、@Pattern(value)(被注释的元素必须符合规定的正则表达式)
40.Hibernate Validator是JSR 303的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
@Email(被注释的元素必须时电子邮箱地址)、@Length(字符串大小必须在指定的范围内)、@NotEmpty(字符串必须非空)、@Range(必须在合适的范围内)
41.SpringMVC数据校验
1)Spring4.0拥有自己独立的数据校验框架,同时支持JSR 303标准的校验框架
2)Spring在进行数据绑定时,可同时调用校验框架完成数据校验工作。在SpringMVC中,可直接通过注解驱动的方式进行数据校验
3)Spring的LocalValidatorFactroyBean既实现了Spring的Validator接口,也实现了JSR303的Validator接口。只要在Spring容器中定义了一个LocalValidatorFactoryBean即可将其注入到需要数据校验的Bean中
4)Spring本身并没有提供JSR303的实现,所以必须将JSR303的实现者的jar包放到类路径下
5)<mvc:annotation-driven/>会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@valid注解即可让SpringMVC在完成数据绑定后执行数据校验的工作
6)在已经标注了JSR303注解的表单/命令对象前标注一个@Valid,SpringMVC框架在将请求参数绑定到该入参对象后,就会调用校验框架更具注解声明的校验规则实施校验
7)SpringMVC是通过对处理方法签名的规约来保存校验结果的:前一个表单/命令对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须时BindingResult或Errors类型,这两个类都位于org.springframework.validation包中
42.在页面上显示错误
1)SpringMVC除了会将表单/命令对象的校验结果保存到对应的BindingResult或Errors对象中外,还会降所有校验结果保存到“隐含模型”
2)即使处理方法的签名中没有对应于表单/命令对象的结果入参,校验结果也会保存在“隐含对象”中。
3)隐含模型中的所有数据最终将通过HttpServletRequest的属性列表暴露给JSP视图对象,因此在JSP中可以获取错误信息
4)在JSP页面上可通过<form:errors path="userName">显示错误信息
43.提示消息国际化
1)每个属性在数据绑定和数据校验发生错误时,都会生成一个对应的FieldError对象
2)当一个属性校验失败后,校验框架会为该属性生成4个消息代码,这些代码以校验注解类名为前缀,结合modleAttribute、属性名及属性类型名生成多个对应的消息代码:例如User类中的password属性标注了一个@Pattern注解,当该属性值不满足@Pattern所定义的规则时,就会产生以下4个错误代码:
- Pattern.user.password
- Pattern.password
- Pattern.java.lang.String
- Pattern
3)当使用SpringMVC标签显示错误消息时,SpringMVC会查看WEB上下文是否装配了对应的国际化消息,如果没有,则显示默认的错误消息,否则使用国际化消息。
4)若数据类型或数据格式转化时发生错误,或该有的参数不存在,或调用处理方法时发生错误,都会在隐含模型中创建错误消息。其错误代码前缀说明如下:
- required:必要的参数不存在。如@RequiredParam("param1")标注了一个入参,但是该参数不存在
- typeMismatch:在数据绑定时,发生数据类型不匹配的问题
- methodInvocation:Spring MVC在调用处理方法时发生了错误
5)配置国际化资源例子:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property>
</bean>
44.处理JSON
1)加入jar包:关于jackson的三个jar包(annotation、core、databind)
2)编写目标方法,使其返回JSON对应的对象或集合
3)在方法上添加@ResponseBody注解
45.处理JSON使用原理(HttpMessageConverter<T>)
1)HttpMessageConverter<T>是Spring3.0新添加的一个接口,负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息
2)HttpMessageConverter<T>接口定义的方法:
- Boolean canRead(Class<?> clazz,MediaType mediaType):指定转换器可以读取的对象类型,即转换器是否可将请求信息转换为clazz类型的对象,同时指定支持MIME类型(text/html,application/json等)
- Boolean canWrite(clazz,MediaType mediaType)
...详见SpringMVC P42
46.使用HttpMessageConverter<T>
1)使用HttpMessageConverter<T>将请求信息转化并绑定到处理方法的入参中或将响应结果转为对应类型的响应信息,Spring提供了两种途径:
①使用@RequestBody/@ResponseBody对处理方法进行标注
②使用HttpEntity<T>/ResponseEntity<T>作为处理方法的入参或返回值
2)当控制器处理方法使用到@RequestBody/@ResponsBody或HttpEntity<T>/ResponseEntity<T>时,Spring首先更具请求头或响应头的Accept属性选择匹配的HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的HttpMessageConverter,若找不到可用的HttpMessageConverter将报错
3)@RequestBody和@ResponseBody不需要成对出现
47.国际化
1)关于国际化:
①在页面上能够根据浏览器语言设置的情况对文本(不是内容),时间,数值进行本地化处理
②可以在bean中获取国际化资源文件Locale对应的消息
③可以通过超链接切换Locale,而不再依赖于浏览器的语言设置情况
2)解决:
①使用JSTL的fmt标签
②在bean中注入ResourceBundleMessageSource的示例,使用其对应的getMessage方法即可
③配置LocalRsolver和LocaleChangeInterceptor
48.通过超链接的方式国际化(SessionLocaleResolver&LocaleChangeInterceptor工作原理)
1)获取name=locale的请求参数
2)把第一步的locale请求参数解析为Locale对象
3)获取LocaleResolver对象
4)把Locale对象设置为Session的属性
5)从Session中获取Locale对象
6)使用该Locale对象
49.文件上传
1)SpringMVC为文件上传提供了直接的支持,这种支持是通过即插即用的MultipartResolver实现的。Spring用Jakarta Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResovler
2)SpringMVC上下文中默认没有装配MultipartResovler,因此默认情况下不能处理文件的上传工作,如果想使用Spring的文件上传功能,需现在上下文中配置MultipartResolver
50.配置MultipartResolver
1)defaultEncoding:必须和用户JSP的pageEncoding属性一致,以便正确解析表单的内容
2)为了让CommonsMultipartResovler正确工作,必须先将Jakarta Commons FileUpload及Jakarta Commons io的类包添加到类路径下
3)例子:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>
51.自定义拦截器
1)SpringMVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HnadlerInterceptor接口
- preHnadle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求reques进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。
- postHandle():这个方法在业务处理器处理完请求后,但是DispatherServlet向客户端返回响应前被调用,在该方法中对用户请求request进行处理。
- afterCompletion():这个方法在DispatcherServlet完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
2)配置拦截器(不)作用的路径,例子:
<mvc:interceptors>
<!-- 配置自定义拦截器 -->
<bean class="com.nick.springmvc.interceptor.FirstInterceptor"></bean>
<mvc:interceptor>
<mvc:mapping path="/emps"/>
<bean class="com.nick.springmvc.interceptor.SecondInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
52.异常处理
1)SpringMVC通过HandlerExceptionResolver处理程序的异常,包括Handler映射、数据绑定以及目标方法执行时发生的异常。
2)SpringMVC提供的HandlerExceptionResolver的实现类
3)DispathcerServlet默认的HandlerExceptionResolver
①没有使用<mvc:annotation-driven/>配置:
AnnotationMehtodHandlerExceptionResolver(id=141)
ResponseStatusExceptionResolver(id144)
DefaultHandlerExceptionResolver(id148)
②使用了<mvc:annotation-driven/>配置:
ExceptionHandlerExceptionResolver(id140)
ResponseStatusExceptionResolver(id144)
DefaultHandlerExceptionResolver(id148)
53.ExceptionHandlerExceptionResolver
1)主要处理Handler中用@ExceptionHandler注解定义的方法
2)@ExceptionHandler注解定义的方法优先级问题:例如发生的NullPoionterException,但是声明的异常有RuntimeException和Exception,此时会根据异常的最近继承关系找到继承深度最浅的那个@ExceptionHandler注解方法,即标记了RuntimeException的方法
3)ExceptionHnadlerMethodResolver内部若找不到@ExceptionHandler注解的话,会找ControllerAdvice中的@ExceptionHnadler注解方法
54.关于@ExceptionHandler注解
1)@ExceptionHandler方法的入参中可以加入Exception类型的参数,该参数即对应发生的异常对象
2)@ExceptionHandler方法的入参中不能传入Map。若希望把异常信息传到页面上,需要使用ModelAndView作为返回值
3)@ExceptionHandler方法标记的异常有优先级的问题
4)@ControllerAdvice:如果在当前Handler中找不到@ExceptionHandler方法来处理当前方法出现的异常,则将去@ControllerAdvice标记的类中查找@ExceptionHandler标记的方法来处理异常
55.ResponseStatusExceptionResolver
1)在异常及异常父类中找到@ResponseStatus注解,然后使用这个注解的属性进行处理
2)定义一个@ResponseStatus注解修饰的异常类,例子:
@ResponseStatus(value=HttpStatus.NOT_FOUND,reason="测试")
public class UserNameNotMatchPasswordException extends Exception{
private static final long serialVersionUID = 1L;
}
3)若在处理其方法抛出了上述异常:若ExceptionHandlerExceptionResolver不解析述异常。由于触发的异常UserNameNotMatchPasswordException带有@ResponseStatus注解。因此会被ResponseStatusExceptionResolver解析到。最后响应HttpStatus.NOT_FOUND代码给客户端。
56.DefaultHandlerExceptionResolver
1)对一些特殊的异常进行处理,比如:
NoSuchRequestHandlingMethodException、
HttpRequestMethodNotSupportedException、
HttpMediaTypeNotSupportedException、
HttpMediaTypeNotAcceptableException等。
57.SimpleMappingExceptionResolver
1)如果希望对所有异常进行统一处理,可以使用SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
2)例子:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>
58.SpringMVC运行流程图解+源码解析(重点,便于理解SpringMVC)
SpringMVC P55-P56
59.Spring整合SpringMVC:
问题:需要进行Spring整合SpringMVC吗?还是否需要再加入Spring的IOC容器?是否需要在web.xml文件中配置启动SpringIOC容器的ContextLoaderListener?
1)需要:通常情况下,类似于数据源,事务,整合其他框架都是放在Spring的配置文件中(而不是放在SpringMVC的配置文件中).实际上放入Spring配置文件对应的IOC容器中的还有Service和Dao。
2)不需要:都放在SpringMVC的配置文件中,也可以分多个Spring的配置文件,然后使用import结点导入其他配置文件
60.用Spring整合SpringMVC
1)问题:若Spring的IOC容器和SpringMVC的IOC容器扫描的包有重合的部分,就会导致有的bean会被创建两次
解决:
①使用Spring的IOC容器扫描的包和SpringMVC的IOC容器的扫描的包没有重合的部分
②使用exclude-filter和include-filter子节点来规定只能扫描的注解
2)SpringMVC的IOC容器中的bean可以来引用SpringIOC容器中的bean。反之则不行,Spring IOC容器中的bean却不能来引用SpringMVC IOC容器的bean
61.在SpringMVC配置文件中引用业务层的Bean
1)多个Spring IOC容器之间可以设置为父子关系,以实现良好的解耦
2)SpringMVC WEB层容器可作为“业务层”Spring容器的子容器:即WEB层容器可以引用业务层容器的Bean,而业务层容器却访问不到WEB层容器的Bean
62.SpringMVC对比Struts2
1)SpringMVC的入口是Servlet,而Struts2是Filter
2)SpringMVC会稍微比Struts2快些。SpringMVC是基于方法设计,而Struts2是基于类,每发一次请求都会实例一个Action
3)SpringMVC使用更加简洁,开发效率SpringMVC确实比Struts高:只是JSR303,处理ajax的请求更方便
4)Struts2的OGNL表达式使页面的开发效率相比SpringMVC更高些。