spring mvc重定向方法


一.不帶參數,直接重定向到另一個地址:

返回String直接跳轉,如:

@RequestMapping(value = "/filehandle")
    public String upload(){

return "redirect:/upload.jsp";

}

 

或者使用使用ModelAndView跳轉

@RequestMapping(value = "/filehandle")
    public ModelAndView upload(){ 

return new ModelAndView("redirect:/toList");

}

 

二.帶參數重定向

1.手動拼接url

@RequestMapping(value = "/filehandle")
    public String upload(){

return "redirect:/test.jsp?a=2&b=fdf&c=flase&d=123";

}

jsp上用以下兩種方式接收

${param.a}
<%=request.getParameter("a") %>

缺點:

  a.參數都會被當成String,強制轉換類型會報錯

  b.因為用get方式,中文中可能會亂碼

2.用RedirectAttributes.addAttribute 傳參

@RequestMapping(value = "/test")
    public String upload(RedirectAttributes attr,Model model){

        attr.addAttribute("a",2);
        attr.addAttribute("b","鎮耿");
        attr.addAttribute("c",false);

        return "redirect:/test.jsp";
    }

不能用Model.addAttribute,因為jsp接不到

jsp接收的方式跟上一個一樣

實際上,這個方法實質上跟方法1是一樣的,只是這個方法會自動拼接url,跳轉之后的地址是一樣的,所以缺點也跟方法1一樣.

3.用RedirectAttributes.addFlashAttribute 傳參(這個是重點,重定向action的地址帶自定義類型的參數的話用這個,直接重定向jsp的話用下一個)

 RedirectAttributes.addFlashAttribute 是 Spring MVC 3.1之后才有的,並且要在 spring-servlet.xml 文件中加入 mvc:annotation-driven。

<mvc:annotation-driven />

  java:

    @RequestMapping(value = "/test")
    public String upload(RedirectAttributes attr){
        TestBean b=new TestBean();
        b.setA("3");
        b.setB("峰峰ff");
        attr.addFlashAttribute("t",b);

        return "redirect:/test2";
    }
    @RequestMapping(value = "/test2")
    public String upload2(){
        return "test";
    }

如果"/test2"里面需要對addFlashAttribute里的值處理可以在"/test2"里用以下幾種方法接

第一種

    @RequestMapping(value ="/test2")
    public String upload2(@ModelAttribute("t") TestBean c) {
        System.out.println(c.getA());
        System.out.println(c.getB());
        c.setB("fFdf發的");
     return "test"; }

可以不用保存,直接更改,jsp接到的是改后的值

第二種在"/test2"處理flashattribute的值:

//        model.asMap().put("t", d);
        System.out.println("t:"+model.asMap().get("t"));
        TestBean t=    (TestBean) model.asMap().get("t");
        t.setB("dsd發扥扥分");

這兩種方法處理過的值在刷新的時候不會消失,而從"test"接過來的值會消失(如上面,t.b的值在刷新的時候不會消失,而t.a會)

第三種:

    System.out.println("Fetch Flash Attributes By using RequestContextUtils");
        Map<String, ?> flashMap = RequestContextUtils.getInputFlashMap(request);
        if (flashMap != null) {
            TestBean t=(TestBean)flashMap.get("t");
            System.out.println("t.b:"+t.getB());
            t.setB("發扥周");
            
        }

這種方法修改過的值在第二次刷新的值會消失

jsp用以下方式接

${t.b }
<%=request.getAttribute("t") %>

addFlashAttribute 默認存放在session里,重定向后取值就會立馬刪除,所以不會占用session很多空間,但仍然有其他問題.

注意:RedirectAttributes.addAttribute和RedirectAttributes.addFlashAttribute最好不要一起用,尤其是兩者添加到key和bean里屬性的名字不要重復,會導致 FlashAttribute里面的值錯亂

 

這方法不能直接重定向到jsp,直接到jsp的話在jsp取不到值,需要重定向到映射上 

原因:

addFlashAttribute方法默認存在session里面,名字是"org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS",

 

  直接跳到jsp的話,存進的變量t的位置不會變,還在session里面的"org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS"里面,值是"[FlashMap [attributes={t=com.cib.xj.poi.TestBean@5f615e1c}, targetRequestPath=/xj.query/test.jsp, targetRequestParams={}]]",

jsp直接用${t.a}是取不到t的,因為t是springmvc封裝的那個變量里面,session里根本沒有"t"這個變量名.可以在jsp用下面的方法取到變量t(類型java.util.concurrent.CopyOnWriteArrayList好像需要在jsp引入,不然會無法編譯jsp)

<%
CopyOnWriteArrayList   m=(CopyOnWriteArrayList  )session.getAttribute("org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS");
if(m!=null){
for(int i=0;i<m.size();i++){
    FlashMap fm =(FlashMap )m.get(i);
    TestBean t=(TestBean)fm.get("t");
    out.print("java:t:a:"+t.getA()+"<br/>");
    out.print("java:t:b:"+t.getB()+"<br/>");
    
}
}
%>

但addFlashAttribute直接重定向jsp的話,即使在jsp用上面的方法取到變量,session里那個變量也不會自動刪除.每運行一次就會往session那個變量增加一個值,前面的仍然保留着,需要自己手動刪除,不然session會越占越大.既然需要自己手動刪除,還不如自己用自定義的變量名直接放進session,在jsp取完值后刪掉,這樣取值更好取(即下面的方法4).

 

  而跳轉到另一個映射上的話(此映射是get方式請求的,因為重定向redirect是用get方式請求的),第二個映射接收的時候會把flashAttribute里面的變量放到Model里面並把session里的那個變量刪除(從上面 "第二種在"/test2"處理flashattribute的值:" 的例子可以看出變量t存進了Model),然后第二個映射正常以"forward"方式返回到jsp的時候,在Model里面的變量t就自然存到了jsp的request范圍內,即jsp的request里面存在變量"t",此時用${t.a}自然可以取到值.相對應,直接跳jsp的話不管是request還是session里面都不存在名字叫"t"的變量,所以直接跳jsp的話用${t.a}是取不到值的.

 

找到原因的方法:

我在jsp上面直接把request和session里面的所有變量都遍歷打印出來了,才發現了flashAttribute存進去的變量是叫"org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS",而不是直接用存進flashAttribute的變量的名字.在嘗試取那個變量的值的時候先用Map取,但報了"java.util.concurrent.CopyOnWriteArrayList"不能轉換到"java.util.Map"的異常,然后發現這個類是ArrayList,就按照正常的List遍歷出它所有的值了.

 

 

4.值放session里,跳轉后從session取值再將值刪除.(如果是要直接重定向jsp還要帶自定義類型的參數的話,要用這個)

@RequestMapping(value = "/test")
    public String upload(HttpSession session){
        TestBean b=new TestBean();
        b.setA("3");
        b.setB("峰峰ff");
        session.setAttribute("u",b );
        return "redirect:/test.jsp";
//        return "redirect:/test2";
    }

jsp接(最好取完就刪了,畢竟取完就沒用了,免得session越占越大)

session.u=<%=session.getAttribute("u") %><br/>
sessionScope.u.a=${sessionScope.u.a}<br/>
u.a=${u.a }<br/>
<% session.removeAttribute("u"); %>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM