Spring MVC
1、Spring MVC概述
Spring MVC框架圍繞DispatcherServlet這個(gè)核心展開,DispatcherServlet負(fù)責(zé)截獲請(qǐng)求并將其分配給響應(yīng)的處理器處理。Spring MVC框架包括注解驅(qū)動(dòng)控制器、請(qǐng)求及響應(yīng)的信息處理、視圖解析、本地化解析、上傳文件解析、異常處理以及表單標(biāo)簽綁定等內(nèi)容。
2、注解驅(qū)動(dòng)的控制器
2.1、使用@RequestMapping映射請(qǐng)求
- 通過請(qǐng)求URL進(jìn)行映射
@RequestMapping("/user/register")
@RequestMpping不但支持標(biāo)準(zhǔn)的URL,還支持Ant風(fēng)格(即?、和*的字符)的和帶{xxx}占位符的URL,可以通過@ParhVariable將URL中的占位符參數(shù)綁定到控制器處理方法的入?yún)⒅小?/p>
- 通過請(qǐng)求參數(shù)、請(qǐng)求方法或請(qǐng)求頭進(jìn)行映射
@RequestMapping(value="/delete", method=RequestMethod.POST, params="userId", headers="content-type=text/*")
2.2、請(qǐng)求處理方法簽名
- 使用@RequestParam綁定請(qǐng)求參數(shù)值
public String handle(@RequestParam(value="userName", required=false))
- 使用@CookieValue綁定請(qǐng)求中的Cookie值
public String handle(@CookieValue(value="sessionId", required=false))
- 使用@RequestHeader綁定請(qǐng)求報(bào)文頭的屬性值
public String handle(@RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive")long keepAlive)
- 使用命令/表單對(duì)象綁定請(qǐng)求參數(shù)值
/handle.html?userName=tom&userAge=12
Public String handle(User user)
- 使用Servlet API對(duì)象作為入?yún)?br>
public void handle(HttpServletRequest req, HttpServletResponse resp)
- 使用Spring MVC自定義的可代理Servlet原生API類的接口
public String handle(WebRequest req)
- 使用IO對(duì)象作為入?yún)?br>
Spring MVC可以獲取ServletRequest的InputStream/Reader或者ServletRespons的OutputStream/Writer,然后傳給控制器的處理方法
public void handle(OutputStream os)
2.3、使用HttpMessageConverter<T>
HttpMessageConverter<T>是Spring 3.0新添加的一個(gè)重要的接口,它負(fù)責(zé)將請(qǐng)求信息轉(zhuǎn)換為一個(gè)對(duì)象(類型為T),將對(duì)象(類型為T)輸出為響應(yīng)信息。
如果在Spring web容器中顯式定義了一個(gè)AnnotationMethodHandlerAdapter,則Spring MVC將使用它覆蓋默認(rèn)的AnnotationMethodHandlerAdapter。
使用途徑:
1、使用@RequestBody/@ResponseBody對(duì)處理方法進(jìn)行標(biāo)注;
2、使用@HttpEntity<T>/ResponsEntity<T>作為處理方法的入?yún)⒒蛘叻祷刂担?/p>
2.4、處理模型數(shù)據(jù)
Spring MVC提供了多種途徑將模型數(shù)據(jù)暴露給視圖
- ModelAndView:處理方法返回值類型為ModelAndView時(shí),方法體即可通過該對(duì)象添加模型數(shù)據(jù);
- @ModelAttribute:方法入?yún)?biāo)注該注解后,入?yún)⒌膶?duì)象就會(huì)放到數(shù)據(jù)模型中;
- Map 及 Model:入?yún)閛rg.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map時(shí),處理方法返回時(shí),Map中的數(shù)據(jù)會(huì)自動(dòng)添加到模型中;
- @SessionAttributes:將模型中的某個(gè)屬性暫存到HttpSession中,以便多個(gè)請(qǐng)求之間共享這個(gè)屬性;
控制器方法返回字符串類型的值會(huì)被當(dāng)成邏輯視圖名處理。當(dāng)字符串帶"forward"或"redirect"前綴時(shí),redirect會(huì)讓瀏覽器發(fā)起一個(gè)新的請(qǐng)求,而forward所到的目標(biāo)地址位于當(dāng)前請(qǐng)求中。
3、處理方法的數(shù)據(jù)綁定
Spring MVC會(huì)根據(jù)請(qǐng)求方法簽名的不同,將請(qǐng)求消息中的消息以一定的方式轉(zhuǎn)換并綁定到請(qǐng)求方法的入?yún)⒅?。在?qǐng)求消息到達(dá)真正調(diào)用處理方法的這一段時(shí)間內(nèi),Spring MVC還完成了很多工作,包括數(shù)據(jù)轉(zhuǎn)換、數(shù)據(jù)格式化及數(shù)據(jù)校驗(yàn)等。
3.1、數(shù)據(jù)轉(zhuǎn)換
//自定義轉(zhuǎn)換器 <userName>:<password>:<realName> -> UserObject
public class StringToUserConverter implements Converter<String, User >{...}
//將StringToUserConverter安裝到Spring上下文中
<beans ...>
<mvc:annotation-drever conversion-service="conversionService">
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactorybean">
<property name="converters"><list>
<bean class="...StringToUserConverter"/>
</list></property>
</bean>
</beans>
//使用StringToUserConverter
@ReqquestMapping(value="")
public String handle(@RequestParam("user") User user)
//url
xxx.html?user=tom:1234:jacktion
3.2、數(shù)據(jù)格式化
//將FormattingConversionServiceFactoryBean安裝到Spring上下文中
org.springframework.format.support.FormattingConversionServiceFactoryBean
//使用注解驅(qū)動(dòng)格式化功能
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
Spring 提供了注解驅(qū)動(dòng)的屬性對(duì)象格式化功能:在Bean屬性設(shè)置、Spring MVC處理方法入?yún)?shù)據(jù)綁定、模型數(shù)據(jù)輸出時(shí)自動(dòng)通過注解應(yīng)用格式化的功能。
3.3、數(shù)據(jù)校驗(yàn)
JSR 303是Java為Bean數(shù)據(jù)合法性校驗(yàn)所提供的標(biāo)準(zhǔn)框架,它已經(jīng)包含在Java EE6.0中。
- Spring校驗(yàn)框架 LocalValidatorFactoryBean即實(shí)現(xiàn)了Spring的Validator接口,也實(shí)現(xiàn)了JSR303的Validator接口。
- Spring MVC數(shù)據(jù)校驗(yàn),在表單/命令對(duì)象標(biāo)注JSR303注解
@Pattern(regexp="");//正則表達(dá)式
private String userName;
@Length(min=2, max=100)//字符串長(zhǎng)度
@DecimalMin //數(shù)值最小值
- 校驗(yàn)結(jié)果保存,前一個(gè)表單/命令對(duì)象的校驗(yàn)結(jié)果保存在其后的入?yún)⒅?,這個(gè)校驗(yàn)結(jié)果的入?yún)⒈仨毷且粋€(gè)BindingResult和Errors類型
public String handle(@Valid @ModelAtterbute("user") User user, BindingResult bindingResult, @Valid Dept dept, Errors depErrors)
{if(bindingResult.hasError()) return ...}
- 頁(yè)面顯示錯(cuò)誤
Spring MVC除了會(huì)將表單/命令對(duì)象的校驗(yàn)結(jié)果保存在對(duì)應(yīng)的BindingResult或Errors中,還會(huì)將所有校驗(yàn)結(jié)果保存到“隱含模型”中。
<form:errors path="*"/> //顯示表單對(duì)象所有的錯(cuò)誤信息
<form:errors path="userName" cssClass="errorClass"/> //顯示userName屬性的錯(cuò)誤
4、視圖和視圖解析器
請(qǐng)求方法執(zhí)行完以后,最中返回一個(gè)ModelAndView對(duì)象,對(duì)于那些返回String、View或ModelMap等類型的處理方法,Spring MVC也會(huì)在內(nèi)部將他們裝配成一個(gè)ModelAndView對(duì)象,它包含了視圖邏輯名和模型對(duì)象的信息??梢酝ㄟ^orderNo屬性指定解析器的優(yōu)先順序,orderNo值越小優(yōu)先級(jí)越高。
4.1、視圖解析器
視圖解析器工作內(nèi)涵:根據(jù)邏輯視圖名和本地化對(duì)象得到一個(gè)視圖對(duì)象。
4.2、JSP和JSTL
jsp是最常見的視圖技術(shù),使用InternalResourceViewResolver作為視圖解析器。
4.3、 模板視圖
Spring Web上下文裝配FreeMarker的基礎(chǔ)設(shè)施和FreeMark視圖解析器:
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
4.4、Excel
擴(kuò)展Spring的AbstractExcelView 或 AbstractJExcelView,使用BeanNameViewResolver視圖解析器。
4.5、PDF
擴(kuò)展AbstractOdfView,使用BeanNameViewResolver視圖解析器。
4.6、輸出XML
使用MarshallingView視圖解析器,注入XStreamMarshaller,將模型數(shù)據(jù)轉(zhuǎn)化為XML。
4.7、 輸出JSON
Spring MVC的MappingJacksonJsonView借助Jackson框架的ObjectMapper將模型數(shù)據(jù)轉(zhuǎn)化為JSON格式輸出。
4.8、混合使用多種視圖技術(shù)
ContentNegotiatingViewResolver根據(jù)請(qǐng)求所要求的MIME類型決定由哪個(gè)視圖解析器負(fù)責(zé)解析,一般將其的優(yōu)先級(jí)設(shè)置為最高。
5、本地化解析
- AcceptHeaderLocaleResolver:根據(jù)HTTP報(bào)文頭的Accept-Language參數(shù)確定本地化類型;
- CookieLocaleResolver:根據(jù)指定的Cookie值確定本地化類型;
- SessionLocaleResolver:根據(jù)Session中特定的屬性值確定本地化類型;
- LocaleChangeInterceptor:從請(qǐng)求參數(shù)中獲取本次請(qǐng)求對(duì)應(yīng)的本地化類型;
6、文件上傳
Spring MVC通過Jakarta Commons FileUpload技術(shù)實(shí)現(xiàn)了一個(gè)Multipartresolver實(shí)現(xiàn)類:CommonsMultipartResolver。
7、雜項(xiàng)
7.1、靜態(tài)資源處理
- 采用<mvc:default-servlet-handler/>將靜態(tài)資源的處理經(jīng)由Spring MVC框架交回Web應(yīng)用服務(wù)器處理;
- <mvc:resources mapping="" location=""/> 由Spring MVC框架自己處理靜態(tài)資源,并添加有用的附加值功能;
7.2、裝配攔截器
<mvc:interceptors></mvc:interceptors>
7.3、異常處理
Spring MVC通過HandlerExceptionResolver處理程序的異常,包括處理器映射、數(shù)據(jù)綁定以及處理器執(zhí)行時(shí)的異常。
- DeaufaultHandlerExceptionResolver 會(huì)將Spring MVC框架的異常轉(zhuǎn)換為相應(yīng)的相應(yīng)狀態(tài)碼;
- AnnotationMethodHandlerExceptionResolver 允許通過@ExceptionHandler的注解指定處理特定異常的方法;
- SimpleMappingExceptionResolver 將異常類名映射為視圖名,即發(fā)生異常時(shí)使用對(duì)應(yīng)的視圖報(bào)告異常;