SpringMVC使⽤ModelAndView进⾏重定向
1、Servlet重定向forward与redirect:
使⽤servlet重定向有两种⽅式,⼀种是forward,另⼀种就是redirect。forward是服务器内部重定向,客户端并不知道服务器把你当前请求重定向到哪⾥去了,地址栏的url与你之
前访问的url保持不变。redirect则是客户端重定向,是服务器将你当前请求返回,然后给个状态标⽰给你,告诉你应该去重新请求另外⼀个url,具体表现就是地址栏的url变成了
新的url。
2、ModelAndView重定向:
使⽤Spring MVC通常是使⽤ModelAndView⽤来返回视图。ModelAndView其实也是⽀持Servlet中的两种重定向⽅式。⽐如404页⾯我们⼀般采⽤redirect重定向⽅式,像下⾯的
代码就是redirect重定向:
public ModelAndView getPage404MV() {
ModelAndView mv = new ModelAndView("redirect:/404.htm");
return mv;
}
要使⽤forward重定向就只需把redirect换成forward即可,特别的ModelAndView默认使⽤forward重定向⽅式。
1. 需求背景
需求:spring MVC框架controller间跳转,需重定向。有⼏种情况:不带参数跳转,带参数拼接url形式跳转,带参数不拼接参数跳转,页⾯也能显⽰。
本来以为挺简单的⼀件事情,并且个⼈认为⽐较常⽤的⼀种⽅式,⼀百度全都有了,这些根本不是问题,但是⼀百度居然出乎我的意料,⼀堆都不是我想要的结果。⽆奈啊,⾃
⼰写⼀篇⽐较全都供以后⼤家⼀百度吧,哈哈哈。。。是这些写的不是很全都⼈们给了我写这篇博客的动⼒。
2. 解决办法
需求有了肯定是解决办法了,⼀⼀解决,说明下spring的跳转⽅式很多很多,我这⾥只是说⼀些⾃我认为好⽤的,常⽤的,spring分装的⼀些类和⽅法。
(1)我在后台⼀个controller跳转到另⼀个controller,为什么有这种需求呢,是这样的。我有⼀个列表页⾯,然后我会进⾏新增操作,新增在后台完成之后我要跳转到列表页⾯,不需要传递参数,列表页⾯默认查询所有的。⽅式⼀:使⽤ModelAndView
return new ModelAndView("redirect:/toList");
这样可以重定向到toList这个⽅法
⽅式⼆:返回String
return "redirect:/ toList ";
其它⽅式:其它⽅式还有很多,这⾥不再做介绍了,⽐如说response等等。这是不带参数的重定向。
(2)第⼆种情况,列表页⾯有查询条件,跳转后我的查询条件不能丢掉,这样就需要带参数的了,带参数可以拼接url
⽅式⼀:⾃⼰⼿动拼接url
new ModelAndView("redirect:/toList?param1="+value1+"¶m2="+value2);
这样有个弊端,就是传中⽂可能会有乱码问题。
⽅式⼆:⽤RedirectAttributes,这个是发现的⼀个⽐较好⽤的⼀个类
这⾥⽤它的addAttribute⽅法,这个实际上重定向过去以后你看url,是它⾃动给你拼了你的url。
使⽤⽅法:
attr.addAttribute("param", value);
return "redirect:/namespace/toController";
这样在toController这个⽅法中就可以通过获得参数的⽅式获得这个参数,再传递到页⾯。过去的url还是和⽅式⼀⼀样的。
(3)带参数不拼接url页⾯也能拿到值(重点是这个)
⼀般我估计重定向到都想⽤这种⽅式:
@RequestMapping("/save")
public String save(@ModelAttribute("form") Bean form,RedirectAttributes attr)
throws Exception {
String code = service.save(form);
if(code.equals("000")){
attr.addFlashAttribute("name", Name());
attr.addFlashAttribute("success", "添加成功!");
return "redirect:/index";
}else{
mvc的controllerattr.addAttribute("projectName", ProjectName());
attr.addAttribute("enviroment", Enviroment());
attr.addFlashAttribute("msg", "添加出错!错误码为:"+Code().getCode()+",错误为:"+Code().getName());
return "redirect:/maintenance/toAddConfigCenter";
}
}
@RequestMapping(“/index”)
public String save(@ModelAttribute("form") Bean form,RedirectAttributes attr)
throws Exception {
return "redirect:/main/list";
}
页⾯取值不⽤我说了吧,直接⽤el表达式就能获得到,这⾥的原理是放到session中,session在跳到页⾯后马上移除对象。所以你刷新⼀下后这个值就会丢掉。
3. 总结
最底层还是两种跳转,只是spring⼜进⾏了封装⽽已,所以说跳转的⽅式其实有很多很多种,你⾃⼰也可以封⼀个,也可以⽤最原始的response来,也没有问题。好了,就到这
⼉。
其实也没有什么,但是知道了这个就很简单了,之前没搞懂,现在搞懂了,和⼤家分享。有问题的给我留⾔。
记得在spring mvc2中,当保存POJO到数据库后,要返回成功页⾯,如果这个时候要带点信息,
则要这样:
Java代码:
//第三个参数(UserModel user)默认为绑定对象
@RequestMapping(value = "/user/save", method = RequestMethod.POST)
public ModelAndView saveUser(HttpServletRequest request, HttpServletResponse response,UserModel user) throws Exception {
ModelAndView mv = new ModelAndView("/user/save/result");//默认为forward模式
// ModelAndView mv = new ModelAndView("redirect:/user/save/result");//redirect模式
mv.addObject("message","保存⽤户成功!");
return mv;
}
⽽在spring mvc 3.1后,可以这样
Java代码:
@RequestMapping(value = "/user/save", method = RequestMethod.POST)
public ModelAndView saveUser(UserModel user, RedirectAttributes redirectAttributes) throws Exception {
redirectAttributes.addFlashAttribute("message", "保存⽤户成功!");//使⽤addFlashAttribute,参数不会出现在url地址栏中
return "redirect:/user/save/result";
}
来个稍微完整点的例⼦,⾸先是⼀个表单,在其中填⼊⼀些信息:
Java代码:
<form:form id="myform" action="saveUserDetails.action" method="POST" commandName="user">
<form:input type="text" name="firstName" path="firstName"/>
<form:input type="text" name="lastName" path="lastName"/>
<form:input type="text" name="email" path="email"/>
<input type="submit" value="submit">
</form:form>
则在controller中,可以这样:
Java代码:
@RequestMapping(value="/saveUserDetails.action", method=RequestMethod.POST)
public String greetingsAction(@Validated User user,RedirectAttributesredirectAttributes){
someUserdetailsService.save(user);
redirectAttributes.addFlashAttribute("firstName", FirstName());
redirectAttributes.addFlashAttribute("lastName", LastName())
return "redirect:success.html";
}
success.html:
<div>
<h1>Hello ${firstName} ${lastName}. Your details stored in our database.</h1>
</div><br>
但如果F5的时候,会发现参数丢失,因为flash scope其实只⽀持redirect的,所以可以判断下:
Java代码:
@RequestMapping(value="/success.html", method=RequestMethod.GET)
public String successView(HttpServletRequest request){
Map<String,?> map = InputFlashMap(request);
if (map!=null)
return "success";
else return "redirect:someOtherView"; //給出其他提⽰信息
spring mvc 如何请求转发和重定向呢?
往下看:
由于这部分内容简单,⼀带⽽过了。
1.请求转发:
(1)返回ModelAndView :
@RequestMapping(value=”/model”,method=RequestMethod.GET)
public ModelAndView testForward(ModelAndView model,@RequestParam(value=”id”,defaultValue=”1”,required=false)Long id){ User u = getBaseService().get(User.class, id);
model.addObject(“user”, u);
model.setViewName(“forward:index.jsp”);
return model;
}
如上代码,如果返回modelAndView 则可以如红⾊标注,添加forward即可,若想重定向,可把forward
替换成redirect便可达到⽬的。(2)返回字符串
@RequestMapping(value=”/forward”,method=RequestMethod.GET)
public String testForward(){
return "forward:/index.action";
}
如上代码红⾊部分。
2.请求重定向
对于请求转发可以分为:1.带参数 2.不带参数
(1)带参数:
Java代码收藏代码
@RequestMapping(value="/redirect",method=RequestMethod.GET)
public String testRedirect(RedirectAttributes attr){
attr.addAttribute("a", "a");
attr.addFlashAttribute("b", "b");
return "redirect:/index.action";
}
带参数可使⽤RedirectAttributes参数进⾏传递:
注意:1.使⽤RedirectAttributes的addAttribute⽅法传递参数会跟随在URL后⾯,如上代码即为http:/index.action?a=a
2.使⽤addFlashAttribute不会跟随在URL后⾯,会把该参数值暂时保存于session,待重定向url获取该参数后从session中移除,这⾥的redirect必须是⽅法映射路径,jsp⽆效。你会发现redirect后的jsp页⾯中b只会出现⼀次,刷新后b再也不会出另外,如果使⽤了RedirectAttributes作为参数,但是没有进⾏redirect呢?这种情况下不会将RedirectAttributes参数传递过去,默认传forward对应的model,官⽅的建议是:
p:ignoreDefaultModelOnRedirect=”true” />
设置下RequestMappingHandlerAdapter 的ignoreDefaultModelOnRedirect属性,这样可以提⾼效率,避免不必要的检索。
(2)⽆参数
@RequestMapping(value=”/redirect”,method=RequestMethod.GET)
public String testRedirect(){
return “redirect:/index.action”;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论