用户刷新页面
错误消失了
如何保存页面刷新错误?
这就是MessageStoreInterceptor的工作方式。它实际上是一个功能,而不是错误。
页面刷新是用户触发的操作,这意味着可以假定他已经阅读了上一个操作(登录尝试)的结果,除非他闭着眼睛按F5键。
您应该希望消息在第一次读取后过期。
考虑具有很多非ajax操作的页面,例如,组合框取决于其他操作,等等。…如果错误消息持续存在,则它将在每次不涉及进入另一个页面的提交操作之后弹出。
你不要那样 您应该希望收到一条消息,指出在 该
操作之后一个操作出了错(或正确)。如果用户随后继续执行其他操作(如刷新),并且这些操作没有出错(或处于特定的成功状态),则不会显示任何消息。
在那之后,也有不少世界问题 时,
从会话持久性消息删除,否则你会与下一个动作得到该消息
RETRIEVE或
AUTOMATIC一个operationMode。然后,您可以(但不应该)自定义MessageStore拦截器,或自行在会话之间写入/读取/删除消息,从而从根本上重新发明轮子。甚至放置两个MessageStore拦截器,一个
RETRIEVE和一个
STORE用于
displayLoginPageAction,得到刚才提到的陷阱。
您还使用PRG模式(发布/重定向/获取),以避免刷新页面时重新发送数据。同样,您应该避免重复读取相同的消息两次。
要查看它是如何工作的,可以看一下MessageStore
Interceptor源代码,它很简单:
在调用之前,如果Action是
ValidationAware
andoperationMode
是RETRIEVE
orAUTOMATIC
:- 阅读
actionMessages
,actionErrors
,fieldErrors
从会议; - 合并 与当前行动的他们
actionMessages
,actionErrors
,fieldErrors
, - 除去
actionMessages
,actionErrors
,fieldErrors
从会议。
/*
* Handle the retrieving of field errors / action messages / field errors, which is
* done before action invocation, and theoperationMode
is ‘RETRIEVE’.
* * @param invocation
* @throws Exception
/
protected void before(ActionInvocation invocation) throws Exception {
String reqOperationMode = getRequestOperationMode(invocation);if (RETRIEVE_MODE.equalsIgnoreCase(reqOperationMode) || RETRIEVE_MODE.equalsIgnoreCase(operationMode) || AUTOMATIC_MODE.equalsIgnoreCase(operationMode)) { Object action = invocation.getAction(); if (action instanceof ValidationAware) { // retrieve error / message from session Map session = (Map) invocation.getInvocationContext().get(ActionContext.SESSION); if (session == null) { if (LOG.isDebugEnabled()) { LOG.debug("Session is not open, no errors / messages could be retrieve for action ["+action+"]"); } return; } ValidationAware validationAwareAction = (ValidationAware) action; if (LOG.isDebugEnabled()) { LOG.debug("retrieve error / message from session to populate into action ["+action+"]"); } Collection actionErrors = (Collection) session.get(actionErrorsSessionKey); Collection actionMessages = (Collection) session.get(actionMessagesSessionKey); Map fieldErrors = (Map) session.get(fieldErrorsSessionKey); if (actionErrors != null && actionErrors.size() > 0) { Collection mergedActionErrors = mergeCollection(validationAwareAction.getActionErrors(), actionErrors); validationAwareAction.setActionErrors(mergedActionErrors); } if (actionMessages != null && actionMessages.size() > 0) { Collection mergedActionMessages = mergeCollection(validationAwareAction.getActionMessages(), actionMessages); validationAwareAction.setActionMessages(mergedActionMessages); } if (fieldErrors != null && fieldErrors.size() > 0) { Map mergedFieldErrors = mergeMap(validationAwareAction.getFieldErrors(), fieldErrors); validationAwareAction.setFieldErrors(mergedFieldErrors); } session.remove(actionErrorsSessionKey); session.remove(actionMessagesSessionKey); session.remove(fieldErrorsSessionKey); }}}
- 阅读
调用后,如果Action是
ValidationAware
andoperationMode
是STORE
or(或operationMode
is是AUTOMATIC
Result的类型redirectAction
):- 阅读
actionMessages
,actionErrors
,fieldErrors
从行动; - 存储
actionMessages
,actionErrors
,fieldErrors
在会话中。
/*
* Handle the storing of field errors / action messages / field errors, which is
* done after action invocation, and theoperationMode
is in ‘STORE’.
* * @param invocation
* @param result
* @throws Exception
/
protected void after(ActionInvocation invocation, String result) throws Exception {String reqOperationMode = getRequestOperationMode(invocation);boolean isRedirect = invocation.getResult() instanceof ServletRedirectResult;if (STORE_MODE.equalsIgnoreCase(reqOperationMode) || STORE_MODE.equalsIgnoreCase(operationMode) || (AUTOMATIC_MODE.equalsIgnoreCase(operationMode) && isRedirect)) { Object action = invocation.getAction(); if (action instanceof ValidationAware) { // store error / messages into session Map session = (Map) invocation.getInvocationContext().get(ActionContext.SESSION); if (session == null) { if (LOG.isDebugEnabled()) { LOG.debug("Could not store action ["+action+"] error/messages into session, because session hasn't been opened yet."); } return; } if (LOG.isDebugEnabled()) { LOG.debug("store action ["+action+"] error/messages into session "); } ValidationAware validationAwareAction = (ValidationAware) action; session.put(actionErrorsSessionKey, validationAwareAction.getActionErrors()); session.put(actionMessagesSessionKey, validationAwareAction.getActionMessages()); session.put(fieldErrorsSessionKey, validationAwareAction.getFieldErrors()); } else if(LOG.isDebugEnabled()) { LOG.debug("Action ["+action+"] is not ValidationAware, no message / error that are storeable"); }}}
- 阅读
注1 :登录操作也是不言自明的:如果登录后再次进入登录页面,则仅表示登录失败…顺便说一句,以上说明适用于每个页面/功能
注2 :网站产生的消息会在X秒钟后自动过期,而不关心用户是否已阅读这些消息…… 这 与可用性恕我直言。



