Spring MVC Controller使用URL参数重定向而不是响应

时间:2010-03-23 14:17:48

标签: java redirect spring-mvc controller

我正在尝试在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中读到时,如果您重定向任何参数将被放入网址。这对我不起作用。什么是最优雅的方式呢?

7 个答案:

答案 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");
}