简体   繁体   English

如何处理 spring mvc 中的浏览器后退按钮

[英]How handle browser back button in spring mvc

When a user is logged on session information is stored.当用户登录时,session 信息被存储。 And session information is erased when the user is logged out.并且 session 信息在用户注销时被删除。 But when I hit the browser 's back button user information is displayed.但是当我点击浏览器的后退按钮时,会显示用户信息。 Since session is gone but we can not be sure the user login operation is carried out.由于 session 已消失,但我们无法确定是否执行了用户登录操作。 How do I resolve this issue?我该如何解决这个问题?

  ----------------------------log out -------------------------------

   @RequestMapping(value="logout.htm",method = RequestMethod.GET)
   public void logOut(HttpSession session,HttpServletResponse                 
   response,HttpServletRequest request) throws IOException{
    final String refererUrl = request.getHeader("Referer");
    response.setHeader(refererUrl, "no-cache");
    response.setHeader("Cache-Control", "no-cache");
    response.setDateHeader("Expires", 0);
    session.removeAttribute("user");
    session.invalidate();
    response.sendRedirect("index.htm");
   }
    ---------------------------------- login ---------------
  @RequestMapping(value="/userLogin",method=RequestMethod.POST)

  public @ResponseBody JsonResponse
 login(@ModelAttribute(value="user") User user, BindingResult     result,HttpServletRequest request,HttpSession session,ModelMap model) throws    UnsupportedEncodingException{

    JsonResponse res = new JsonResponse();

    if(!result.hasErrors()&& userService.findUser(user, request)){
        res.setStatus("SUCCESS");
        session.setAttribute("user",
      new String(user.getUsername().getBytes("iso-  8859-1"), "UTF-8"));
      }
         else{
        res.setStatus("FAIL");
        result.rejectValue("username","1");
        res.setResult(result.getAllErrors());
       }
      return res;
   }
   --------------------------profile --------------------------------------

    @RequestMapping(value="myProfile.htm",method = RequestMethod.GET)
   public String showmyProfile(@ModelAttribute(value="addUser") User user,Model          model,HttpServletRequest request,
        HttpServletResponse response,
         HttpSession session) throws IOException{

        if(session.getAttribute("user")== null){
        response.sendRedirect("index");
    }

i use this method. 我用这种方法。 first create one class that implements Filter and override doFilter() method. 首先创建一个实现Filter的类并重写doFilter()方法。 code of doFilter() is: doFilter()的代码是:

 @Override
 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse hsr = (HttpServletResponse) res;
hsr.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
hsr.setHeader("Pragma", "no-cache"); // HTTP 1.0.
hsr.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(req, res);
 }

after use filter in web.xml. 之后在web.xml中使用过滤器。 this filter is this. 这个过滤器就是这个。

  <filter>
    <filter-name>noCacheFilter</filter-name>
    <filter-class>com.example.NoCacheFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>noCacheFilter</filter-name>
  <url-pattern>/secured/*.jsp</url-pattern>// urls that not cached 
 </filter-mapping>

Configure an interceptor inside Servlet Context as this: 在Servlet上下文中配置一个拦截器,如下所示:

<!--  configuration for handling browser back button  -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**/*"/>
        <beans:bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
            <beans:property name="cacheSeconds" value="0"/>
            <beans:property name="useExpiresHeader" value="true"/>
            <beans:property name="useCacheControlHeader" value="true"/>
            <beans:property name="useCacheControlNoStore" value="true"/>
        </beans:bean>
    </mvc:interceptor>
</mvc:interceptors>

Note: Don't forget to remove your browser cache while testing your application. 注意:测试应用程序时,请不要忘记删除浏览器缓存。

在spring-security 4.0中,默认情况下已解决此问题。即使在安全XML配置中,也不需要编写任何其他代码。

response.setHeader(refererUrl, "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);

The above code clears cache and expiring the session in the server side. 上面的代码在服务器端清除了缓存并终止了会话。 But whether session is live or not, it should be verified or handled in your view (HTML or JSP). 但是,无论会话是否在线,都应在您的视图(HTML或JSP)中对其进行验证或处理。 You can have the following meta tags in your view to say no-cache and no-store 您可以在视图中使用以下元标记来表示无缓存和无存储

<meta http-equiv="Cache-control" content="no-cache">

or 要么

<META HTTP-EQUIV="Cache-Control" CONTENT="No-Cache,Must-Revalidate,No-Store">

Please refer this for Browser Cache Control 请参考以获得浏览器缓存控制

The Spring Boot implementation is extrapolated from Hadi J's answer . Spring 引导实现是从Hadi J 的回答中推断出来的。

NOTE: This implementation will work for Spring Boot v1.3.0 or above.注意:此实现适用于 Spring Boot v1.3.0 或更高版本。


Create a CustomFilter.java class which will implement the Filter interface.创建一个CustomFilter.java class 它将实现Filter接口。 The aim here is to disable caching.这里的目的是禁用缓存。

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;

@WebFilter
public class CustomFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        
        httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        httpServletResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        httpServletResponse.setDateHeader("Expires", 0); // Proxies.
        
        chain.doFilter(request, response);
    }

}

Finally, add the @ServletComponentScan annotation to your SpringBootApplication class.最后,将@ServletComponentScan注解添加到您的SpringBootApplication class。 This will enable scanning for @WebFilter , @WebListener and @WebServlet annotations.这将启用对@WebFilter@WebListener@WebServlet注释的扫描。

@ServletComponentScan
@SpringBootApplication
public class SampleSpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SampleSpringBootApplication.class, args);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM