一尘不染

将通知消息设置为请求属性,该属性应在sendRedirect之后显示

jsp

我创建了两套servlet:视图和控制器/处理程序

  • 浏览次数 :进行简单的读取和数据转发给 JSP 小号
  • 控制器 :执行数据库更新或插入,并向 JSP 或View类型的servlet 发送通知

此处的通知是针对用户的状态消息。示例:“您已成功更新等等…”

如果我requestDispatcher.forward()在控制器中使用并且用户刷新(在控制器将控件传递给视图/
jsp之后),则通过确认重新发送来刷新页面,可能会执行重复的操作

如果我使用,response.sendRedirect()似乎在会话中未设置任何通知就无法发送任何通知

有没有一个好的设计实践可以帮助您?任何处理此特定情况的Java w / o框架的MVC的良好链接都将受到赞赏。

我没有使用Spring或Struts-只是普通的旧HTTPServlet

示例-控制器:

public XServlet extends HttpServlet{
     public void processRequest(request, response) throws ...{ 
         //Do some stuff here
         if(success){
             setUserMessage("Hooray ur profile pic is uploaded!");
         } else {
             setUserMessage("Oh no! We couldn't upload that file its too biG!");
         }

         //Send the notification
         request.setAttribute("status", getUserMessage());
         request.getRequestDispatcher("editProfile.jsp").forward(request, response);
    }
}

这样做意味着如果用户尝试刷新页面,则控件将再次传递给该控制器,并且某些操作可能会不必要地重复。

但是,如果我使用它,sendRedirect()那么我不借助会话属性或将其附加到url就无法显示状态消息。


阅读 337

收藏
2020-06-08

共1个答案

一尘不染

您正在寻找“ Flash作用域 ”。

闪存作用域由一个短暂的cookie支持,该cookie与会话作用域中的数据条目相关联。重定向之前,将在HTTP响应上设置一个cookie,该cookie的值与会话范围内的数据条目唯一关联。重定向之后,将检查Flash作用域cookie的存在,并将与cookie关联的数据条目从会话作用域中删除,并将其放入重定向请求的请求作用域中。最后,cookie将从HTTP响应中删除。这样,重定向的请求可以访问在初始请求中准备的请求范围的数据。

用简单的Servlet术语表示如下:

  1. 创建闪存作用域并添加条目:
        String message = "Some message";

    // ...

    Map<String, Object> flashScope = new HashMap<>();
    flashScope.put("message", message);
  1. 重定向之前,请将其存储在以唯一ID为键的会话中,并将其设置为cookie:
        String flashScopeId = UUID.randomUUID().toString();
    request.getSession().setAttribute(flashScopeId, flashScope);
    Cookie cookie = new Cookie("flash", flashScopeId);
    cookie.setPath(request.getContextPath());
    response.addCookie(cookie);

    // ...

    response.sendRedirect(request.getContextPath() + "/someservlet");
  1. 在下一个请求中,找到Flash Cookie,将其映射回请求范围并删除Cookie:
        if (request.getCookies() != null) {
        for (Cookie cookie : request.getCookies()) {
            if ("flash".equals(cookie.getName())) {
                Map<String, Object> flashScope = (Map<String, Object>) request.getSession().getAttribute(cookie.getValue());

                if (flashScope != null) {
                    request.getSession().removeAttribute(cookie.getValue());

                    for (Entry<String, Object> entry : flashScope.entrySet()) {
                        request.setAttribute(entry.getKey(), entry.getValue());
                    }
                }

                cookie.setValue(null);
                cookie.setMaxAge(0);
                cookie.setPath(request.getContextPath());
                response.addCookie(cookie);
            }
        }
    }

可以使用特定于上下文的帮助器方法(例如setFlashAttribute(),带有响应包装器的Servlet过滤器)进一步抽象该方法。

2020-06-08