文章目錄
-
- 五、擷取參數資料處理以及頁面跳轉
-
- 請求轉發和請求重定向
-
- 5.1、ServletAPI方式跳轉
- 5.2、SpringMVC方式跳轉
-
- (1)通過SpringMVC來實作轉發和重定向 - 無需視圖解析器
- (2)通過SpringMVC來實作轉發和重定向 - 有視圖解析器;
- 資料處理
-
- 5.1、擷取前端送出的資料 和 處理送出資料
-
- 1、送出的域名稱和處理方法的參數名一緻
- 2、送出的域名稱和處理方法的參數名不一緻
- 3、送出的是一個對象
- 5.2、設定資料顯示在前端
-
- 第一種 : 通過ModelAndView(不常用)
- 第二種 : 通過ModelMap(不常用)
- 第三種 : 通過Model(常用)
- 三種方式對比
- 5.3、亂碼問題
五、擷取參數資料處理以及頁面跳轉
請求轉發和請求重定向
5.1、ServletAPI方式跳轉
通過設定ServletAPI , 不需要視圖解析器 ,如下
1、通過HttpServletResponse進行輸出
2、通過HttpServletResponse實作重定向
3、通過HttpServletResponse實作轉發
@Controller
public class ResultGo {
@RequestMapping("/result/t1")
public void test1(HttpServletRequest req, HttpServletResponse rsp) throwsIOException {
rsp.getWriter().println("Hello,Spring BY servlet API");
}
@RequestMapping("/result/t2")
public void test2(HttpServletRequest req, HttpServletResponse rsp) throwsIOException {
rsp.sendRedirect("/index.jsp");
}
@RequestMapping("/result/t3")
public void test3(HttpServletRequest req, HttpServletResponse rsp) throwsException {
//轉發
req.setAttribute("msg","/result/t3");
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
}
}
5.2、SpringMVC方式跳轉
(1)通過SpringMVC來實作轉發和重定向 - 無需視圖解析器
直接return為預設轉發到指定的路勁頁面下
@Controller
public class ResultSpringMVC {
//轉發1(預設的方式):直接return指定頁面的路徑
@RequestMapping("/rsm/t1")
public String test1(){
//轉發
return "/index.jsp";
}
//轉發2:使用字首forward:告訴處理器為轉發到指定的路徑頁面
@RequestMapping("/rsm/t2")
public String test2(){
//轉發二
return "forward:/index.jsp";
}
//重定向:同理,使用字首redirect:告訴處理器為重定向到指定的路徑頁面
@RequestMapping("/rsm/t3")
public String test3(){
//重定向
return "redirect:/index.jsp";
}
}
(2)通過SpringMVC來實作轉發和重定向 - 有視圖解析器;
重定向,不需要視圖解析器,因為重定向本質上就是一個新的請求,所有就不要視圖解析器了**,需要我們使用字首“redirect來指明為重定向”**,我們隻需要注解路徑問題
轉發:return “視圖名” ;預設就是轉發到 {視圖解析器字首}+視圖名+{視圖解析器字尾}
@Controller
public class ResultSpringMVC2 {
@RequestMapping("/rsm2/t1")
public String test1(){
//轉發
return "test";
}
@RequestMapping("/rsm2/t2")
public String test2(){
//重定向
return "redirect:/index.jsp";
//return "redirect:hello.do"; //hello.do為另一個請求/
}
}
資料處理
5.1、擷取前端送出的資料 和 處理送出資料
1、送出的域名稱和處理方法的參數名一緻
送出資料 : http://localhost:8080/hello?name=kunkun 處理方法 :springMVC自動擷取參數名為name的參數值,并指派給處理方法的同名參數
@RequestMapping("/hello")
public String hello(String name){//自動擷取參數名為name的參數值,并指派給處理方法的同名參數
System.out.println(name);
return "hello";
}
2、送出的域名稱和處理方法的參數名不一緻
送出資料 : http://localhost:8080/hello?username=kunkun
處理方法 :使用注解@RequestParam(“指定請求參數名”)修飾處理方法的參數,表示擷取指定名字參數指派給他所有修飾的方法
//@RequestParam("username") : username送出的域的名稱 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){//表示擷取參數名為username的參數值指派給name,
System.out.println(name);
return "hello";
}
推薦使用第二種方式,無論是否請求參數名和處理方法參數名是否一樣,我們都是用此注解修飾處理方法參數,因為可以簡單明了知道是從前端擷取參數,擷取了那個參數值,防止亂套
3、送出的是一個對象
要求送出的表單域和對象的屬性名一緻 , 參數使用對象即可,但是有一個要求就是我們需要保持參數名和對象屬性名稱一樣,SpringMVC自動為我們重前端請求位址擷取參數值,按照參數的name屬性為我們對象相同屬性名注入(說白了就是使用set注入)
(1)實體類
public class User {
private int id;
private String name;
private int age;
}
(2)送出資料:http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15
(3)處理方法:
/**
* 從前端接受的是一個對象:id,name,age
* 1、接受前端使用者傳遞的參數,判斷參數的名字,假設名字直接在方法上,可以直接使用
* 2、假設傳遞的一個對象User,比對User對象中的字段名:如果參數名和屬性性名一緻,則ok,否則比對不到
* 3、自動的為我們封裝對象,按照屬性名和參數名進行設定
*/
@GetMapping("/t2")
public String test2(User user) {
System.out.println(user);
return "test";
}
5.2、設定資料顯示在前端
第一種 : 通過ModelAndView(不常用)
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws Exception {
//傳回一個模型視圖對象
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
第二種 : 通過ModelMap(不常用)
ModelMap
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
//封裝要顯示到視圖中的資料
//相當于req.setAttribute("name",name);
model.addAttribute("name",name);
System.out.println(name);
return "hello";
}
第三種 : 通過Model(常用)
Model
@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
//封裝要顯示到視圖中的資料
//相當于req.setAttribute("name",name);
model.addAttribute("msg",name);
System.out.println(name);
return "test";
}
三種方式對比
- Model隻有幾個方法适用與存儲資料
- ModelMap繼承與LinkedMap,除了自身的一些方法外,同樣的繼承了LinkedMap的方法和特性
- ModelAndView 即可以存儲資料,又可以設定傳回視圖層,控制視圖跳轉邏輯
- 一般情況下我們都是使用Model
5.3、亂碼問題
當我們送出表單到伺服器端,擷取的參數值亂碼,我們采用過濾器了解決亂碼問題,SpringMVC給我們提供了一個過濾器,我們可以直接在web.xml中配置這個過濾器,一般情況下是不會發生亂碼
<!--配置SpringMVC的亂碼過濾器-->
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
但是我們發現,在一些情況下,這個過濾器,對get請求支援不是很好:處理方法
1、修改Tomacat的配置檔案:設定編碼!
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
2、自定義一個過濾器(網上大神寫好的)
package com.atdk.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
/**
* 解決get和post請求 全部亂碼的過濾器
*/
public class GenericEncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//處理response的字元編碼
HttpServletResponse myResponse = (HttpServletResponse) response;
myResponse.setContentType("text/html;charset=UTF-8");
// 轉型為與協定相關對象
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 對request包裝增強
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
//自定義request對象,HttpServletRequest的包裝類
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
//是否編碼的标記
private boolean hasEncode;
//定義一個可以傳入HttpServletRequest對象的構造函數,以便對其進行裝飾
public MyRequest(HttpServletRequest request) {
super(request);// super必須寫
this.request = request;
}
// 對需要增強方法 進行覆寫
@Override
public Map getParameterMap() {
// 先獲得請求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
// post請求
try {
// 處理post亂碼
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
// get請求
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) { // 確定get手動編碼邏輯隻運作一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
// 處理get亂碼
values[i] = new String(values[i]
.getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
//取一個值
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回參數的第一個值
}
//取所有值
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
3.在web.xml中配置此過濾器即可
以上是本人學習狂勝說所做筆記,參考了狂神的部落格,謝謝狂神。