我创建了两套servlet:视图和控制器/处理程序
此处的通知是针对用户的状态消息。示例:“您已成功更新等等…”
如果我requestDispatcher.forward()在控制器中使用并且用户刷新(在控制器将控件传递给视图/ jsp之后),则通过确认重新发送来刷新页面,可能会执行重复的操作
requestDispatcher.forward()
如果我使用,response.sendRedirect()似乎在会话中未设置任何通知就无法发送任何通知
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就无法显示状态消息。
sendRedirect()
您正在寻找“ Flash作用域 ”。
闪存作用域由一个短暂的cookie支持,该cookie与会话作用域中的数据条目相关联。重定向之前,将在HTTP响应上设置一个cookie,该cookie的值与会话范围内的数据条目唯一关联。重定向之后,将检查Flash作用域cookie的存在,并将与cookie关联的数据条目从会话作用域中删除,并将其放入重定向请求的请求作用域中。最后,cookie将从HTTP响应中删除。这样,重定向的请求可以访问在初始请求中准备的请求范围的数据。
用简单的Servlet术语表示如下:
String message = "Some message"; // ... Map<String, Object> flashScope = new HashMap<>(); flashScope.put("message", message);
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");
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过滤器)进一步抽象该方法。
setFlashAttribute()