我正在尝试在Spring MVC应用程序中实现RESTful url。一切都很好,除了处理表格提交。我需要将其重定向回原始表单或“成功”页面。
@Controller
@RequestMapping("/form")
public class MyController {
@RequestMapping(method = RequestMethod.GET)
public String setupForm() {
// do my stuff
return "myform";
}
@RequestMapping(method = RequestMethod.POST)
public String processForm(ModelMap model) {
// process form data
model.addAttribute("notification", "Successfully did it!");
return "redirect:/form";
}
}
但是,当我在Spring documentation中读到时,如果您重定向任何参数将被放入网址。这对我不起作用。什么是最优雅的方式呢?
答案 0 :(得分:34)
我遇到了同样的问题。解决了这个问题:
return new ModelAndView("redirect:/user/list?success=true");
然后我的控制器方法如下所示:
public ModelMap list(@RequestParam(required=false) boolean success) {
ModelMap mm = new ModelMap();
mm.put(SEARCH_MODEL_KEY, campaignService.listAllCampaigns());
if(success)
mm.put("successMessageKey", "campaign.form.msg.success");
return mm;
}
除非你想发送简单的数据,否则完全可以工作,而不是收集。然后你必须使用我猜的会话。
答案 1 :(得分:10)
这个问题是由于模型属性被持久化到查询字符串中引起的(正如其他人所说的) - 这通常是不受欢迎的,并且存在创建安全漏洞以及荒谬的查询字符串的风险。我通常的解决方案是永远不要在Spring MVC中使用字符串重定向,而是使用RedirectView,它可以配置为不公开模型属性(参见:http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/servlet/view/RedirectView.html)
RedirectView(String url, boolean contextRelative, boolean http10Compatible, boolean exposeModelAttributes)
所以我倾向于使用一个util方法来执行'安全重定向',如:
public static RedirectView safeRedirect(String url) {
RedirectView rv = new RedirectView(url);
rv.setExposeModelAttributes(false);
return rv;
}
另一个选择是使用bean配置XML:
<bean id="myBean" class="org.springframework.web.servlet.view.RedirectView">
<property name="exposeModelAttributes" value="false" />
<property name="url" value="/myRedirect"/>
</bean>
同样,你可以将它抽象到自己的类中以避免重复(例如SafeRedirectView)。
关于“清除模型”的说明 - 这与在所有情况下“不暴露模型”不同。我工作的一个站点有很多过滤器,它们向模型添加了东西,这意味着在重定向之前清除模型不会阻止长查询字符串。我还建议“不暴露模型属性”比“重定向前清除模型”更具语义性。
答案 2 :(得分:8)
您可以让processForm()
返回一个View对象,并让它返回具有RedirectView
参数的具体类型setExposeModelAttributes()
。
当你返回一个前缀为"redirect:"
的视图名称时,无论如何,Spring MVC会将其转换为RedirectView
对象,它只是将setExposeModelAttributes
转换为true(我认为这是奇怪的)值默认为)。
答案 3 :(得分:7)
http://jira.springframework.org/browse/SPR-6464为我提供了所需的功能,直到Spring MVC提供功能(可能在3.0.2版本中)。虽然我只是简单地实现了他们暂时的类,并将过滤器添加到我的Web应用程序上下文中。效果很棒!
答案 4 :(得分:4)
如果您不希望URL中有成功消息,那么一个选项是将其放入会话中(在processForm方法中),然后在setupForm方法中检查它(并将其删除)。
编辑添加:如果手动执行此操作很痛苦,那么您可以编写RedirectView的子类,添加“message”属性并包装将其插入会话的过程。但是,不确定是否有一种简单的方法可以将消息从会话中取出...
老实说,我认为没有一个简单的答案 - HTTP重定向的本质是状态不会被延续;如果你想保持状态无论如何,你仍然坚持使用各种常用方法来维护Web应用程序中的状态:会话,cookie,查询字符串......
答案 5 :(得分:3)
嘿,你可以做一个简单的事情而不是使用模型发送参数使用HttpServletRequest对象并执行此操作
HttpServletRequest request;
request.setAttribute("param", "value")
现在您的参数将不会显示在您的网址标题中,希望它有效:)
答案 6 :(得分:1)
@RequestMapping(path="/apps/add", method=RequestMethod.POST)
public String addApps(String appUrl, Model model, final RedirectAttributes redirectAttrs) {
if (!validate(appUrl)) {
redirectAttrs.addFlashAttribute("error", "Validation failed");
}
return "redirect:/apps/add"
}
@RequestMapping(path="/apps/add", method=RequestMethod.GET)
public String addAppss(Model model) {
String error = model.asMap().get("error");
}