基于 Spring MVC 的站点上的状态消息(注释控制器)
2022-09-01 17:40:38
使用注释控制器在基于Spring MVC的站点上组织状态消息(“您的数据已成功保存/添加/删除”)的最佳方法是什么?
因此,问题在于在 contoller 中从 POST 方法发送消息的方式。
使用注释控制器在基于Spring MVC的站点上组织状态消息(“您的数据已成功保存/添加/删除”)的最佳方法是什么?
因此,问题在于在 contoller 中从 POST 方法发送消息的方式。
正如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>
一种行之有效的方法是对应保留到下一个 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 拦截器将从闪存对象读取闪存值,并将它们放在请求范围内:
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>
我希望这对你有所帮助。