Struts2與DWR在項目中的共存解決方案

1.struts2和dwr爲何會衝突?正則表達式

最近不少同窗都在問一樣一個問題,struts2和dwr該如何共存?咱們先分析一下爲何會出現衝突.apache

struts2經過StrutsPrepareAndExecuteFilter過濾器來處理請求,常見的配置以下:app

 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>框架

問題就在這裏,<url-pattern>/*</url-pattern>配置過濾了全部的請求,當用戶提交的請求是/dwr/*時,也一樣被StrutsPrepareAndExecuteFilter處理了,根本達不到DWR框架,這就是爲何兩者不能共存的緣由.post


2.經過struts2源碼發現問題ui

網上我沒找到問題的解決方案,因此,只能經過閱讀源代碼來查找問題的根源了.在StrutsPrepareAndExecuteFilter類中,重寫了doFilter方法:url

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
 
        try {
            prepare.setEncodingAndLocale(request, response);
            prepare.createActionContext(request, response);
            prepare.assignDispatcherToThread();
   if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
    chain.doFilter(request, response);
   } else {
    request = prepare.wrapRequest(request);
    ActionMapping mapping = prepare.findActionMapping(request, response, true);
    if (mapping == null) {
     boolean handled = execute.executeStaticResourceRequest(request, response);
     if (!handled) {
      chain.doFilter(request, response);
     }
    } else {
     execute.executeAction(request, response, mapping);
    }
   }
        } finally {
            prepare.cleanupRequest(request);
        }
    }spa

注意看粗體部分,若是excludedPatterns不爲null且prepare.isUrlExcluded方法的返回值爲true,則該請求不交給struts框架處理,那麼,sUrlExcluded是如何定義的呢?咱們跟蹤找到下面的代碼:token

    public boolean isUrlExcluded( HttpServletRequest request, List<Pattern> excludedPatterns ) {
        if (excludedPatterns != null) {
            String uri = getUri(request);
            for ( Pattern pattern : excludedPatterns ) {
                if (pattern.matcher(uri).matches()) {
                    return true;
                }
            }
        }
        return false;
    }get

咱們看到,  isUrlExcluded 方法中 excludedPatterns參數是一個List集合, String uri = getUri(request);代碼獲取請求路徑,而後經過一個for循環將請求路徑與 excludedPatterns進行匹(,注意,這裏是經過正則表達式進行匹配的),若是匹配成功,則返回true,不然返回false.

那麼, excludedPatterns的值從哪裏來呢?下面的代碼是也:

    public List<Pattern> buildExcludedPatternsList( Dispatcher dispatcher ) {
        return buildExcludedPatternsList(dispatcher.getContainer().getInstance(String.class, StrutsConstants.STRUTS_ACTION_EXCLUDE_PATTERN));
    }
           
    private List<Pattern> buildExcludedPatternsList( String patterns ) {
        if (null != patterns && patterns.trim().length() != 0) {
            List<Pattern> list = new ArrayList<Pattern>();
            String[] tokens = patterns.split(",");
            for ( String token : tokens ) {
                list.add(Pattern.compile(token.trim()));
            }
            return Collections.unmodifiableList(list);
        } else {
            return null;
        }
    }

看了上面的代碼,是否是豁然開朗?原來, StrutsConstants.STRUTS_ACTION_EXCLUDE_PATTERN常量保存了不禁struts2處理的路徑,咱們在struts2.properties中配置便可.

struts.action.excludePattern=/dwr/.*,/dwr/test/.*

相關文章
相關標籤/搜索