javascript
【SSM框架系列】SpringMVC的请求和响应
request和response
request對象的作用
response功能
Springmvc僅僅是對上述兩個對象進(jìn)行了封裝,所以Springmvc的請求和響應(yīng)與上面一致。
springmvc響應(yīng)數(shù)據(jù)
頁面跳轉(zhuǎn)
1)直接返回字符串
返回的是要跳轉(zhuǎn)的資源路徑名,資源路徑名可以是html、jsp或者是Controller中其他的方法虛擬資源路徑。默認(rèn)是請求轉(zhuǎn)發(fā),如果想要重定向,要寫:redirect:資源路徑名(不需要帶項(xiàng)目名)。
2)返回通過ModelAndView對象
在Controller中方法使用ModelAndView對象并且設(shè)置視圖名稱,并將該對象返回,
這個ModelAndView對象可以是在方法內(nèi)部new出來的,如下:
也可以在Controller中方法形參上直接聲明一個ModelAndView對象。
這種方式無需自己在方法中創(chuàng)建,框架會幫我們將ModelAndView對象注入,直接使用設(shè)置視圖名稱即可。
@RequestMapping(value="/quick3") public ModelAndView save3(ModelAndView modelAndView){modelAndView.addObject("username","趙麗穎");modelAndView.setViewName("success");return modelAndView; }ModelAndView對象的功能:
上述兩種方式獲得的ModelAndView對象都可以完成以下兩個功能
modelAndView.setViewName("/success.jsp");
modelAndView.addObject(“username”,“趙麗穎”);
使用ModelAndView注意事項(xiàng):
這種方式只能通過返回ModelAndView對象實(shí)現(xiàn)頁面跳轉(zhuǎn),除此之外的其他方式返回字符串(資源路徑名稱)即可實(shí)現(xiàn)頁面跳轉(zhuǎn)。
如果使用ModelAndView封裝數(shù)據(jù),必須通過返回該ModelAndView對象實(shí)現(xiàn)頁面跳轉(zhuǎn),否則在跳轉(zhuǎn)后的頁面會拿不到數(shù)據(jù)。
回寫數(shù)據(jù)
直接回寫字符串
原始方式:相當(dāng)于response.getWriter().print(“hello”),將一個字符串直接寫入到前端頁面,原頁面內(nèi)容會被覆蓋。這種用法建議不用。
Springmvc方式:將需要回寫的字符串直接返回,需要通過@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳轉(zhuǎn)是直接在http響應(yīng)體中返回,業(yè)務(wù)方法返回值也是void
ResponseBody用法:
- 如果不寫該注解,方法的String返回值會被當(dāng)做一個要跳轉(zhuǎn)的資源名稱
- 在方法上添加@ResponseBody注解后,則會將String類型的返回值響應(yīng)到頁面
- 如果是同步請求,會直接在頁面上顯示,但是會覆蓋掉原來頁面的內(nèi)容
- 如果是異步請求,會返回到異步請求的回調(diào)函數(shù)中
返回對象或集合
方式1
為處理器適配器(RequestMappingHandlerAdapter)配置消息轉(zhuǎn)換器(MappingJackson2HttpMessageConverter),指定使用jackson進(jìn)行對象或集合的轉(zhuǎn)換。
在spring-mvc.xml中進(jìn)行如下配置:
<bean class=" org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter "><property name="messageConverters"><list><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/></list></property></bean>然后在業(yè)務(wù)方法中直接返回需要轉(zhuǎn)換的對象或集合即可。此時仍需要@ResponseBody注解,因?yàn)樵诨貙憯?shù)據(jù)。
@RequestMapping(value="/quick10")@ResponseBody//期望SpringMVC自動將User轉(zhuǎn)換成json格式的字符串public User save10() throws IOException {User user = new User();user.setUsername("趙麗穎");user.setAge(18);return user;}方式二
可以使用mvc的注解驅(qū)動代替上述配置復(fù)雜配置
<!-- 萬能標(biāo)簽,Springmvc首配 --><mvc:annotation-driven/>這是一個神奇的標(biāo)簽,能幫代替我們完成很多工作,所以使用Springmvc開發(fā),第一步先在配置文件中配置該標(biāo)簽。原理如下:
-
處理器映射器、處理器適配器、視圖解析器稱為 SpringMVC 的三大組件。
-
使用<mvc:annotation-driven />將自動加載 RequestMappingHandlerMapping(處理映射器)和RequestMappingHandlerAdapter( 處 理 適 配 器 )。
-
所以可以在Springmvc配置文件中使用<mvc:annotation-driven />替代處理映射器和處理適配器的配置。
-
同時使用<mvc:annotation-driven />默認(rèn)底層就會集成jackson進(jìn)行對象或集合的json格式字符串的轉(zhuǎn)換。
Springmvc把對象通過json形式回寫的步驟就變成了如下簡單幾步:
說明:
- 如果視圖層使用JSP技術(shù),Controller一般返回ModelAndView
- 如果視圖層使用HTML技術(shù),Controller一般返回JSON字符串,可以在HTML發(fā)送異步請求,后臺響應(yīng)JSON字符串到Ajax的回調(diào)函數(shù)中,返回JSON字符串,可以返回對象或集合,讓SpringMVC框架轉(zhuǎn)換為JSON字符串
- 需要配置兩個地方
- 方法上@ResponseBody
- 配置文件 <mvc:annotation-driven />
SpringMVC獲取請求數(shù)據(jù)
Springmvc獲取的請求參數(shù)類型
客戶端請求參數(shù)的格式是:name=value&name=value……
服務(wù)器端要獲得請求的參數(shù),有時還需要進(jìn)行數(shù)據(jù)的封裝,SpringMVC可以接收如下類型的參數(shù)
Springmvc可以把請求參數(shù)中的參數(shù)值直接賦值給業(yè)務(wù)方法的形參。
要求:Controller中的業(yè)務(wù)方法的參數(shù)名稱要與請求參數(shù)的name一致,參數(shù)值會自匹配賦值。并且能自動做類型轉(zhuǎn)換。
自動的類型轉(zhuǎn)換是指從String向其他類型的轉(zhuǎn)換。請求地址: http://localhost:8080/quick11?username=zhangsan&age=12業(yè)務(wù)方法代碼:
@RequestMapping(value="/quick11")@ResponseBodypublic void save11(String username,int age) throws IOException {System.out.println(username);System.out.println(age);}其中,請求參數(shù)名和業(yè)務(wù)方法中形參名稱必須相同,Springmvc可以自動完成String到其他類型的自動轉(zhuǎn)換。
獲得POJO類型參數(shù)
要求:Controller中的業(yè)務(wù)方法形參POJO的屬性名與請求參數(shù)的name一致,參數(shù)值可以自動匹配賦值。并且能自動做類型轉(zhuǎn)換。自動的類型轉(zhuǎn)換是指從String向其他類型的轉(zhuǎn)換。
請求地址:
http://localhost:8080/quick12?username=zhangsan&age=12業(yè)務(wù)方法代碼:
@Datapublic class User {private String username;private int age;}@RequestMapping(value="/quick12")@ResponseBodypublic void save12(User user) throws IOException {System.out.println(user);}其中,請求參數(shù)名和業(yè)務(wù)方法中形參名稱必須相同,Springmvc可以自動完成String到其他類型的自動轉(zhuǎn)換。
獲取數(shù)組類型參數(shù)
Springmvc可以把請求參數(shù)中的多個同名參數(shù)的值組合成一個數(shù)組,直接賦值給業(yè)務(wù)方法形參中的同名數(shù)組字段。
要求:Controller中的業(yè)務(wù)方法數(shù)組名稱與請求參數(shù)的name一致,參數(shù)值可以自動匹配賦值。并且能自動做類型轉(zhuǎn)換。自動的類型轉(zhuǎn)換是指從String向其他類型的轉(zhuǎn)換。
請求地址:
http://localhost:8080/quick13?strs=aaa&strs=bbb&strs=ccc業(yè)務(wù)方法代碼:
@RequestMapping(value="/quick13")@ResponseBodypublic void save13(String[] strs) throws IOException {System.out.println(Arrays.asList(strs));}獲取集合類型參數(shù)
Springmvc可以把請求參數(shù)中的值賦值賦值給集合類型參數(shù),要將集合參數(shù)包裝到一個POJO中才可以。
<form action="${pageContext.request.contextPath}/user/quick14" method="post"><%--表明是第一個User對象的username age--%><input type="text" name="userList[0].username"><br/><input type="text" name="userList[0].age"><br/><input type="text" name="userList[1].username"><br/><input type="text" name="userList[1].age"><br/><input type="submit" value="提交"></form>@Datapublic class VO {private List<User> userList;}@RequestMapping(value="/quick14")@ResponseBodypublic void save14(VO vo) throws IOException {System.out.println(vo);}其中input標(biāo)簽的name值為save14方法對象的字段值。
更簡單的辦法就是在User類中添加一個屬性userList,在toString()方法中避免遞歸即可。
獲取集合類型參數(shù)-json
當(dāng)使用ajax提交時,可以指定contentType為application/json,那么在方法參數(shù)位置使用@RequestBody可以直接接收json格式的集合數(shù)據(jù),Springmvc可以自動封裝到形參List里面,而不需要使用POJO對象封裝List。此處沒有名字一致的要求。
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script><script>var userList = new Array();userList.push({username:"趙麗穎",age:18});userList.push({username:"迪麗熱巴",age:28});$.ajax({type:"POST",url:"${pageContext.request.contextPath}/user/quick15",data:JSON.stringify(userList),contentType:"application/json;charset=utf-8"});</script>@RequestMapping(value="/quick15")@ResponseBodypublic void save15(@RequestBody List<User> userList) throws IOException {System.out.println(userList);}出現(xiàn)無法訪問靜態(tài)資源的情況,可以使用SpringMVC的萬能模式解決。
<mvc:annotation-driven/><mvc:default-servlet-handler/>使用@RequestBody獲取請求體中的數(shù)組類型的json數(shù)據(jù),需要在前端配合ContentType=“application/json;charset=utf-8”使用。如果發(fā)送的Json數(shù)據(jù)是數(shù)組對象,需要在業(yè)務(wù)方法形參使用一個名字任意的JavaBean的list對象接收。
如果發(fā)送的json數(shù)據(jù)是單個對象,則不需要使用@RequestBody和設(shè)置ContentType:
結(jié)論:@RequestBody和ContentType配合使用成對出現(xiàn),用來處理集合數(shù)據(jù)的封裝。
靜態(tài)資源訪問的開啟
當(dāng)有靜態(tài)資源需要加載時,比如jquery文件,通過谷歌開發(fā)者工具抓包發(fā)現(xiàn),沒有加載到j(luò)query文件。
原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表對所有的非JSP資源都進(jìn)行攔截過濾匹配對應(yīng)的資源路徑和業(yè)務(wù)方法,但是靜態(tài)資源沒有與之匹配的資源路徑和業(yè)務(wù)方法。
可以通過以下兩種方式指定放行靜態(tài)資源:
- 在spring-mvc.xml配置文件中指定放行的資源
- 使用mvc:default-servlet-handler/標(biāo)簽
解決POST請求相應(yīng)亂碼
當(dāng)post請求時,數(shù)據(jù)會出現(xiàn)亂碼,我們可以設(shè)置一個過濾器來進(jìn)行編碼的過濾。
<!--配置全局過濾器,解決POST請求亂碼問題--><filter><filter-name>encodingFilter</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><!-- 是否強(qiáng)制使用上述編碼 --><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>上述配置可以解決配置可以解決整個項(xiàng)目的POST請求亂碼,項(xiàng)目的相應(yīng)亂碼可以在Springmvc配置文件中進(jìn)行如下配置:
<!-- 解決整個模塊相應(yīng)亂碼 --><mvc:annotation-driven><mvc:message-converters><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg value="utf-8"/></bean></mvc:message-converters></mvc:annotation-driven>上述兩個配置配合使用,可以解決整個項(xiàng)目的請求和相應(yīng)亂碼問題
解決響應(yīng)亂碼的另一種方式,不推薦使用。
@ResponseBody@RequestMapping(value = "/test5_1",consumes = "application/x-www-form-urlencoded;charset=utf-8")public String test5_1( User user){System.out.println(user);return "趙麗穎";}參數(shù)綁定注解@RequestParam
當(dāng)請求參數(shù)名稱與Controller的業(yè)務(wù)方法參數(shù)名稱不一致時,就需要通過@RequestParam注解顯示的綁定
<form action="${pageContext.request.contextPath}/quick16" method="post"><input type="text" name="name"><br><input type="submit" value="提交"><br></form> @RequestMapping(value="/quick16")@ResponseBodypublic void save16(@RequestParam(value="name",required = false) String username) throws IOException {System.out.println(username);}@RequestParam用于解決請求參數(shù)和業(yè)務(wù)方法形參名稱不一致的問題。其required屬性默認(rèn)為true,要求必須攜帶相應(yīng)的請求參數(shù),可以攜帶相應(yīng)的參數(shù)發(fā)送請求或者設(shè)置required = false
Restful風(fēng)格的參數(shù)的獲取
Restful是一種軟件架構(gòu)風(fēng)格、設(shè)計(jì)風(fēng)格,而不是標(biāo)準(zhǔn),只是提供了一組設(shè)計(jì)原則和約束條件。主要用于客戶端和服務(wù)器交互類的軟件,基于這個風(fēng)格設(shè)計(jì)的軟件可以更簡潔,更有層次,更易于實(shí)現(xiàn)緩存機(jī)制等。
Restful風(fēng)格的請求是使用“url+請求方式”表示一次請求目的的,HTTP 協(xié)議里面四個表示操作方式的動詞如下:
GET:用于獲取資源
POST:用于新建資源
PUT:用于更新資源
DELETE:用于刪除資源
例如:
/user/1 GET : 得到 id = 1 的 user
/user/1 DELETE: 刪除 id = 1 的 user
/user/1 PUT: 更新 id = 1 的 user
/user POST: 新增 user
上述url地址/user/1中的1就是要獲得的請求參數(shù),在SpringMVC中可以使用占位符進(jìn)行參數(shù)綁定。
地址/user/1可以寫成/user/{id},占位符{id}對應(yīng)的就是1的值。
在業(yè)務(wù)方法中我們可以使用@PathVariable注解進(jìn)行占位符的匹配獲取工作。
自定義類型轉(zhuǎn)換器
SpringMVC 默認(rèn)已經(jīng)提供了一些常用的類型轉(zhuǎn)換器,例如客戶端提交的字符串轉(zhuǎn)換成int型進(jìn)行參數(shù)設(shè)置。
但是不是所有的數(shù)據(jù)類型都提供了轉(zhuǎn)換器,沒有提供的就需要自定義轉(zhuǎn)換器,例如:特殊格式的日期類型的數(shù)據(jù)就需要自定義轉(zhuǎn)換器。
自定義轉(zhuǎn)換器步驟:
1. 編寫類實(shí)現(xiàn)Converter接口,接口泛型<源類型, 目標(biāo)類型>,實(shí)現(xiàn)convert方法接口全包名org.springframework.core.convert.converter.Converter 2. 在springmvc配置文件中裝配自定義類型轉(zhuǎn)換器(注入ConversionServiceFactoryBean的converters屬性)ConversionServiceFactoryBean的bean的id要注意,不要與系統(tǒng)重名 3. 在springmvc配置文件的<mvc:annotation-driven/>中引入上述轉(zhuǎn)換器編寫萬能Date轉(zhuǎn)換類
public class DataConverter implements Converter<String, Date> {@Overridepublic Date convert(String s) {//定義simpleDataFormat對象//配置自定義Date類型轉(zhuǎn)換器之后,系統(tǒng)內(nèi)置Date類型轉(zhuǎn)換器將失效,所以要把系統(tǒng)默認(rèn)格式一起處理了SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");//判斷格式 1999/01/01char c4 = s.charAt(4);char c7 = s.charAt(7);if ('-' == c4 && '-' == c7) {sdf = new SimpleDateFormat("yyyy-MM-dd");} else if ('.' == c4 && '.' == c7) {sdf = new SimpleDateFormat("yyyy.MM.dd");} else if ('年' == c4 && '月' == c7) {sdf = new SimpleDateFormat("yyyy年MM月dd日");}Date date = null;try {date = sdf.parse(s);} catch (ParseException e) {e.printStackTrace();}return date;}}在springmvc配置文件中配置
<!-- 引入自定義的類型轉(zhuǎn)換器所述的工廠Bean --><mvc:annotation-driven conversion-service="conversionService1"/><!-- 裝配springmvc的類型轉(zhuǎn)換工廠對象,將自定的DataConverter注入其屬性converters --><bean id="conversionService1" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><list><bean class="cs.wy.converter.DataConverter"/></list></property></bean>獲取Servlet相關(guān)API
SpringMVC支持使用原始ServletAPI對象作為控制器方法的參數(shù)進(jìn)行注入,常用的對象如下:
-
HttpServletRequest
-
HttpServletResponse
-
HttpSession
代碼如下:
@RequestMapping(value="/quick19")@ResponseBodypublic void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {System.out.println(request);System.out.println(response);System.out.println(session);}獲取請求頭信息
使用@RequestHeader可以獲得請求頭信息,相當(dāng)于request.getHeader(name)
@RequestHeader注解的屬性如下:
-
value:請求頭的名稱
-
required:是否必須攜帶此請求頭
使用@CookieValue可以獲得指定Cookie的值
@CookieValue注解的屬性如下:
-
value:指定cookie的名稱
-
required:是否必須攜帶此cookie
總結(jié)
以上是生活随笔為你收集整理的【SSM框架系列】SpringMVC的请求和响应的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【SSM框架系列】Spring-MVC的
- 下一篇: 【十大经典排序算法】java实现--选择