1.struts2和dwr為什么會(huì)沖突?
最近很多同學(xué)都在問(wèn)同樣一個(gè)問(wèn)題,struts2和dwr該如何共存?我們先分析一下為什么會(huì)出現(xiàn)沖突.
struts2通過(guò)StrutsPrepareAndExecuteFilter過(guò)濾器來(lái)處理請(qǐng)求,常見(jiàn)的配置如下:
<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>
問(wèn)題就在這里,<url-pattern>/*</url-pattern>配置過(guò)濾了所有的請(qǐng)求,當(dāng)用戶提交的請(qǐng)求是/dwr/*時(shí),也同樣被StrutsPrepareAndExecuteFilter處理了,根本達(dá)不到DWR框架,這就是為什么二者不能共存的原因.
2.通過(guò)struts2源碼發(fā)現(xiàn)問(wèn)題
網(wǎng)上我沒(méi)找到問(wèn)題的解決方案,所以,只能通過(guò)閱讀源代碼來(lái)查找問(wèn)題的根源了.在StrutsPrepareAndExecuteFilter類(lèi)中,重寫(xiě)了doFilter方法:
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);
}
}
注意看粗體部分,如果excludedPatterns不為null且prepare.isUrlExcluded方法的返回值為true,則該請(qǐng)求不交給struts框架處理,那么,sUrlExcluded是如何定義的呢?我們跟蹤找到下面的代碼:
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;
}
我們看到, isUrlExcluded 方法中 excludedPatterns參數(shù)是一個(gè)List集合, String uri = getUri(request);代碼獲取請(qǐng)求路徑,然后通過(guò)一個(gè)for循環(huán)將請(qǐng)求路徑與 excludedPatterns進(jìn)行匹(,注意,這里是通過(guò)正則表達(dá)式進(jìn)行匹配的),如果匹配成功,則返回true,否則返回false.
那么, excludedPatterns的值從哪里來(lái)呢?下面的代碼是也:
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;
}
}
看了上面的代碼,是不是豁然開(kāi)朗?原來(lái), StrutsConstants.STRUTS_ACTION_EXCLUDE_PATTERN常量保存了不由struts2處理的路徑,我們?cè)趕truts2.properties中配置即可.
struts.action.excludePattern=/dwr/.*,/dwr/test/.*