• cxf的一些使用说明


    /**
     * 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.cxf.transport.servlet;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.Method;
    import java.util.Collection;
    import java.util.Enumeration;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    
    import org.apache.cxf.Bus;
    import org.apache.cxf.BusFactory;
    import org.apache.cxf.common.util.ReflectionUtil;
    import org.apache.cxf.helpers.CastUtils;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.core.io.Resource;
    import org.springframework.web.context.support.WebApplicationContextUtils;
    import org.springframework.web.context.support.XmlWebApplicationContext;
    
    public class CXFServlet extends CXFNonSpringServlet
        implements ApplicationListener<ContextRefreshedEvent> {
        private static final long serialVersionUID = -5922443981969455305L;
        private boolean busCreated;
        private XmlWebApplicationContext createdContext; 
        
        public CXFServlet() {
        }
    
        @Override
        protected void loadBus(ServletConfig sc) {
            ApplicationContext wac = WebApplicationContextUtils.
                getWebApplicationContext(sc.getServletContext());
            
            if (wac instanceof AbstractApplicationContext) {
                addListener((AbstractApplicationContext)wac);
            }
            
            String configLocation = sc.getInitParameter("config-location");
            if (configLocation == null) {
                try {
                    InputStream is = sc.getServletContext().getResourceAsStream("/WEB-INF/cxf-servlet.xml");
                    if (is != null && is.available() > 0) {
                        is.close();
                        configLocation = "/WEB-INF/cxf-servlet.xml";
                    }
                } catch (Exception ex) {
                    //ignore
                }
            }
            if (configLocation != null) {
                wac = createSpringContext(wac, sc.getServletContext(), configLocation);
            }
            if (wac != null) {
                setBus((Bus)wac.getBean("cxf", Bus.class));
            } else {
                busCreated = true;
                setBus(BusFactory.newInstance().createBus());
            }
        }
    
        protected void addListener(AbstractApplicationContext wac) {
            try {
                //spring 2 vs spring 3 return type is different
                Method m = wac.getClass().getMethod("getApplicationListeners");
                Collection<Object> c = CastUtils.cast((Collection<?>)ReflectionUtil
                                                          .setAccessible(m).invoke(wac));
                c.add(this);
            } catch (Throwable t) {
                //ignore.
            }
        }
    
        /**
         * Try to create a spring application context from the config location.
         * Will first try to resolve the location using the servlet context.
         * If that does not work then the location is given as is to spring
         * 
         * @param ctx
         * @param sc
         * @param configLocation
         * @return
         */
        private ApplicationContext createSpringContext(ApplicationContext ctx,
                                                       final ServletContext sc,
                                                       String location) {
            XmlWebApplicationContext ctx2 = new XmlWebApplicationContext();
            createdContext = ctx2;
            ctx2.setServletConfig(new ServletConfig() {
                public String getServletName() {
                    return "CXF";
                }
                public ServletContext getServletContext() {
                    return sc;
                }
                public String getInitParameter(String name) {
                    return sc.getInitParameter(name);
                }
                public Enumeration<String> getInitParameterNames() {
                    return sc.getInitParameterNames();
                }
            });
            Resource r = ctx2.getResource(location);
            try {
                InputStream in = r.getInputStream();
                in.close();
            } catch (IOException e) {
                //ignore
                r = ctx2.getResource("classpath:" + location);
                try {
                    r.getInputStream().close();
                } catch (IOException e2) {
                    //ignore
                    r = null;
                }
            }
            try {
                if (r != null) {
                    location = r.getURL().toExternalForm();
                }
            } catch (IOException e) {
                //ignore
            }        
            if (ctx != null) {
                ctx2.setParent(ctx);
                String names[] = ctx.getBeanNamesForType(Bus.class);
                if (names == null || names.length == 0) {
                    ctx2.setConfigLocations(new String[] {"classpath:/META-INF/cxf/cxf.xml",
                                                          location});                
                } else {
                    ctx2.setConfigLocations(new String[] {location});                                
                }
            } else {
                ctx2.setConfigLocations(new String[] {"classpath:/META-INF/cxf/cxf.xml",
                                                      location});
                createdContext = ctx2;
            }
            ctx2.refresh();
            return ctx2;
        }
        public void destroyBus() {
            if (busCreated) {
                //if we created the Bus, we need to destroy it.  Otherwise, spring will handleit.
                getBus().shutdown(true);
                setBus(null);
            }
            if (createdContext != null) {
                createdContext.close();
            }
        }
    
        public void onApplicationEvent(ContextRefreshedEvent event) {
            destroy();
            setBus(null);
            try {
                init(getServletConfig());
            } catch (ServletException e) {
                throw new RuntimeException("Unable to reinitialize the CXFServlet", e);
            }
        }
    
    }
    View Code

    如果存在Web-INF/cxf-servlet.xml,或者在web.xml中配置的cxf Servlet节按中提供了config-location,那么cxf会自己创建一个spring容器,如果在web.xml中同时也使用spring的监听器创建容器

     <context-param>
      <param-name>contextConfigLocation</param-name> 
      <param-value>classpath*:conf/cxf-servlet.xml</param-value> 
      </context-param> 
     <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
      </listener>
    View Code

    那么cxf容器会作为子容器,就是系统中有2个spring容器。
    cxf自己创建容器时会加载classpath:/META-INF/cxf/cxf.xml这个就中的bug,如果系统只建立一个spring容器(Web-INF/下以及cxfServlet中不提供配置),那么需要自己在spring配置xml文件中通过资源导入classpath:/META-INF/cxf/cxf.xml 加载,或者将该配置放在web.xml的context-param 中

  • 相关阅读:
    Centos 7环境下配置MySQL 5.7读写分离
    Centos 7环境下安装配置MySQL 5.7
    Hadoop 2.8集群安装及配置记录
    ASP.NET Core 1.1版本之Hello word
    Hadoop版Helloworld之wordcount运行示例
    SSH配置免密登陆设置汇总
    最小安装模式下Centos7.*网卡启动配置
    骚扰式管理
    项目团队之分工协作
    利用微软AntiXss Library过滤输出字符,防止XSS攻击
  • 原文地址:https://www.cnblogs.com/wdfrog/p/3197385.html
Copyright © 2020-2023  润新知