spring - 使用 RedirectView 进行重定向,然后在 Controller 方法中访问重定向属性
问题描述
我正在尝试使用 Spring MVC 在我的应用程序中创建用户表单,然后验证 ModelAttribute。如果我的验证失败,我会使用 ModelAndView 返回在表单上显示验证错误的视图。我的控制器代码呈现空白表单是:
@GetMapping("/home")
public ModelAndView getUserHome(){
ModelAndView mv = new ModelAndView();
//In actual application, I have more code to put attributes in ModelAndView that will be needed
//on view form, like select box options
mv.addObject("user", new User());
mv.setViewName("user/home/userHome");
return mv;
}
填写视图上的用户表单并单击提交按钮后,我将请求发布到以下控制器方法:
@PostMapping("/persistUser")
public ModelAndView saveUser(@ModelAttribute("user") @Validated User user, BindingResult bindingResult, ModelMap modelMap){
ModelAndView mv = new ModelAndView();
List<ObjectError> errors = bindingResult.getAllErrors();
if(bindingResult.hasErrors() && !(errors.size() == 1 && errors.get(0).getCode().equals("user.system.mismatch"))){
mv.addObject("user", user);
//more code to put more attributes like select box options on view
mv.setViewName("user/home/userHome");
return mv;
}
//if no errors, I have code to persist user object here. At this point
//I sure can have userId and pass this as request attribute to redirect URL.
//But, I need to also pass some messages(based on business logic) about what selections were
//made on user form. I do not have the option to persist these selections on backend,
//as our database does not have supporting columns for that. Therefore, I need to send them as
//redirect attributes. And these messages would be displayed only once, right after the user
//object was created. Upon subsequent visits to this userId view, these messages would no longer
//be required. So we don't really need to persist them at backend.
RedirectView rv = new RedirectView("/user/home?userId="+user.getId(), true, true, false);
//Here user.getId() is the userId newly persisted.
modelMap.addAttribute("message", messageSource.getMessage("user.system.mismatch", null, Locale.US));
return new ModelAndView(rv, modelMap);
}
我在这里获取“用户”模型对象,执行验证,如果出现错误,我通过 ModelAndView 将用户发送回表单。如果没有错误,我有代码来持久化对象并重定向到另一个显示刚刚创建的用户对象的视图。在这个视图中,我需要显示一些我试图作为重定向属性传递给重定向接收控制器方法的消息。请阅读解释我为什么需要传递消息的注释行。我写了我的控制器方法如下:
@GetMapping("/user/home")
public ModelAndView getUser(
@RequestParam(name="userId", required = true) String userId,
@RequestParam(name="message", required = false) String message,
HttpSession session){
ModelAndView mv = new ModelAndView();
User user = (User)session.getAttribute("user");
mv.addObject("message", message);
mv.setViewName("user/home/view");
return mv;
}
我无法在此处检索“消息”属性。我也尝试过使用 RedirectAttributes,但无论哪种方式,我都无法检索存储在“消息”中的值。当然我可以发送“消息”作为另一个请求参数,但是我的消息往往很长,我不想看到超长的 URL。
有人可以建议我如何解决这个问题吗?谢谢。
解决方案
我终于想出了一种将“消息”添加为 RedirectAttributes 并稍后将其检索为 ModelAttribute 的方法。以下是控制器方法的修改版本:
@PostMapping("/persistUser")
public ModelAndView saveUser(@ModelAttribute("user") @Validated User user, BindingResult bindingResult, RedirectAttributes ra){
ModelAndView mv = new ModelAndView();
List<ObjectError> errors = bindingResult.getAllErrors();
if(bindingResult.hasErrors() && !(errors.size() == 1 && errors.get(0).getCode().equals("user.system.mismatch"))){
mv.addObject("user", user);
//more code to put more attributes like select box options on view
mv.setViewName("user/home/userHome");
return mv;
}
RedirectView rv = new RedirectView("/user/home?userId="+user.getId(), true, true, false);
//Here user.getId() is the userId newly persisted.
ra.addFlashAttribute("message", messageSource.getMessage("user.system.mismatch", null, Locale.US));
return new ModelAndView(rv);
}
然后重定向接收方法如下:
@GetMapping("/user/home")
public ModelAndView getUser(
@RequestParam(name="userId", required = true) String userId,
@ModelAttribute(name="message") String message,
HttpSession session){
ModelAndView mv = new ModelAndView();
User user = (User)session.getAttribute("user");
mv.addObject("message", message);
mv.setViewName("user/home/view");
return mv;
}
这对我来说按预期工作。
推荐阅读
- python-3.x - 而不是替换重复的文件格式,而是在文件名中有一个 _1_
- javascript - Reddit 获取 api Oauth 令牌 javascript/react js
- javascript - 对数组中的项目进行分组和过滤
- react-native - 自定义字体不适用于 react-native-paper
- tensorflow - Object Detection Api 中类数对推理时间的影响
- android - 尝试在 Android 中使用 appcenter Distribute
- python - 为什么stitching_detailed.py 和stitching_detailed.cpp 会产生如此不同的结果?
- angular - Angular Datatables 获取所有选定的行
- c - 为什么将输入提供给指针时无法打印值输出?
- c# - 计算给定行数和每行项目限制的列数