javascript
【SSM框架系列】SpringMVC的请求和响应
request和response
request對象的作用
response功能
Springmvc僅僅是對上述兩個對象進行了封裝,所以Springmvc的請求和響應與上面一致。
springmvc響應數據
頁面跳轉
1)直接返回字符串
返回的是要跳轉的資源路徑名,資源路徑名可以是html、jsp或者是Controller中其他的方法虛擬資源路徑。默認是請求轉發,如果想要重定向,要寫:redirect:資源路徑名(不需要帶項目名)。
2)返回通過ModelAndView對象
在Controller中方法使用ModelAndView對象并且設置視圖名稱,并將該對象返回,
這個ModelAndView對象可以是在方法內部new出來的,如下:
也可以在Controller中方法形參上直接聲明一個ModelAndView對象。
這種方式無需自己在方法中創建,框架會幫我們將ModelAndView對象注入,直接使用設置視圖名稱即可。
@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注意事項:
這種方式只能通過返回ModelAndView對象實現頁面跳轉,除此之外的其他方式返回字符串(資源路徑名稱)即可實現頁面跳轉。
如果使用ModelAndView封裝數據,必須通過返回該ModelAndView對象實現頁面跳轉,否則在跳轉后的頁面會拿不到數據。
回寫數據
直接回寫字符串
原始方式:相當于response.getWriter().print(“hello”),將一個字符串直接寫入到前端頁面,原頁面內容會被覆蓋。這種用法建議不用。
Springmvc方式:將需要回寫的字符串直接返回,需要通過@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳轉是直接在http響應體中返回,業務方法返回值也是void
ResponseBody用法:
- 如果不寫該注解,方法的String返回值會被當做一個要跳轉的資源名稱
- 在方法上添加@ResponseBody注解后,則會將String類型的返回值響應到頁面
- 如果是同步請求,會直接在頁面上顯示,但是會覆蓋掉原來頁面的內容
- 如果是異步請求,會返回到異步請求的回調函數中
返回對象或集合
方式1
為處理器適配器(RequestMappingHandlerAdapter)配置消息轉換器(MappingJackson2HttpMessageConverter),指定使用jackson進行對象或集合的轉換。
在spring-mvc.xml中進行如下配置:
<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>然后在業務方法中直接返回需要轉換的對象或集合即可。此時仍需要@ResponseBody注解,因為在回寫數據。
@RequestMapping(value="/quick10")@ResponseBody//期望SpringMVC自動將User轉換成json格式的字符串public User save10() throws IOException {User user = new User();user.setUsername("趙麗穎");user.setAge(18);return user;}方式二
可以使用mvc的注解驅動代替上述配置復雜配置
<!-- 萬能標簽,Springmvc首配 --><mvc:annotation-driven/>這是一個神奇的標簽,能幫代替我們完成很多工作,所以使用Springmvc開發,第一步先在配置文件中配置該標簽。原理如下:
-
處理器映射器、處理器適配器、視圖解析器稱為 SpringMVC 的三大組件。
-
使用<mvc:annotation-driven />將自動加載 RequestMappingHandlerMapping(處理映射器)和RequestMappingHandlerAdapter( 處 理 適 配 器 )。
-
所以可以在Springmvc配置文件中使用<mvc:annotation-driven />替代處理映射器和處理適配器的配置。
-
同時使用<mvc:annotation-driven />默認底層就會集成jackson進行對象或集合的json格式字符串的轉換。
Springmvc把對象通過json形式回寫的步驟就變成了如下簡單幾步:
說明:
- 如果視圖層使用JSP技術,Controller一般返回ModelAndView
- 如果視圖層使用HTML技術,Controller一般返回JSON字符串,可以在HTML發送異步請求,后臺響應JSON字符串到Ajax的回調函數中,返回JSON字符串,可以返回對象或集合,讓SpringMVC框架轉換為JSON字符串
- 需要配置兩個地方
- 方法上@ResponseBody
- 配置文件 <mvc:annotation-driven />
SpringMVC獲取請求數據
Springmvc獲取的請求參數類型
客戶端請求參數的格式是:name=value&name=value……
服務器端要獲得請求的參數,有時還需要進行數據的封裝,SpringMVC可以接收如下類型的參數
Springmvc可以把請求參數中的參數值直接賦值給業務方法的形參。
要求:Controller中的業務方法的參數名稱要與請求參數的name一致,參數值會自匹配賦值。并且能自動做類型轉換。
自動的類型轉換是指從String向其他類型的轉換。請求地址: http://localhost:8080/quick11?username=zhangsan&age=12業務方法代碼:
@RequestMapping(value="/quick11")@ResponseBodypublic void save11(String username,int age) throws IOException {System.out.println(username);System.out.println(age);}其中,請求參數名和業務方法中形參名稱必須相同,Springmvc可以自動完成String到其他類型的自動轉換。
獲得POJO類型參數
要求:Controller中的業務方法形參POJO的屬性名與請求參數的name一致,參數值可以自動匹配賦值。并且能自動做類型轉換。自動的類型轉換是指從String向其他類型的轉換。
請求地址:
http://localhost:8080/quick12?username=zhangsan&age=12業務方法代碼:
@Datapublic class User {private String username;private int age;}@RequestMapping(value="/quick12")@ResponseBodypublic void save12(User user) throws IOException {System.out.println(user);}其中,請求參數名和業務方法中形參名稱必須相同,Springmvc可以自動完成String到其他類型的自動轉換。
獲取數組類型參數
Springmvc可以把請求參數中的多個同名參數的值組合成一個數組,直接賦值給業務方法形參中的同名數組字段。
要求:Controller中的業務方法數組名稱與請求參數的name一致,參數值可以自動匹配賦值。并且能自動做類型轉換。自動的類型轉換是指從String向其他類型的轉換。
請求地址:
http://localhost:8080/quick13?strs=aaa&strs=bbb&strs=ccc業務方法代碼:
@RequestMapping(value="/quick13")@ResponseBodypublic void save13(String[] strs) throws IOException {System.out.println(Arrays.asList(strs));}獲取集合類型參數
Springmvc可以把請求參數中的值賦值賦值給集合類型參數,要將集合參數包裝到一個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標簽的name值為save14方法對象的字段值。
更簡單的辦法就是在User類中添加一個屬性userList,在toString()方法中避免遞歸即可。
獲取集合類型參數-json
當使用ajax提交時,可以指定contentType為application/json,那么在方法參數位置使用@RequestBody可以直接接收json格式的集合數據,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);}出現無法訪問靜態資源的情況,可以使用SpringMVC的萬能模式解決。
<mvc:annotation-driven/><mvc:default-servlet-handler/>使用@RequestBody獲取請求體中的數組類型的json數據,需要在前端配合ContentType=“application/json;charset=utf-8”使用。如果發送的Json數據是數組對象,需要在業務方法形參使用一個名字任意的JavaBean的list對象接收。
如果發送的json數據是單個對象,則不需要使用@RequestBody和設置ContentType:
結論:@RequestBody和ContentType配合使用成對出現,用來處理集合數據的封裝。
靜態資源訪問的開啟
當有靜態資源需要加載時,比如jquery文件,通過谷歌開發者工具抓包發現,沒有加載到jquery文件。
原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表對所有的非JSP資源都進行攔截過濾匹配對應的資源路徑和業務方法,但是靜態資源沒有與之匹配的資源路徑和業務方法。
可以通過以下兩種方式指定放行靜態資源:
- 在spring-mvc.xml配置文件中指定放行的資源
- 使用mvc:default-servlet-handler/標簽
解決POST請求相應亂碼
當post請求時,數據會出現亂碼,我們可以設置一個過濾器來進行編碼的過濾。
<!--配置全局過濾器,解決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><!-- 是否強制使用上述編碼 --><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>上述配置可以解決配置可以解決整個項目的POST請求亂碼,項目的相應亂碼可以在Springmvc配置文件中進行如下配置:
<!-- 解決整個模塊相應亂碼 --><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>上述兩個配置配合使用,可以解決整個項目的請求和相應亂碼問題
解決響應亂碼的另一種方式,不推薦使用。
@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 "趙麗穎";}參數綁定注解@RequestParam
當請求參數名稱與Controller的業務方法參數名稱不一致時,就需要通過@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用于解決請求參數和業務方法形參名稱不一致的問題。其required屬性默認為true,要求必須攜帶相應的請求參數,可以攜帶相應的參數發送請求或者設置required = false
Restful風格的參數的獲取
Restful是一種軟件架構風格、設計風格,而不是標準,只是提供了一組設計原則和約束條件。主要用于客戶端和服務器交互類的軟件,基于這個風格設計的軟件可以更簡潔,更有層次,更易于實現緩存機制等。
Restful風格的請求是使用“url+請求方式”表示一次請求目的的,HTTP 協議里面四個表示操作方式的動詞如下:
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就是要獲得的請求參數,在SpringMVC中可以使用占位符進行參數綁定。
地址/user/1可以寫成/user/{id},占位符{id}對應的就是1的值。
在業務方法中我們可以使用@PathVariable注解進行占位符的匹配獲取工作。
自定義類型轉換器
SpringMVC 默認已經提供了一些常用的類型轉換器,例如客戶端提交的字符串轉換成int型進行參數設置。
但是不是所有的數據類型都提供了轉換器,沒有提供的就需要自定義轉換器,例如:特殊格式的日期類型的數據就需要自定義轉換器。
自定義轉換器步驟:
1. 編寫類實現Converter接口,接口泛型<源類型, 目標類型>,實現convert方法接口全包名org.springframework.core.convert.converter.Converter 2. 在springmvc配置文件中裝配自定義類型轉換器(注入ConversionServiceFactoryBean的converters屬性)ConversionServiceFactoryBean的bean的id要注意,不要與系統重名 3. 在springmvc配置文件的<mvc:annotation-driven/>中引入上述轉換器編寫萬能Date轉換類
public class DataConverter implements Converter<String, Date> {@Overridepublic Date convert(String s) {//定義simpleDataFormat對象//配置自定義Date類型轉換器之后,系統內置Date類型轉換器將失效,所以要把系統默認格式一起處理了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配置文件中配置
<!-- 引入自定義的類型轉換器所述的工廠Bean --><mvc:annotation-driven conversion-service="conversionService1"/><!-- 裝配springmvc的類型轉換工廠對象,將自定的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相關API
SpringMVC支持使用原始ServletAPI對象作為控制器方法的參數進行注入,常用的對象如下:
-
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可以獲得請求頭信息,相當于request.getHeader(name)
@RequestHeader注解的屬性如下:
-
value:請求頭的名稱
-
required:是否必須攜帶此請求頭
使用@CookieValue可以獲得指定Cookie的值
@CookieValue注解的屬性如下:
-
value:指定cookie的名稱
-
required:是否必須攜帶此cookie
總結
以上是生活随笔為你收集整理的【SSM框架系列】SpringMVC的请求和响应的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【SSM框架系列】Spring-MVC的
- 下一篇: gradle idea java ssm