struts2 集成webservice 的方法
来源:互联网 发布:2017上海网络视听季 编辑:程序博客网 时间:2024/06/05 15:09
由于项目需求的需要,要在原来用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的过滤类:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
所以,我们要重写这个类,可以在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:
* <p/>
* <ul>
* <p/>
* <li>Executing actions</li>
* <p/>
* <li>Cleaning up the {@link ActionContext} (see note)</li>
* <p/>
* <li>Serving static content</li>
* <p/>
* <li>Kicking off XWork's interceptor chain for the request lifecycle</li>
* <p/>
* </ul>
* <p/>
* <p/> <b>IMPORTANT</b>: this filter must be mapped to all requests. Unless you know exactly what you are doing, always
* map to this URL pattern: /*
* <p/>
* <p/> <b>Executing actions</b>
* <p/>
* <p/> This filter executes actions by consulting the {@link ActionMapper} and determining if the requested URL should
* invoke an action. If the mapper indicates it should, <b>the rest of the filter chain is stopped</b> and the action is
* invoked. This is important, as it means that filters like the SiteMesh filter must be placed <b>before</b> this
* filter or they will not be able to decorate the output of actions.
* <p/>
* <p/> <b>Cleaning up the {@link ActionContext}</b>
* <p/>
* <p/> This filter will also automatically clean up the {@link ActionContext} for you, ensuring that no memory leaks
* take place. However, this can sometimes cause problems integrating with other products like SiteMesh. See {@link
* ActionContextCleanUp} for more information on how to deal with this.
* <p/>
* <p/> <b>Serving static content</b>
* <p/>
* <p/> This filter also serves common static content needed when using various parts of Struts, such as JavaScript
* files, CSS files, etc. It works by looking for requests to /struts/*, and then mapping the value after "/struts/"
* to common packages in Struts and, optionally, in your class path. By default, the following packages are
* automatically searched:
* <p/>
* <ul>
* <p/>
* <li>org.apache.struts2.static</li>
* <p/>
* <li>template</li>
* <p/>
* </ul>
* <p/>
* <p/> This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme's default stylesheet
* will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the
* org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma
* separated (space, tab and new line will do as well) list in the filter init parameter named "packages". <b>Be
* careful</b>, however, to expose any packages that may have sensitive information, such as properties file with
* database access credentials.
* <p/>
* <p/>
* <p/>
* <p>
* <p/>
* This filter supports the following init-params:
* <!-- START SNIPPET: params -->
* <p/>
* <ul>
* <p/>
* <li><b>config</b> - a comma-delimited list of XML configuration files to load.</li>
* <p/>
* <li><b>actionPackages</b> - a comma-delimited list of Java packages to scan for Actions.</li>
* <p/>
* <li><b>configProviders</b> - a comma-delimited list of Java classes that implement the
* {@link ConfigurationProvider} interface that should be used for building the {@link Configuration}.</li>
* <p/>
* <li><b>loggerFactory</b> - The class name of the {@link LoggerFactory} implementation.</li>
* <p/>
* <li><b>*</b> - any other parameters are treated as framework constants.</li>
* <p/>
* </ul>
* <p/>
* <!-- END SNIPPET: params -->
* <p/>
* </p>
* <p/>
* To use a custom {@link Dispatcher}, the <code>createDispatcher()</code> 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<String, String> params = new HashMap<String, String>();
for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
String name = (String) e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
return new Dispatcher(filterConfig.getServletContext(), params);
}
/**
* Modify state of StrutsConstants.STRUTS_STATIC_CONTENT_LOADER setting.
* @param staticResourceLoader val New setting
*/
@Inject
public void setStaticResourceLoader(StaticContentLoader staticResourceLoader) {
this.staticResourceLoader = staticResourceLoader;
}
/**
* Modify ActionMapper instance.
* @param mapper New instance
*/
@Inject
public void setActionMapper(ActionMapper mapper) {
actionMapper = mapper;
}
/**
* Provide a workaround for some versions of WebLogic.
* <p/>
* Servlet 2.3 specifies that the servlet context can be retrieved from the session. Unfortunately, some versions of
* WebLogic can only retrieve the servlet context from the filter config. Hence, this method enables subclasses to
* retrieve the servlet context from other sources.
*
* @return the servlet context.
*/
protected ServletContext getServletContext() {
return filterConfig.getServletContext();
}
/**
* Expose the FilterConfig instance.
*
* @return Our FilterConfit instance
*/
protected FilterConfig getFilterConfig() {
return filterConfig;
}
/**
* Wrap and return the given request, if needed, so as to to transparently
* handle multipart data as a wrapped class around the given request.
*
* @param request Our ServletRequest object
* @param response Our ServerResponse object
* @return Wrapped HttpServletRequest object
* @throws ServletException on any error
*/
protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException {
Dispatcher du = Dispatcher.getInstance();
// Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be
// configured first before struts2 dispatcher filter, hence when its cleanup filter's turn,
// static instance of Dispatcher should be null.
if (du == null) {
Dispatcher.setInstance(dispatcher);
// prepare the request no matter what - this ensures that the proper character encoding
// is used before invoking the mapper (see WW-9127)
dispatcher.prepare(request, response);
} else {
dispatcher = du;
}
try {
// Wrap request first, just in case it is multipart/form-data
// parameters might not be accessible through before encoding (ww-1278)
request = dispatcher.wrapRequest(request, getServletContext());
} catch (IOException e) {
String message = "Could not wrap servlet request with MultipartRequestWrapper!";
log.error(message, e);
throw new ServletException(message, e);
}
return request;
}
/**
* Process an action or handle a request a static resource.
* <p/>
* The filter tries to match the request to an action mapping.
* If mapping is found, the action processes is delegated to the dispatcher's serviceAction method.
* If action processing fails, doFilter will try to create an error page via the dispatcher.
* <p/>
* Otherwise, if the request is for a static resource,
* the resource is copied directly to the response, with the appropriate caching headers set.
* <p/>
* If the request does not match an action mapping, or a static resource page,
* then it passes through.
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
//System.out.println(request.getRequestURI());
//System.out.println(request.getRequestURI().contains("services"));
if(request.getRequestURI().contains("services"))
{
chain.doFilter(req,res);
}
else
{
HttpServletResponse response = (HttpServletResponse) res;
ServletContext servletContext = getServletContext();
String timerKey = "FilterDispatcher_doFilter: ";
try {
// FIXME: this should be refactored better to not duplicate work with the action invocation
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
ActionContext ctx = new ActionContext(stack.getContext());
ActionContext.setContext(ctx);
UtilTimerStack.push(timerKey);
request = prepareDispatcherAndWrapRequest(request, response);
ActionMapping mapping;
try {
mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());
} catch (Exception ex) {
log.error("error getting ActionMapping", ex);
dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
return;
}
if (mapping == null) {
// there is no action in this request, should we look for a static resource?
String resourcePath = RequestUtils.getServletPath(request);
if ("".equals(resourcePath) && null != request.getPathInfo()) {
resourcePath = request.getPathInfo();
}
if (staticResourceLoader.canHandle(resourcePath)) {
staticResourceLoader.findStaticResource(resourcePath, request, response);
} else {
// this is a normal request, let it pass through
chain.doFilter(request, response);
}
// The framework did its job here
return;
}
dispatcher.serviceAction(request, response, servletContext, mapping);
} finally {
try {
ActionContextCleanUp.cleanUp(req);
} finally {
UtilTimerStack.pop(timerKey);
}
}
}
}
}
2.如果在struts2.13之后,一般不提倡再用org.Apache.struts2.FilterDispatcher,而是用org.Apache.struts2.ng.filter.StrutsPrepareAndExecuteFilter.
然后自己写个过滤类,继承StrutsPrepareAndExeuteFilter即可。重写里面的doFilter方法。
web.xml里面的过滤器类片段
<filter>
<filter-name>struts2</filter-name>
<filter-class>Myfilter.MyFilter</filter-class>
</filter>
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);
}
}
}
}
方式一: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的过滤类:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
所以,我们要重写这个类,可以在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:
* <p/>
* <ul>
* <p/>
* <li>Executing actions</li>
* <p/>
* <li>Cleaning up the {@link ActionContext} (see note)</li>
* <p/>
* <li>Serving static content</li>
* <p/>
* <li>Kicking off XWork's interceptor chain for the request lifecycle</li>
* <p/>
* </ul>
* <p/>
* <p/> <b>IMPORTANT</b>: this filter must be mapped to all requests. Unless you know exactly what you are doing, always
* map to this URL pattern: /*
* <p/>
* <p/> <b>Executing actions</b>
* <p/>
* <p/> This filter executes actions by consulting the {@link ActionMapper} and determining if the requested URL should
* invoke an action. If the mapper indicates it should, <b>the rest of the filter chain is stopped</b> and the action is
* invoked. This is important, as it means that filters like the SiteMesh filter must be placed <b>before</b> this
* filter or they will not be able to decorate the output of actions.
* <p/>
* <p/> <b>Cleaning up the {@link ActionContext}</b>
* <p/>
* <p/> This filter will also automatically clean up the {@link ActionContext} for you, ensuring that no memory leaks
* take place. However, this can sometimes cause problems integrating with other products like SiteMesh. See {@link
* ActionContextCleanUp} for more information on how to deal with this.
* <p/>
* <p/> <b>Serving static content</b>
* <p/>
* <p/> This filter also serves common static content needed when using various parts of Struts, such as JavaScript
* files, CSS files, etc. It works by looking for requests to /struts/*, and then mapping the value after "/struts/"
* to common packages in Struts and, optionally, in your class path. By default, the following packages are
* automatically searched:
* <p/>
* <ul>
* <p/>
* <li>org.apache.struts2.static</li>
* <p/>
* <li>template</li>
* <p/>
* </ul>
* <p/>
* <p/> This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme's default stylesheet
* will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the
* org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma
* separated (space, tab and new line will do as well) list in the filter init parameter named "packages". <b>Be
* careful</b>, however, to expose any packages that may have sensitive information, such as properties file with
* database access credentials.
* <p/>
* <p/>
* <p/>
* <p>
* <p/>
* This filter supports the following init-params:
* <!-- START SNIPPET: params -->
* <p/>
* <ul>
* <p/>
* <li><b>config</b> - a comma-delimited list of XML configuration files to load.</li>
* <p/>
* <li><b>actionPackages</b> - a comma-delimited list of Java packages to scan for Actions.</li>
* <p/>
* <li><b>configProviders</b> - a comma-delimited list of Java classes that implement the
* {@link ConfigurationProvider} interface that should be used for building the {@link Configuration}.</li>
* <p/>
* <li><b>loggerFactory</b> - The class name of the {@link LoggerFactory} implementation.</li>
* <p/>
* <li><b>*</b> - any other parameters are treated as framework constants.</li>
* <p/>
* </ul>
* <p/>
* <!-- END SNIPPET: params -->
* <p/>
* </p>
* <p/>
* To use a custom {@link Dispatcher}, the <code>createDispatcher()</code> 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<String, String> params = new HashMap<String, String>();
for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
String name = (String) e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
return new Dispatcher(filterConfig.getServletContext(), params);
}
/**
* Modify state of StrutsConstants.STRUTS_STATIC_CONTENT_LOADER setting.
* @param staticResourceLoader val New setting
*/
@Inject
public void setStaticResourceLoader(StaticContentLoader staticResourceLoader) {
this.staticResourceLoader = staticResourceLoader;
}
/**
* Modify ActionMapper instance.
* @param mapper New instance
*/
@Inject
public void setActionMapper(ActionMapper mapper) {
actionMapper = mapper;
}
/**
* Provide a workaround for some versions of WebLogic.
* <p/>
* Servlet 2.3 specifies that the servlet context can be retrieved from the session. Unfortunately, some versions of
* WebLogic can only retrieve the servlet context from the filter config. Hence, this method enables subclasses to
* retrieve the servlet context from other sources.
*
* @return the servlet context.
*/
protected ServletContext getServletContext() {
return filterConfig.getServletContext();
}
/**
* Expose the FilterConfig instance.
*
* @return Our FilterConfit instance
*/
protected FilterConfig getFilterConfig() {
return filterConfig;
}
/**
* Wrap and return the given request, if needed, so as to to transparently
* handle multipart data as a wrapped class around the given request.
*
* @param request Our ServletRequest object
* @param response Our ServerResponse object
* @return Wrapped HttpServletRequest object
* @throws ServletException on any error
*/
protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException {
Dispatcher du = Dispatcher.getInstance();
// Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be
// configured first before struts2 dispatcher filter, hence when its cleanup filter's turn,
// static instance of Dispatcher should be null.
if (du == null) {
Dispatcher.setInstance(dispatcher);
// prepare the request no matter what - this ensures that the proper character encoding
// is used before invoking the mapper (see WW-9127)
dispatcher.prepare(request, response);
} else {
dispatcher = du;
}
try {
// Wrap request first, just in case it is multipart/form-data
// parameters might not be accessible through before encoding (ww-1278)
request = dispatcher.wrapRequest(request, getServletContext());
} catch (IOException e) {
String message = "Could not wrap servlet request with MultipartRequestWrapper!";
log.error(message, e);
throw new ServletException(message, e);
}
return request;
}
/**
* Process an action or handle a request a static resource.
* <p/>
* The filter tries to match the request to an action mapping.
* If mapping is found, the action processes is delegated to the dispatcher's serviceAction method.
* If action processing fails, doFilter will try to create an error page via the dispatcher.
* <p/>
* Otherwise, if the request is for a static resource,
* the resource is copied directly to the response, with the appropriate caching headers set.
* <p/>
* If the request does not match an action mapping, or a static resource page,
* then it passes through.
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
//System.out.println(request.getRequestURI());
//System.out.println(request.getRequestURI().contains("services"));
if(request.getRequestURI().contains("services"))
{
chain.doFilter(req,res);
}
else
{
HttpServletResponse response = (HttpServletResponse) res;
ServletContext servletContext = getServletContext();
String timerKey = "FilterDispatcher_doFilter: ";
try {
// FIXME: this should be refactored better to not duplicate work with the action invocation
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
ActionContext ctx = new ActionContext(stack.getContext());
ActionContext.setContext(ctx);
UtilTimerStack.push(timerKey);
request = prepareDispatcherAndWrapRequest(request, response);
ActionMapping mapping;
try {
mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());
} catch (Exception ex) {
log.error("error getting ActionMapping", ex);
dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
return;
}
if (mapping == null) {
// there is no action in this request, should we look for a static resource?
String resourcePath = RequestUtils.getServletPath(request);
if ("".equals(resourcePath) && null != request.getPathInfo()) {
resourcePath = request.getPathInfo();
}
if (staticResourceLoader.canHandle(resourcePath)) {
staticResourceLoader.findStaticResource(resourcePath, request, response);
} else {
// this is a normal request, let it pass through
chain.doFilter(request, response);
}
// The framework did its job here
return;
}
dispatcher.serviceAction(request, response, servletContext, mapping);
} finally {
try {
ActionContextCleanUp.cleanUp(req);
} finally {
UtilTimerStack.pop(timerKey);
}
}
}
}
}
2.如果在struts2.13之后,一般不提倡再用org.Apache.struts2.FilterDispatcher,而是用org.Apache.struts2.ng.filter.StrutsPrepareAndExecuteFilter.
然后自己写个过滤类,继承StrutsPrepareAndExeuteFilter即可。重写里面的doFilter方法。
web.xml里面的过滤器类片段
<filter>
<filter-name>struts2</filter-name>
<filter-class>Myfilter.MyFilter</filter-class>
</filter>
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);
}
}
}
}
- struts2 集成webservice 的方法
- 常用的webservice客户端和spring集成的方法
- AXIS2的WEBSERVICE集成
- webservice客户端和spring集成的常用方法
- Struts2集成spring3后action的几种实例方法
- webservice与spring的集成
- CXF集成SPRING的WEBSERVICE
- 几种常用的webservice客户端和spring集成的方法
- 几种常用的webservice客户端和spring集成的方法
- 几种常用的webservice客户端和spring集成的方法
- spring+hibernate+struts2的集成
- struts2 与 spring 的集成
- Struts2集成JSON的方案
- Struts2 与 Spring 的集成
- Struts2与URLRewrite的集成
- Struts2+JQuery+JSON的集成
- struts2和json的集成
- Struts2 与 Spring 的集成
- Popup-Fenster mit JavaScript
- 枚举enum的用途浅例
- 分享一个类似于MFC的字符串类
- ASP.NET基础(2)
- 数组集合,相信总有你分不清楚的
- struts2 集成webservice 的方法
- php xdebug 调试
- 函数调用方式的区别[thiscall,__cdecl,__stdcall]
- 存储过程
- Intent的一个用处
- ASP.NET控件
- HDU 4016 搜索
- 一个安慰就够了
- 存储过程的应用