情景再现:
在项目开发中遇到一个问题,用户修改某项信息提交表单后重定向到首页,已经在model中添加了修改结果的提示,如下
model.addAttribute("message", "修改成功!");
但是当使用类似 return "redirect:/admin/class"; 的代码进行跳转的时候,浏览器地址栏的url会增加 (?message="修改成功!")这样的参数影响体验,百度了很多方法(如使用RedirectAttributes、使用RedirectAttributesModelMap、使用RedirectView等)都无法解决,甚至有人说把<mvc:annotation-driven>改成<mvc:annotation-driven ignore-default-model-on-redirect="true">,这更是无稽之谈,因为整个model直接被忽略了,相当于在浏览器里输入首页地址直接访问,设置的提示信息全无。
我的解决思路:
在处理修改请求的方法中,把修改的结果放进session,重定向后,在定向到的方法中从session中取关键字看有没有值,有值得话添加到返回的model里,并且从session中移除改键值对,没有的话则不处理。
代码如下:
处理修改请求的方法classUpdate,添加信息到session,然后重定向到首页地址/admin/class(Clazz是我的实体类不认识不必在意,关注重点即可):
@RequestMapping(value = "/class/update", method=RequestMethod.POST)
public String classUpdate(Clazz clazz, HttpSession session) {
if (clazz.getId()!= null && !StringUtils.equals(clazz.getId(), "")) {
if (clazzService.updateClazz(clazz) != null) {
session.setAttribute("message", "修改成功!");
} else {
session.setAttribute("error", "修改失败!");
}
} else {
if (clazzService.createClazz(clazz) != null) {
session.setAttribute("message", "添加成功!");
} else {
session.setAttribute("error", "添加失败!");
}
}
return "redirect:/admin/class";
}
访问首页的方法,先判断session中是否有数据,有的话添加到model,并从session移除不再需要的数据:
@RequestMapping("/class")
public String classManage(HttpSession session, Model model) {
String message = (String) session.getAttribute("message");
if (message != null) {
model.addAttribute("message", message);
session.removeAttribute("message");
}
String error = (String) session.getAttribute("error");
if (error != null) {
model.addAttribute("error", error);
session.removeAttribute("error");
}
List<Clazz> clazzList = clazzService.getAllClazz();
model.addAttribute("classes", clazzList);
return "admin/classManage";
}
因为这种提示用户的需求基本上只有两种,要么成功要么失败(最多也就有普通信息、成功信息、警告信息、错误信息这四种),所以在访问首页的方法中处理起来并不麻烦,多判断几次即可,当然如果想更优雅也可以定义一个如下的工具类:
public class ModelUtil {
public static void setModelValue(HttpSession session, Model model) {
String[] types = {"message", "success", "warning", "error"};
Object valueObj;
String value;
for (String type : types) {
valueObj = session.getAttribute(type);
if (valueObj != null && !StringUtils.equals(value = (String) valueObj, "")) {
model.addAttribute(type, value);
session.removeAttribute(type);
}
}
}
}
上面的代码可能有些地方难以理解,其实是精细优化的结果:
Object valueObj = session.getAttribute(type);这里不直接强转是因为可能为空,如果下面的if判断为空会因无用的强转浪费一点性能,当判断不为空的时候强转并赋值给定义的value即可,赋值过程也简化在if语句中了,注意向model中添加数据后一定要把session中不再需要的数据清理掉,也算是优化的一部分
在访问首页的方法中如下使用:
@RequestMapping("/class")
public String classManage(HttpSession session, Model model) {
ModelUtil.setModelValue(session, model);
List<Clazz> clazzList = clazzService.getAllClazz();
model.addAttribute("classes", clazzList);
return "admin/classManage";
}
也许之前百度的方法其实可行,但是我试的方法都不行,所以就自己想了这个办法,这个方法不一定是很好,但是最起码行之有效,如果你有更好的更优雅的解决方案欢迎交流!