基于Spring MVC的站点上的状态消息(注释控制器)

时间:2010-04-24 10:28:13

标签: java spring-mvc controller annotations

使用注释控制器在基于Spring MVC的站点上组织状态消息(“您的数据是否已成功保存/添加/删除”)的最佳方法是什么?

因此,问题在于从控制器中的POST方法发送消息。

7 个答案:

答案 0 :(得分:16)

正如muanis所提到的,从3.1版开始,最好的方法是使用RedirectAttributes。我将i18n添加到博客中给出的样本中。所以这将是一个完整的样本。

@RequestMapping("/users")
@Controller
public class UsersController {

            @Autowired
            private MessageSource messageSource;

            @RequestMapping(method = RequestMethod.POST, produces = "text/html")
            public String create(@Valid User user, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, Locale locale, RedirectAttributes redirectAttributes) {
                ...
                ...
                redirectAttributes.addFlashAttribute("SUCCESS_MESSAGE", messageSource.getMessage("label_user_saved_successfully", new String[] {user.getUserId()}, locale));
                return "redirect:/users/" + encodeUrlPathSegment("" + user.getId(), httpServletRequest);
            }
    ...
    ...
}

在消息包中添加适当的消息,比如messages.properties。

label_user_saved_successfully=Successfully saved user: {0}

编辑jspx文件以使用相关属性

<c:if test="${SUCCESS_MESSAGE != null}">
  <div id="status_message">${SUCCESS_MESSAGE}</div>
</c:if> 

答案 1 :(得分:8)

一种经过验证的方法是对消息使用特殊的闪存范围,这些消息应保留到下一个GET请求之前。

我喜欢使用会话范围的flash对象:

public interface Flash {
    void info(String message, Serializable... arguments);
    void error(String message, Serializable... arguments);
    Map<String, MessageSourceResolvable> getMessages();
    void reset();
}

@Component("flash")
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public class FlashImpl implements Flash {
    ...
}

一个特殊的MVC拦截器将从flash对象中读取flash值并将它们放在请求范围内:

public class FlashInterceptor implements WebRequestInterceptor {
    @Autowired
    private Flash flash;

    @Override
    public void preHandle(WebRequest request) {
        final Map<String, ?> messages = flash.getMessages();
        request.setAttribute("flash", messages, RequestAttributes.SCOPE_REQUEST);

        for (Map.Entry<String, ?> entry : messages.entrySet()) {
            final String key = "flash" + entry.getKey();
            request.setAttribute(key, entry.getValue(), RequestAttributes.SCOPE_REQUEST);
        }

        flash.reset();
    }

    ...
}

现在,您可以在控制器中将消息放入“闪存范围”中:

@Conteroller
public class ... {
    @Autowired
    private Flash flash;

    @RequestMapping(...)
    public void doSomething(...) {
        // do some stuff...
        flash.info("your.message.key", arg0, arg1, ...);
    }
}

在您的视图中,您将遍历Flash消息:

<c:forEach var="entry" items="${flash}">
    <div class="flash" id="flash-${entry.key}">
        <spring:message message="${entry.value}" />
    </div>
</c:forEach>

我希望这会对你有所帮助。

答案 2 :(得分:1)

经过一段时间再次敲击我的脑袋后,我终于成功了。

我使用的是Spring 3.1,它支持在重定向中传递的requestFlashAttributes。

解决我的问题的关键是将返回类型更改为字符串而不是ModelAndView对象。

这家伙发表了一篇关于在春季使用flash消息的优秀帖子(http://www.tikalk.com/java/redirectattributes-new-feature-spring-mvc-31)

答案 3 :(得分:0)

您应该保持简单并使用特定的HTTP 1.1状态代码。因此,对于成功的通话,您将返回200 OK。在客户端,如果要在控制器返回200时向用户显示特定消息,则在那里显示。

答案 4 :(得分:0)

如果您的意思是在一些POST后重新加载页面,您可以在视图中包含一个标志(JSP或速度或您使用的任何内容)。例如。像这样的东西

<c:if test="${not empty resultMessage}">
 <spring:message code="${resultMessage}" />
</c:if>

您的消息包应该包含该代码的消息。

如果您执行AJAX POST以提交一些数据(即页面未重新加载而您需要显示消息),您可以

1)让JS文件动态化(JSP或Velocity,再次)并在那里插入<spring:message>标签(我真的不喜欢这个选项)

2)遵循this link的建议并使用@ResponseBody将状态对象返回给JS。在标记为@ResponseBody的对象内,您可以同时显示状态和消息。例如。使用this case中的邮件包。

答案 5 :(得分:0)

在JSP上显示消息的最简单方法是使用包含要显示的消息的作用域(可能是会话,可能是请求)对象。例如,您可以执行以下操作:

... java stuff ...
List messages = new ArrayList();
messages.add("some message");
messages.add("some other message");
request.addAttribute("NotableMessages", messages);
... java stuff ...

... jsp and JSTL stuff ...
<c:if test="not empty NotableMessages">
<ul>
<c:forEach items="${NotableMessages}" var="item">
<li>${item}</li>
</c:forEach>
</ul>
</c:if>
... jsp stuff ...

答案 6 :(得分:0)

除了适当的状态代码外,您始终可以使用所需的特定消息设置标题。当然,如果你能控制控制器的使用方式(即没有第三方),这真的是个好主意。