struts2 集成webservice 的方法
由于項目需求的需要,要在原來用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.那就放行,代碼如下所示:
1.如果在struts2.13之前,可以用以下方法。
在web.xml里面加入了struts2的過濾類:
所以,我們要重寫這個類,可以在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*/@Injectpublic void setStaticResourceLoader(StaticContentLoader staticResourceLoader) {this.staticResourceLoader = staticResourceLoader;}/*** Modify ActionMapper instance.* @param mapper New instance*/@Injectpublic 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 invocationValueStack 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 herereturn;}dispatcher.serviceAction(request, response, servletContext, mapping);} finally {try {ActionContextCleanUp.cleanUp(req);} finally {UtilTimerStack.pop(timerKey);}}}} } View Code2.如果在struts2.13之后,一般不提倡再用org.Apache.struts2.FilterDispatcher,而是用org.Apache.struts2.ng.filter.StrutsPrepareAndExecuteFilter.
然后自己寫個過濾類,繼承StrutsPrepareAndExeuteFilter即可。重寫里面的doFilter方法。
web.xml里面的過濾器類片段
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);}}}}轉載于:https://www.cnblogs.com/longshiyVip/p/5014508.html
總結
以上是生活随笔為你收集整理的struts2 集成webservice 的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构之外部排序:失败树
- 下一篇: 计算机网络之物理层:7、物理层设备(中继