Struts2 action 的 ;jsessionid=xxx 使找不到页面 Bug 的解决 [转帖]
原文地址自己留个地址,遇到这个问题可以考虑使用。不过要重新编译struts2的jar包确实比较。。。
刚刚又找到一个解决办法:
在用Struts的时候发现这样一个问题,不管我们的程序中是否创建了一个新的session,从页面提交表单到action类,再跳转到页面的时候url中总是出现了;jsessionid这样的一长串内容,这是由于新建的session导致容器产生的。
经过深入研究struts的代码发现问题所在,原来是struts在处理自动Locale时导致的,struts调用了request.getSession()方法,该方法等同于 request.getSession(true) ,相当于不存在session时就自动创建一个新的session,于是就出现前面提到的现象。
要解决这个问题必须关闭struts的自动Locale的功能,不过很简单,只用在struts-config.xml的controller配置增加一个locale参数值等于false即可,如:
<controller locale="false"/>
上述办法貌似针对的是Struts1的。又去搜索了一下。或许可以用一下方案:
通过加入 Filter 的方式过滤掉 URL 中包含的 jsessionid,再重新包装 Response 返回给浏览器。
代码如下:
DisableUrlSessionFilter.java
package
com.randomcoder.security;
import java.io.IOException;
import javax.servlet. * ;
import javax.servlet.http. * ;
/** */ /**
* Servlet filter which disables URL-encoded session identifiers.
*
* <pre>
* Copyright (c) 2006, Craig Condit. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* </pre>
*/
@SuppressWarnings( " deprecation " )
public class DisableUrlSessionFilter implements Filter
{
/** *//**
* Filters requests to disable URL-based session identifiers.
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
// skip non-http requests
if (!(request instanceof HttpServletRequest))
{
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// clear session if session id in URL
if (httpRequest.isRequestedSessionIdFromURL())
{
HttpSession session = httpRequest.getSession();
if (session != null) session.invalidate();
}
// wrap response to remove URL encoding
HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(httpResponse)
{
@Override
public String encodeRedirectUrl(String url) { return url; }
@Override
public String encodeRedirectURL(String url) { return url; }
@Override
public String encodeUrl(String url) { return url; }
@Override
public String encodeURL(String url) { return url; }
};
// process next request in chain
chain.doFilter(request, wrappedResponse);
}
/** *//**
* Unused.
*/
public void init(FilterConfig config) throws ServletException {}
/** *//**
* Unused.
*/
public void destroy() {}
}
import java.io.IOException;
import javax.servlet. * ;
import javax.servlet.http. * ;
/** */ /**
* Servlet filter which disables URL-encoded session identifiers.
*
* <pre>
* Copyright (c) 2006, Craig Condit. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* </pre>
*/
@SuppressWarnings( " deprecation " )
public class DisableUrlSessionFilter implements Filter
{
/** *//**
* Filters requests to disable URL-based session identifiers.
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
// skip non-http requests
if (!(request instanceof HttpServletRequest))
{
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// clear session if session id in URL
if (httpRequest.isRequestedSessionIdFromURL())
{
HttpSession session = httpRequest.getSession();
if (session != null) session.invalidate();
}
// wrap response to remove URL encoding
HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(httpResponse)
{
@Override
public String encodeRedirectUrl(String url) { return url; }
@Override
public String encodeRedirectURL(String url) { return url; }
@Override
public String encodeUrl(String url) { return url; }
@Override
public String encodeURL(String url) { return url; }
};
// process next request in chain
chain.doFilter(request, wrappedResponse);
}
/** *//**
* Unused.
*/
public void init(FilterConfig config) throws ServletException {}
/** *//**
* Unused.
*/
public void destroy() {}
}
相应的web.xml文件为:
<?
xml version="1.0" encoding="UTF-8"
?>
< web-app xmlns ="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version ="2.4" >
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext.xml </ param-value >
</ context-param >
<!--
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.fallbackLocale</param-name>
<param-value>en_US</param-value>
</context-param>
-->
< context-param >
< param-name > javax.servlet.jsp.jstl.fmt.localizationContext </ param-name >
< param-value > ApplicationResources </ param-value >
</ context-param >
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
< filter >
< filter-name > DisableUrlSessionFilter </ filter-name >
< filter-class > com.randomcoder.security.DisableUrlSessionFilter </ filter-class >
</ filter >
< filter >
< filter-name > OpenSessionInViewFilter </ filter-name >
< filter-class > org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </ filter-class >
</ filter >
< filter >
< filter-name > CitadelFilter </ filter-name >
< filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >
< init-param >
< param-name > targetBeanName </ param-name >
< param-value > citadelFilter </ param-value >
</ init-param >
</ filter >
< filter-mapping >
< filter-name > DisableUrlSessionFilter </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< filter-mapping >
< filter-name > OpenSessionInViewFilter </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< filter-mapping >
< filter-name > CitadelFilter </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< servlet >
< servlet-name > springmvc </ servlet-name >
< servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
< load-on-startup > 1 </ load-on-startup >
</ servlet >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /home </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /login </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /login-error </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /logout </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /article/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /articles/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /tag/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /tags/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /legal/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /test/* </ url-pattern >
</ servlet-mapping >
< session-config >
< session-timeout > 30 </ session-timeout >
</ session-config >
< welcome-file-list >
< welcome-file > index.jsp </ welcome-file >
< welcome-file > index.html </ welcome-file >
</ welcome-file-list >
< jsp-config >
< jsp-property-group >
< url-pattern > *.jsp </ url-pattern >
< el-ignored > false </ el-ignored >
< page-encoding > UTF-8 </ page-encoding >
< scripting-invalid > true </ scripting-invalid >
</ jsp-property-group >
</ jsp-config >
< resource-ref >
< res-ref-name > jdbc/randomcoder </ res-ref-name >
< res-type > javax.sql.DataSource </ res-type >
< res-auth > Container </ res-auth >
</ resource-ref >
< env-entry >
< env-entry-name > loginEncryptionKey </ env-entry-name >
< env-entry-type > java.lang.String </ env-entry-type >
</ env-entry >
< mime-mapping >
< extension > wsdl </ extension >
< mime-type > text/xml </ mime-type >
</ mime-mapping >
</ web-app >
< web-app xmlns ="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version ="2.4" >
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext.xml </ param-value >
</ context-param >
<!--
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.fallbackLocale</param-name>
<param-value>en_US</param-value>
</context-param>
-->
< context-param >
< param-name > javax.servlet.jsp.jstl.fmt.localizationContext </ param-name >
< param-value > ApplicationResources </ param-value >
</ context-param >
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
< filter >
< filter-name > DisableUrlSessionFilter </ filter-name >
< filter-class > com.randomcoder.security.DisableUrlSessionFilter </ filter-class >
</ filter >
< filter >
< filter-name > OpenSessionInViewFilter </ filter-name >
< filter-class > org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </ filter-class >
</ filter >
< filter >
< filter-name > CitadelFilter </ filter-name >
< filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >
< init-param >
< param-name > targetBeanName </ param-name >
< param-value > citadelFilter </ param-value >
</ init-param >
</ filter >
< filter-mapping >
< filter-name > DisableUrlSessionFilter </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< filter-mapping >
< filter-name > OpenSessionInViewFilter </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< filter-mapping >
< filter-name > CitadelFilter </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
< servlet >
< servlet-name > springmvc </ servlet-name >
< servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
< load-on-startup > 1 </ load-on-startup >
</ servlet >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /home </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /login </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /login-error </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /logout </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /article/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /articles/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /tag/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /tags/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /legal/* </ url-pattern >
</ servlet-mapping >
< servlet-mapping >
< servlet-name > springmvc </ servlet-name >
< url-pattern > /test/* </ url-pattern >
</ servlet-mapping >
< session-config >
< session-timeout > 30 </ session-timeout >
</ session-config >
< welcome-file-list >
< welcome-file > index.jsp </ welcome-file >
< welcome-file > index.html </ welcome-file >
</ welcome-file-list >
< jsp-config >
< jsp-property-group >
< url-pattern > *.jsp </ url-pattern >
< el-ignored > false </ el-ignored >
< page-encoding > UTF-8 </ page-encoding >
< scripting-invalid > true </ scripting-invalid >
</ jsp-property-group >
</ jsp-config >
< resource-ref >
< res-ref-name > jdbc/randomcoder </ res-ref-name >
< res-type > javax.sql.DataSource </ res-type >
< res-auth > Container </ res-auth >
</ resource-ref >
< env-entry >
< env-entry-name > loginEncryptionKey </ env-entry-name >
< env-entry-type > java.lang.String </ env-entry-type >
</ env-entry >
< mime-mapping >
< extension > wsdl </ extension >
< mime-type > text/xml </ mime-type >
</ mime-mapping >
</ web-app >