天天看點

04-SpringMVC擷取參數處理參數以及頁面跳轉問題

文章目錄

    • 五、擷取參數資料處理以及頁面跳轉
      • 請求轉發和請求重定向
        • 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中配置此過濾器即可

以上是本人學習狂勝說所做筆記,參考了狂神的部落格,謝謝狂神。