zoukankan      html  css  js  c++  java
  • 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.那就放行,代码如下所示:

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

    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);
                }
            }
         }
    
        
    }
  • 相关阅读:
    Java基础之集合Collection一:
    Java基础之字符串String:
    Java基础之Map学习代码示例二:
    Jav基础之字符串缓冲区StringBuffer:
    Java基础之TreeSet集合使用泛型、比较器排序示例:
    Java基础之Map学习代码示例一:
    Java基础之StringBuilder
    Java基础之泛型限定的使用示例:
    Java基础之泛型的应用
    spark.primitives 包中的几个基本类
  • 原文地址:https://www.cnblogs.com/longshiyVip/p/5014508.html
Copyright © 2011-2022 走看看