由于项目需求的需要,要在原来用Struts2的框架之上集成webservice,因为之前单单做webservice的时候没有多大问题,使用 Spring 和 Xfire就可以轻松地发布服务,但是,当和Struts2集成的时候问题确出现了。因为原来在web.xml中,struts2过滤了/*,即把根目录 下得所有目录都进行了过滤,而webservice的目录我定义为/services/*,这样一来,客户端访问该web服务的时候就被strust2过 滤器当成无效链接过滤了。
问题找到了,所以解决办法也很容易找到,有下面两种方式:
方式一:struts2不要过滤根目录下所有的文件目录,可以用/*.action,/*.do,/*.jsp的形式等等。或者在链接action的时候创立一个命名空间如my,然后struts2就只过滤my/*,这样就不会影响service/*的东西了。 方式二:感谢http://blog.csdn.net/lishengbo/article/details/5474044 提供的思路,修改struts2 dispatcher的内容,因为dispatcher里面有个方式dofilter,他得功能是把过滤请求传递给下面一个过滤器,这样就把当前的请求放 行了。所以可以在dofilter里面做下处理,如果请求的链接种包含了service.那就放行,代码如下所示:if(request.getRequestURI().contains("services")) { chain.doFilter(req,res); }
1.如果在struts2.13之前,可以用以下方法。
在web.xml里面加入了struts2的过滤类:struts2 org.apache.struts2.dispatcher.FilterDispatcher
所以,我们要重写这个类,可以在src下建立一个org.apache.struts2.dispatcher.FilterDispatcher类,或者自己指定一个位置,然后在web.xml中修改下对应的struts2的对应类即可。
我采用了方式二解决了问题。因为struts2监听所有的请求比较好,只对一些有要求的请求才放行。修改后的FilterDispatcher.java的源代码如下:
/* * $Id: FilterDispatcher.java 674498 2008-07-07 14:10:42Z mrdon $ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */package org.apache.struts2.dispatcher;import java.io.IOException;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts2.RequestUtils;import org.apache.struts2.StrutsStatics;import org.apache.struts2.dispatcher.mapper.ActionMapper;import org.apache.struts2.dispatcher.mapper.ActionMapping;import org.apache.struts2.dispatcher.ng.filter.FilterHostConfig;import org.apache.struts2.util.ClassLoaderUtils;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.config.Configuration;import com.opensymphony.xwork2.config.ConfigurationProvider;import com.opensymphony.xwork2.inject.Inject;import com.opensymphony.xwork2.util.ValueStack;import com.opensymphony.xwork2.util.ValueStackFactory;import com.opensymphony.xwork2.util.logging.Logger;import com.opensymphony.xwork2.util.logging.LoggerFactory;import com.opensymphony.xwork2.util.profiling.UtilTimerStack;/** * Master filter for Struts that handles four distinct * responsibilities: * *
- * *
- Executing actions * *
- Cleaning up the { @link ActionContext} (see note) * *
- Serving static content * *
- Kicking off XWork's interceptor chain for the request lifecycle * *
- * *
- org.apache.struts2.static * *
- template * *
*
* This filter supports the following init-params: * * *- * *
- config - a comma-delimited list of XML configuration files to load. * *
- actionPackages - a comma-delimited list of Java packages to scan for Actions. * *
- configProviders - a comma-delimited list of Java classes that implement the * { @link ConfigurationProvider} interface that should be used for building the { @link Configuration}. * *
- loggerFactory - The class name of the { @link LoggerFactory} implementation. * *
- * - any other parameters are treated as framework constants. * *
createDispatcher()
method could be overriden by * the subclass. * * @version $Date: 2008-07-07 22:10:42 +0800 (星期一, 07 七月 2008) $ $Id: FilterDispatcher.java 674498 2008-07-07 14:10:42Z mrdon $ * @deprecated Since Struts 2.1.3, use { @link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter} instead or * { @link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter} and { @link org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter} * if needing using the { @link ActionContextCleanUp} filter in addition to this one * * @see ActionMapper * @see ActionContextCleanUp * @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter * @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter * @see org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter */public class FilterDispatcher implements StrutsStatics, Filter { /** * Provide a logging instance. */ private Logger log; /** * Provide ActionMapper instance, set by injection. */ private ActionMapper actionMapper; /** * Provide FilterConfig instance, set on init. */ private FilterConfig filterConfig; /** * Expose Dispatcher instance to subclass. */ protected Dispatcher dispatcher; /** * Loads stattic resources, set by injection */ protected StaticContentLoader staticResourceLoader; /** * Initializes the filter by creating a default dispatcher * and setting the default packages for static resources. * * @param filterConfig The filter configuration */ public void init(FilterConfig filterConfig) throws ServletException { try { this.filterConfig = filterConfig; initLogging(); dispatcher = createDispatcher(filterConfig); dispatcher.init(); dispatcher.getContainer().inject(this); staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig)); } finally { ActionContext.setContext(null); } } private void initLogging() { String factoryName = filterConfig.getInitParameter("loggerFactory"); if (factoryName != null) { try { Class cls = ClassLoaderUtils.loadClass(factoryName, this.getClass()); LoggerFactory fac = (LoggerFactory) cls.newInstance(); LoggerFactory.setLoggerFactory(fac); } catch (InstantiationException e) { System.err.println("Unable to instantiate logger factory: " + factoryName + ", using default"); e.printStackTrace(); } catch (IllegalAccessException e) { System.err.println("Unable to access logger factory: " + factoryName + ", using default"); e.printStackTrace(); } catch (ClassNotFoundException e) { System.err.println("Unable to locate logger factory class: " + factoryName + ", using default"); e.printStackTrace(); } } log = LoggerFactory.getLogger(FilterDispatcher.class); } /** * Calls dispatcher.cleanup, * which in turn releases local threads and destroys any DispatchListeners. * * @see javax.servlet.Filter#destroy() */ public void destroy() { if (dispatcher == null) { log.warn("something is seriously wrong, Dispatcher is not initialized (null) "); } else { try { dispatcher.cleanup(); } finally { ActionContext.setContext(null); } } } /** * Create a default { @link Dispatcher} that subclasses can override * with a custom Dispatcher, if needed. * * @param filterConfig Our FilterConfig * @return Initialized Dispatcher */ protected Dispatcher createDispatcher(FilterConfig filterConfig) { Map 2.如果在struts2.13之后,一般不提倡再用org.Apache.struts2.FilterDispatcher,而是用org.Apache.struts2.ng.filter.StrutsPrepareAndExecuteFilter.
然后自己写个过滤类,继承StrutsPrepareAndExeuteFilter即可。重写里面的doFilter方法。
web.xml里面的过滤器类片段struts2 Myfilter.MyFilter
MyFilter.java源代码
package Myfilter;import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;import org.apache.struts2.dispatcher.mapper.ActionMapping;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class MyFilter extends StrutsPrepareAndExecuteFilter{ //修改struts2 默认的过滤器 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; System.out.println(request.getRequestURI()); System.out.println(request.getRequestURI().contains("services")); if(request.getRequestURI().contains("services")) //如果是访问webservice 这不进行过滤 { chain.doFilter(req,res); } else{ 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); } } } }