天天看点

springmvc中使用forward和redirect

本文转载自“独钓渔”的博客

(一) java web编程中的forward和redirect

在java web编程中跳转有两种:” 1:forward ,2:redirect。

我的理解是:forward是请求转发,redirect是重定向。

forward(请求转发):

可以看出是统一次请求,当request到达这个servlet后又看到又forward又将当前的request继续转发到forward的地址去,在这个过程中,可以利用request.setAttribute设置一些转发的属性,都会被带到目标servlet中去,目标servlet可以通过request.getparam来获取原始的request请求,也可通过request.getAttribute来获取转发过程中的设置的属性。

redirect(重定向):

redirect重定向,基本可以理解为响应了301,302等之类的,你重新安装redirect新地址去重新请求。所有一般来说redirect不能带model信息,无法像forward利用request.setAttribute来设置一些转发属性,如果重定向到外部应用只有通过GET提交方式传递数据,如果是重定向到应用自己内部的其它地址,则还可以利用session实现数据传递。

自己总结:

可以理解为forward过程发生在request过程中,redirect发生在response过程中。从浏览器来看,forward是一次请求,转发过程在Servlet容器中完成,所有目标Servlet返回信息就会在当前的请求response中,浏览器地址不变;而redirect是重定向,这次请求的servlet响应,响应的response内容为一个redirect, 浏览器收到这个redirect后重新发起一个新的request请求到redirect这个目标地址,在由这个目标地址的Servlet来响应返回的内容。也正是应为如此,forward(请求转发)只能用在同一个应用中。而redirect可以重定向到其他外部应用中去。

在redirect过程中是一次完全重新的GET请求,如果要在redircet中带数据转发只有这一种方式(利用GET请求时把参数带上)。

eg1  redirect:/path/list?prama1=values1&prama2=values2

eg2  redirect:http://api.xxx.com/path/list?prama1=values1&prama2=values2           

如果redirect是以/开始这会认为是同一应用中(如eg1),那么他们直接的数据传递还可以利用session实现。

(二) 说说springmvc中的forward和redirect

springmvc完成forward和redirect时本质也是一样。

Spring MVC 中,我们在返回逻辑视图时,框架会通过 viewResolver 来解析得到具体的 View,然后向浏览器渲染。假设逻辑视图名为 hello,通过配置,我们配置某个 ViewResolver 如下:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
    <description>  
        假如逻辑试图名为 "hello",因此 viewResolver 将解析成 /WEB-INF/jsp/hello.jsp  
    </description>  
    <property name="prefix" value="/WEB-INF/jsp/" />  
    <property name="suffix" value=".jsp" />  
</bean>             

实际上,框架还是通过 forward 的方式转发到了 /WEB-INF/jsp/hello.jsp。如果逻辑视图名是 /hello,实际还是转发到了 /WEB-INF/jsp/hello.jsp,即 /WEB-INF/jsp//hello.jsp 等同于 /WEB-INF/jsp/hello.jsp。

现在有个问题,如果 /hello 就是某个 controller 的映射,我想转发到这个 controller,怎么办?我们可以通过forward 前缀来达到转发到其它资源的目的:

public String handle() {  
    // return "forward:/hello" => 转发到能够匹配 /hello 的 controller 上  
    // return "hello" => 实际上还是转发,只不过是框架会找到该逻辑视图名对应的 View 并渲染  
    // return "/hello" => 同 return "hello"  
    return "forward:/hello";  
}             

同理,如果我们想重定向到某个资源,我们可以通过 redirect 前缀来达到重定向到其它资源的目的:

public String handle() {  
    // 重定向到 /hello 资源  
    return "redirect:/hello";  
}             

forward(请求转发)因为有request.setAttribute方法所以请求转发过程中增加一些请求属性都是非常容易的事情。

redirect(重定向)要想在重定向过程中传递数据相对麻烦得多。

1,redirect到外部应用时,只有通过get提交方式传递数据(如eg2)。

2,redircet到应用自己的其它地址时,可以通过get提交方式传递数据(如eg1),还可通过session方式传递数据。

Spring MVC中有RedirectAttributes类专门用于重定向之后还能带参数跳转的的工具类。

他有两种带参的方式:

第一种:

redirectAttributes.addAttributie(“prama”,value); 这种方法相当于在重定向链接地址追加传递的参数,例如:

redirectAttributes.addAttributie("prama1",value1);
redirectAttributes.addAttributie("prama2",value2);
return:"redirect:/path/list"            

以上重定向的方法等同于 return:”redirect:/path/list?prama1=value1&prama2=value2”

第二种:

redirectAttributes.addFlashAttributie(“prama”,value); 这种方法是隐藏了参数,链接地址上不直接暴露,但是能且只能在重定向的 “页面” 获取prama参数值。其原理就是放到session中,session在跳到页面后马上移除对象。如果是重定向一个controller中是获取不到该prama属性值的。除非在controller中用(@RequestPrama(value = “prama”)String prama)注解,采用传参的方式。页面获值例如:

redirectAttributes.addFlashAttributie("prama1",value1);
redirectAttributes.addFlashAttributie("prama2",value2);
return:"redirect:/path/list.jsp"
在以上参数均可在list.jsp页面使用EL表达式获取到参数值${prama*}
controller获得redirectAttributes重定向的值例如:

redirectAttributes.addFlashAttributie("prama1",value1);
redirectAttributes.addFlashAttributie("prama2",value2);
return:"redirect:/path/list"

@RequestMapping("list")
public List<Student> list(@RequestPrama(value = "prama1")String  prama1,
   @RequestPrama(value = "prama2")String  prama2,...
){
    //TODO
}           

这可以在controller中获取redirect传过来的值。