struts1 消息缓存机制
问题:
使用saveError(HttpSession,ActionMessages messages);保存了错误信息。
第一次返回时显示了错误信息,第二次发送请求时错误信息却没了,感到奇怪,深入了解便发现了struts1.x对
缓存信息处理机制的奥妙。
code: save error message
??? ? protected void saveErrors(HttpSession session, ActionMessages errors) {
? ? ? ? // Remove the error attribute if none are required
? ? ? ? if ((errors == null) || errors.isEmpty()) {
? ? ? ? ? ? session.removeAttribute(Globals.ERROR_KEY);
?
? ? ? ? ? ? return;
? ? ? ? }
?
? ? ? ? // Save the errors we need
? ? ? ? session.setAttribute(Globals.ERROR_KEY, errors);//session范围
? ? }
?
ActionServlet 中对每次请求的处理:
? ? */
?1. ? public void doPost(HttpServletRequest request, HttpServletResponse response)
? ? ? ? throws IOException, ServletException {
? ? ? ? process(request, response);
? ? }
?2.
?protected void process(HttpServletRequest request,
? ? ? ? HttpServletResponse response)
? ? ? ? throws IOException, ServletException {
? ? ? ? ModuleUtils.getInstance().selectModule(request, getServletContext());
?
? ? ? ? ModuleConfig config = getModuleConfig(request);
?
? ? ? ? RequestProcessor processor = getProcessorForModule(config);
?
? ? ? ? if (processor == null) {
? ? ? ? ? ? processor = getRequestProcessor(config);
? ? ? ? }
?
? ? ? ? processor.process(request, response);
? ? }
3.
?? ? public void process(HttpServletRequest request, HttpServletResponse response)
? ? ? ? throws IOException, ServletException {
? ? ? ? // Wrap multipart requests with a special wrapper
? ? ? ? request = processMultipart(request);
?
? ? ? ? // Identify the path component we will use to select a mapping
? ? ? ? String path = processPath(request, response);
?
? ? ? ? if (path == null) {
? ? ? ? ? ? return;
? ? ? ? }
?
? ? ? ? if (log.isDebugEnabled()) {
? ? ? ? ? ? log.debug("Processing a '" + request.getMethod() + "' for path '"
? ? ? ? ? ? ? ? + path + "'");
? ? ? ? }
?
? ? ? ? // Select a Locale for the current user if requested
? ? ? ? processLocale(request, response);
?
? ? ? ? // Set the content type and no-caching headers if requested
? ? ? ? processContent(request, response);
? ? ? ? processNoCache(request, response);
?
? ? ? ? // General purpose preprocessing hook
? ? ? ? if (!processPreprocess(request, response)) {
? ? ? ? ? ? return;
? ? ? ? }
?
? ? ? ? this.processCachedMessages(request, response);//缓存信息处理机制
4.
? protected void processCachedMessages(HttpServletRequest request,
? ? ? ? HttpServletResponse response) {
? ? ? ? HttpSession session = request.getSession(false);
?
? ? ? ? if (session == null) {
? ? ? ? ? ? return;
? ? ? ? }
?
? ? ? ? // Remove messages as needed
? ? ? ? ActionMessages messages =
? ? ? ? ? ? (ActionMessages) session.getAttribute(Globals.MESSAGE_KEY);
?
? ? ? ? if (messages != null) {
? ? ? ? ? ? if (messages.isAccessed()) {//是否移除普通消息
? ? ? ? ? ? ? ? session.removeAttribute(Globals.MESSAGE_KEY);
? ? ? ? ? ? }
? ? ? ? }
?
? ? ? ? // Remove error messages as needed
? ? ? ? messages = (ActionMessages) session.getAttribute(Globals.ERROR_KEY);
?
? ? ? ? if (messages != null) {
? ? ? ? ? ? if (messages.isAccessed()) {
? ? ? ? ? ? ? ? session.removeAttribute(Globals.ERROR_KEY);
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
由此我得到了结论。
?
这个问题刚好解决了目前困扰我的一个问题:
? ?1.附件上传功能:?
? ? ? ? 当用户新增一条业务数据时,此时没有业务id,同时这个功能里要增加附件,附件作为单独部分处理,
但是此时没有业务id,不好对把附件id与业务id关联只得把附件id用session缓存起来,此时问题来了,
当新增业务数据时,上传附件,但却没有增加业务数据去进行了,其它的业务操作,当用户第二次进入该功能点
时,因为session缓存,此时该条数据依然存在,给用户造成了困扰。
? 而用struts1的缓存处理机制很好的解决了我的问题:
? code:
?
?if (messages.isAccessed()) {//是否移除普通消息
? ? ? ? ? ? ? ? session.removeAttribute(Globals.MESSAGE_KEY);
? ? ? ? ? ? }