jsessionid 所引起的404问题和解决方法
问题:
在SpringMvc使用RedirectView或者"redirect:"前缀来做重定向时,Spring MVC最后会调用:
response.sendRedirect(response.encodeRedirectURL(url));
对于某些浏览器来说,打开一个新的浏览器窗口,第一次访问服务器时,encodeRedirectURL()会在url后面附加上一段jsessionid,
如果初始的url为"http://www.sina.com.cn",最终得到的url为"http://www.sina.com.cn;jsessionid=126AFFB8D83764DB4843889A72C0E4B6"
这是典型的Java做事的方式,其他语言的服务器端平台并不会这样做。这个jsessionid很多时候会引起严重的问题,例如,如果你使用上述带有jsessionid的url直接访问新浪的网站,IE会向你报告:找不到服务器。
解决方法:
不通过Spring MVC做重定向,自己直接调用:
response.sendRedirect(url); return null; //告诉Spring MVC我已经完成了处理
基于拓展知识的需要,如果问题已经解决,以下内容可以不看。
其他方案:
1) 还有说通过重写覆写dofilter方法:
/** * @ClassName: CorsFilter * @Description: (跨域过滤器) */ @Component public class CorsFilter implements Filter { private static Logger logger = LoggerFactory.getLogger(CorsFilter.class); @Override public void init(FilterConfig config) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) resp; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,Accept"); response.setHeader("P3P", "CP=CAO PSA OUR"); HttpServletResponseWrapper wrappedResponse = null; if (req instanceof HttpServletRequest) { HttpServletRequest httpRequest = (HttpServletRequest) req; if (httpRequest.isRequestedSessionIdFromURL()) { logger.info("doFilter isRequestedSessionIdFromURL"); HttpSession session = httpRequest.getSession(); if (session != null) { session.invalidate(); } // wrap response to remove URL encoding wrappedResponse = new HttpServletResponseWrapper(response) { @Override public String encodeRedirectUrl(String url) { logger.info("doFilter encodeRedirectUrl=" + url); return url; } @Override public String encodeRedirectURL(String url) { logger.info("doFilter encodeRedirectURL=" + url); return url; } @Override public String encodeUrl(String url) { logger.info("doFilter encodeUrl=" + url); return url; } @Override public String encodeURL(String url) { logger.info("doFilter encodeURL=" + url); return url; } }; } } chain.doFilter(req, wrappedResponse != null ? wrappedResponse : resp); } @Override public void destroy() { }
核心点是把
response.sendRedirect(response.encodeRedirectURL(url));
改为:response.sendRedirect(url);
亲测后,好像并不能解决问题。
2)Cookie欺骗
encodeRedirectURL()仅在无法确定浏览器是否支持cookie的时候才会在url后面附加上jsessionid,如果它能找到一个jsessionid的cookie,它就认为浏览器是支持cookie的。
因此可以自己创建一个jsessionid的cookie来欺骗encodeRedirectURL()。
Cookie cookie = new Cookie("jsessionid", "xxxxxxxxxxxxxxxxxxxx"); cookie.setMaxAge(Integer.MAX_VALUE); response.addCookie(cookie); 然后再调用Spring MVC的重定向功能就没有问题了。
这种方法没有测试过。