博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
struts2 集成webservice 的方法
阅读量:5838 次
发布时间:2019-06-18

本文共 19332 字,大约阅读时间需要 64 分钟。

由于项目需求的需要,要在原来用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
  • *

    *
*

*

IMPORTANT: this filter must be mapped to all requests. Unless you know exactly what you are doing, always * map to this URL pattern: /* *

*

Executing actions *

*

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, the rest of the filter chain is stopped and the action is * invoked. This is important, as it means that filters like the SiteMesh filter must be placed before this * filter or they will not be able to decorate the output of actions. *

*

Cleaning up the {
@link ActionContext}
*

*

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. *

*

Serving static content *

*

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: *

*
    *

    *
  • org.apache.struts2.static
  • *

    *
  • template
  • *

    *
*

*

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". Be * careful, however, to expose any packages that may have sensitive information, such as properties file with * database access credentials. *

*

*

*

*

* 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.
  • *

    *
*

*
*

*

*

* To use a custom {
@link Dispatcher}, the 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
params = new HashMap
(); 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. *

* 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. *

* 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. *

* Otherwise, if the request is for a static resource, * the resource is copied directly to the response, with the appropriate caching headers set. *

* 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); } } } }}
View Code

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);            }        }     }    }
你可能感兴趣的文章
我的2014-相对奢侈的生活
查看>>
Java设计模式
查看>>
华为OJ 名字美丽度
查看>>
mysql-This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决
查看>>
基本概念复习
查看>>
通过Roslyn构建自己的C#脚本(更新版)(转)
查看>>
红黑树
查看>>
【数据库】
查看>>
WindowManager.LayoutParams 详解
查看>>
Android的Aidl安装方法
查看>>
Linux中rc的含义
查看>>
安卓中数据库的搭建与使用
查看>>
AT3908 Two Integers
查看>>
.NET 设计规范--.NET约定、惯用法与模式-2.框架设计基础
查看>>
win7 64位+Oracle 11g 64位下使用 PL/SQL Developer 的解决办法
查看>>
sql 内联,左联,右联,全联
查看>>
C++关于字符串的处理
查看>>
Breaking parallel loops in .NET C# using the Stop method z
查看>>
[轉]redis;mongodb;memcache三者的性能比較
查看>>
让你的WPF程序在Win7下呈现Win8风格主题
查看>>