`
ssydxa219
  • 浏览: 609053 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

静态资源处理问题

 
阅读更多

package com.sean.filter;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class StaticResourceFilter implements Filter {

    private static final String RESOURCE_BAST_PATH = "resourceBastPath";
    private String basePath;

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
     FilterChain chain) throws IOException, ServletException {
 if (request instanceof HttpServletRequest) {
     HttpServletRequest req = (HttpServletRequest) request;
     String uri = req.getRequestURI();
     // find howto/xxx.swf request
     Pattern pattern = Pattern.compile("(howto/.+\\.swf$)");
     Matcher matcher = pattern.matcher(uri);
     if (matcher.find()) {
  String path = matcher.group(0);
  // Read data from disk and transmit to response.
  InputStream is = new FileInputStream(getBasePath() + "/" + path);
  int iValue = -1;
  while ((iValue = is.read()) != -1) {
      response.getOutputStream().write(iValue);
  }
  response.getOutputStream().flush();
  return;
     }
 }

 chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 setBasePath(filterConfig.getInitParameter(RESOURCE_BAST_PATH));
    }

    public String getBasePath() {
 return basePath;
    }

    public void setBasePath(String basePath) {
 this.basePath = basePath;
    }

}

 

<!-- Filter to deal with request for swf resources -->
 <filter>
  <filter-name>resourceFilter</filter-name>
  <filter-class>com.sean.filter.StaticResourceFilter</filter-class>
  <init-param>
   <param-name>resourceBastPath</param-name>
   <param-value>/var/www/xxapp/resource/flash</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>resourceFilter</filter-name>
  <!-- Filter all request -->
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 

 

<object classid="clsid:F08DF954-8592-11D1-B16A-00C0F0283628" id="Slider1"
width="100" height="50">
 <param name="BorderStyle" value="1" />
 <param name="MousePointer" value="0" />
 <param name="Enabled" value="1" />
 <param name="Min" value="0" />
 <param name="Max" value="10"/>
 <param name="src" value="howto/help.swf"/>
 </object>

 

struts2.1.8 StrutsPrepareAndExecuteFilter 关于静态资源处理问题

 <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();
        }
    }

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics