您的位置:首页 > 编程语言 > Java开发

struts2.1.8 StrutsPrepareAndExecuteFilter 关于静态资源处理问题。访问classPath下静态资源

2014-01-04 14:24 621 查看
在web.xml中作如下配置:

<filter>

<filter-name>struts2</filter-name>

<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

<init-param>

<param-name>packages</param-name>

<param-value>net.zdsoft.eis.template</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>*.action</url-pattern>

</filter-mapping> <filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>/static/*</url-pattern>

</filter-mapping>

用于处理静态资源(css、js、图片之类),启动后正常。但当修改了struts配置文件,并且struts.configuration.xml.reload=true时,再次加载静态资源时会出错如下错误:

java.lang.NullPointerException at org.apache.struts2.dispatcher.DefaultStaticContentLoader.findStaticResource(DefaultStaticContentLoader.java:164)

at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeStaticResourceRequest(ExecuteOperations.java:62)

at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:86)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

原因:重新加载配置文件时,静态资源的处理类DefaultStaticContentLoader的setHostConfig(HostConfig filterConfig)方法没调用,导致pathPrefixes为空。

解决方案:

1、继承StrutsPrepareOperations类,构造方法中传入参数FilterConfig。createActionContext方法中如果oldContext为空,则重新初始化静态资源配置。完整代码如下:

public class StrutsPrepareOperations extends PrepareOperations {

private ServletContext servletContext;

private Dispatcher dispatcher;

private FilterHostConfig config;

public StrutsPrepareOperations(ServletContext servletContext, Dispatcher dispatcher,

FilterConfig filterConfig) {

super(servletContext, dispatcher);

this.dispatcher = dispatcher;

this.servletContext = servletContext;

this.config = new FilterHostConfig(filterConfig);

}

// 重写doFilter,由于在struts配置文件重新加载后,静态资源有问题

/**

* Creates the action context and initializes the thread local

*/

public ActionContext createActionContext(HttpServletRequest request,

HttpServletResponse response) {

ActionContext ctx;

Integer counter = 1;

Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);

if (oldCounter != null) {

counter = oldCounter + 1;

}

ActionContext oldContext = ActionContext.getContext();

if (oldContext != null) {

// detected existing context, so we are probably in a forward

ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));

} else {

ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class)

.createValueStack();

stack.getContext().putAll(

dispatcher.createContextMap(request, response, null, servletContext));

ctx = new ActionContext(stack.getContext());

// add by zhaosf

StaticContentLoader staticResourceLoader = dispatcher.getContainer().getInstance(

StaticContentLoader.class);

staticResourceLoader.setHostConfig(config);

}

request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);

ActionContext.setContext(ctx);

return ctx;

}

2、继承org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter时,重写init方法,如下:

public class StrutsFilter extends StrutsPrepareAndExecuteFilter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

InitOperations init = new InitOperations();

try {

FilterHostConfig config = new FilterHostConfig(filterConfig);

init.initLogging(config);

Dispatcher dispatcher = init.initDispatcher(config);

init.initStaticContentLoader(config, dispatcher);

prepare = new StrutsPrepareOperations(filterConfig.getServletContext(), dispatcher,

filterConfig);

execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);

this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

postInit(dispatcher, filterConfig);

} finally {

init.cleanup();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: