Java Spring MVC 控制器重定向使用 URL 参数而不是响应
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2500592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MVC Controller redirect using URL parameters instead of in response
提问by
I am trying to implement RESTful urls in my Spring MVC application. All is well except for handling form submissions. I need to redirect either back to the original form or to a "success" page.
我正在尝试在我的 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";
}
}
However as I read in the Spring documentation, if you redirect any parameters will be put into the url. And that doesn't work for me. What would be the most graceful way around this?
但是,正如我在Spring 文档中所读到的,如果重定向任何参数都将放入 url。这对我不起作用。解决这个问题的最优雅的方法是什么?
采纳答案by Jacob Mattison
http://jira.springframework.org/browse/SPR-6464provided me with what I needed to get things working until Spring MVC offers the functionality (potentially in the 3.0.2 release). Although I simply implemented the classes they have temporarily and added the filter to my web application context. Works great!
http://jira.springframework.org/browse/SPR-6464为我提供了在 Spring MVC 提供功能(可能在 3.0.2 版本中)之前使事情正常工作所需的一切。尽管我只是简单地实现了他们临时拥有的类并将过滤器添加到我的 Web 应用程序上下文中。效果很好!
回答by matt b
You can have processForm()
return a View object instead, and have it return the concrete type RedirectView
which has a parameter for setExposeModelAttributes()
.
您可以processForm()
改为返回一个 View 对象,并让它返回RedirectView
具有setExposeModelAttributes()
.
When you return a view name prefixed with "redirect:"
, Spring MVC transforms this to a RedirectView
object anyway, it just does so with setExposeModelAttributes
to true (which I think is an odd value to default to).
当您返回一个以 为前缀的视图名称时"redirect:"
,Spring MVCRedirectView
无论如何都会将其转换为一个对象,它只是使用setExposeModelAttributes
to true (我认为这是一个奇怪的默认值)。
回答by Jacob Mattison
If you don't want the success message in the URL, then one option is to put it in the session (in the processForm method) and then check for it (and remove it) in the setupForm method.
如果您不想在 URL 中显示成功消息,那么一种选择是将其放入会话中(在 processForm 方法中),然后在 setupForm 方法中检查它(并删除它)。
Edited to add: if this is a pain to do manually, then you could write a subclass of RedirectView that adds a "message" attribute and wraps the process of inserting it into the session. Not sure, though, if there's an easy way to wrap getting the message back out of the session...
编辑添加:如果这是手动完成的痛苦,那么您可以编写一个 RedirectView 的子类,它添加一个“消息”属性并包装将其插入会话的过程。但是,不确定是否有一种简单的方法可以将消息从会话中取出......
Honestly, I don't think there's an easy answer -- the nature of an HTTP redirect is that state isn't carried over; if you want to maintain state anyway, you're stuck with the various usual ways to maintain state in web applications: the session, a cookie, a querystring...
老实说,我不认为有一个简单的答案——HTTP 重定向的本质是状态不会被转移;如果您无论如何都想维护状态,那么您会遇到在 Web 应用程序中维护状态的各种常用方法:会话、cookie、查询字符串……
回答by Mat
I had the same problem. solved it like this:
我有同样的问题。像这样解决了它:
return new ModelAndView("redirect:/user/list?success=true");
And then my controller method look like this:
然后我的控制器方法如下所示:
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;
}
Works perfectly unless you want to send simple data, not collections let's say. Then you'd have to use session I guess.
除非您想发送简单的数据,否则可以完美地工作,而不是集合。那么我猜你就必须使用会话。
回答by MatCarey
This problem is caused (as others have stated) by model attributes being persisted into the query string - this is usually undesirable and is at risk of creating security holes as well as ridiculous query strings. My usual solution is to never use Strings for redirects in Spring MVC, instead use a RedirectView which can be configured not to expose model attributes (see: http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/servlet/view/RedirectView.html)
这个问题是由模型属性被持久化到查询字符串中引起的(正如其他人所说) - 这通常是不可取的,并且有创建安全漏洞以及荒谬的查询字符串的风险。我通常的解决方案是永远不要在 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)
So I tend to have a util method which does a 'safe redirect' like:
所以我倾向于使用一个 util 方法来执行“安全重定向”,例如:
public static RedirectView safeRedirect(String url) {
RedirectView rv = new RedirectView(url);
rv.setExposeModelAttributes(false);
return rv;
}
The other option is to use bean configuration XML:
另一种选择是使用 bean 配置 XML:
<bean id="myBean" class="org.springframework.web.servlet.view.RedirectView">
<property name="exposeModelAttributes" value="false" />
<property name="url" value="/myRedirect"/>
</bean>
Again, you could abstract this into its own class to avoid repetition (e.g. SafeRedirectView).
同样,您可以将其抽象为它自己的类以避免重复(例如 SafeRedirectView)。
A note about 'clearing the model' - this is not the same as 'not exposing the model' in all circumstances. One site I worked on had a lot of filters which added things to the model, this meant that clearing the model before redirecting would not prevent a long query string. I would also suggest that 'not exposing model attributes' is a more semantic approach than 'clearing the model before redirecting'.
关于“清除模型”的说明 - 这与在所有情况下“不暴露模型”不同。我工作的一个站点有很多过滤器,它们向模型添加了一些东西,这意味着在重定向之前清除模型不会阻止长查询字符串。我还建议“不公开模型属性”是一种比“重定向前清除模型”更语义化的方法。
回答by Sudhanshu Gaur
Hey you can just do one simple thing instead of using model to send parameter use HttpServletRequest object and do this
嘿,您可以只做一件简单的事情,而不是使用模型发送参数使用 HttpServletRequest 对象并执行此操作
HttpServletRequest request;
request.setAttribute("param", "value")
now your parametrs will not be shown in your url header hope it works :)
现在您的参数将不会显示在您的 url 标头中,希望它能正常工作:)
回答by Anton
@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");
}