【问题标题】:Issue with consuming JAX-RPC service from a JAX-WS CXF framework从 JAX-WS CXF 框架使用 JAX-RPC 服务的问题
【发布时间】:2012-07-08 03:36:48
【问题描述】:

您能否建议我是否可以在 JAX-RPC 中使用 WSDL with DII 概念,并在 CXF2.6(不支持 JAX-RPC)框架中编写一个方法来使用 JAX- RPC 服务? 您是否看到与这种方法的任何类加载问题或 jar 冲突?

CXF 管道是否支持这样的调用?

原因是我们的供应商仍然使用 JAX-RPC,并且我们在 JAX-WS 框架上运行。 我们无法控制托管供应商的实施。

Saludos 卡西克

【问题讨论】:

    标签: web-services jax-ws cxf jax-rpc


    【解决方案1】:

    你可以试试这个从 CXF 中改编而来的 DynamicClientFactory。这将允许您调用 RPC/Encoded Web Service。

    代码:

    拨打电话:

    DynamicClientFactory dcf = DynamicClientFactory.newInstance();
    org.apache.cxf.endpoint.Client client = dcf.createClient(url); //URL of WSDL
    Object[] response = client.invoke(...);
    

    DynamicClientFactory.java

    package ar.com.nextel.nxsgst.daemon.core;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.StringTokenizer;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.namespace.QName;
    
    import org.apache.cxf.Bus;
    import org.apache.cxf.bus.CXFBusFactory;
    import org.apache.cxf.common.i18n.Message;
    import org.apache.cxf.common.logging.LogUtils;
    import org.apache.cxf.common.util.StringUtils;
    import org.apache.cxf.endpoint.Client;
    import org.apache.cxf.endpoint.ClientImpl;
    import org.apache.cxf.endpoint.EndpointImplFactory;
    import org.apache.cxf.endpoint.SimpleEndpointImplFactory;
    import org.apache.cxf.endpoint.dynamic.TypeClassInitializer;
    import org.apache.cxf.jaxb.JAXBDataBinding;
    import org.apache.cxf.resource.URIResolver;
    import org.apache.cxf.service.Service;
    import org.apache.cxf.service.factory.ServiceConstructionException;
    import org.apache.cxf.service.model.SchemaInfo;
    import org.apache.cxf.service.model.ServiceInfo;
    import org.w3c.dom.Element;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXParseException;
    
    import com.sun.codemodel.JCodeModel;
    import com.sun.codemodel.JDefinedClass;
    import com.sun.codemodel.JPackage;
    import com.sun.tools.xjc.Options;
    import com.sun.tools.xjc.api.ErrorListener;
    import com.sun.tools.xjc.api.S2JJAXBModel;
    import com.sun.tools.xjc.api.SchemaCompiler;
    import com.sun.tools.xjc.api.XJC;
    
    public class DynamicClientFactory {
    
        private static final Logger LOG = LogUtils.getL7dLogger(DynamicClientFactory.class);
    
        private Bus bus;
    
        private boolean simpleBindingEnabled = true;
    
        private Map<String, Object> jaxbContextProperties;
    
        protected DynamicClientFactory(Bus bus) {
            this.bus = bus;
        }
    
        protected EndpointImplFactory getEndpointImplFactory() {
            return SimpleEndpointImplFactory.getSingleton();
        }
    
        /**
         * Create a new instance using a specific <tt>Bus</tt>.
         * 
         * @param b the <tt>Bus</tt> to use in subsequent operations with the
         *            instance
         * @return the new instance
         */
        public static DynamicClientFactory newInstance(Bus b) {
            return new DynamicClientFactory(b);
        }
    
        /**
         * Create a new instance using a default <tt>Bus</tt>.
         * 
         * @return the new instance
         * @see CXFBusFactory#getDefaultBus()
         */
        public static DynamicClientFactory newInstance() {
            Bus bus = CXFBusFactory.getThreadDefaultBus();
            return new DynamicClientFactory(bus);
        }
    
        /**
         * Create a new <code>Client</code> instance using the WSDL to be loaded
         * from the specified URL and using the current classloading context.
         * 
         * @param wsdlURL the URL to load
         * @return
         */
        public Client createClient(String wsdlUrl) {
            return createClient(wsdlUrl, (QName)null, (QName)null);
        }
    
        /**
         * Create a new <code>Client</code> instance using the WSDL to be loaded
         * from the specified URL and with the specified <code>ClassLoader</code>
         * as parent.
         * 
         * @param wsdlUrl
         * @param classLoader
         * @return
         */
        public Client createClient(String wsdlUrl, ClassLoader classLoader) {
            return createClient(wsdlUrl, null, classLoader, null);
        }
    
        public Client createClient(String wsdlUrl, QName service) {
            return createClient(wsdlUrl, service, null);
        }
    
        public Client createClient(String wsdlUrl, QName service, QName port) {
            return createClient(wsdlUrl, service, null, port);
        }
    
        public Client createClient(String wsdlUrl, QName service, ClassLoader classLoader, QName port) {
            if (classLoader == null) {
                classLoader = Thread.currentThread().getContextClassLoader();
            }
            URL u = composeUrl(wsdlUrl);
            LOG.log(Level.FINE, "Creating client from URL " + u.toString());
            ClientImpl client = new ClientImpl(bus, u, service, port,
                                               getEndpointImplFactory());
    
            Service svc = client.getEndpoint().getService();
            //all SI's should have the same schemas
            Collection<SchemaInfo> schemas = svc.getServiceInfos().get(0).getSchemas();
    
            SchemaCompiler compiler = XJC.createSchemaCompiler();
            ErrorListener elForRun = new InnerErrorListener(wsdlUrl);
            compiler.setErrorListener(elForRun);
    
            addSchemas(wsdlUrl, schemas, compiler);
    
            S2JJAXBModel intermediateModel = compiler.bind();
            JCodeModel codeModel = intermediateModel.generateCode(null, elForRun);
            StringBuilder sb = new StringBuilder();
            boolean firstnt = false;
    
            for (Iterator<JPackage> packages = codeModel.packages(); packages.hasNext();) {
                JPackage jpackage = packages.next();
                if (!isValidPackage(jpackage)) {
                    continue;
                }
                if (firstnt) {
                    sb.append(':');
                } else {
                    firstnt = true;
                }
                sb.append(jpackage.name());
            }
            outputDebug(codeModel);
    
            String packageList = sb.toString();
    
            JAXBContext context = null;
            Map<String, Object> contextProperties = jaxbContextProperties;
    
            if (contextProperties == null) {
                contextProperties = Collections.emptyMap();
            }
    
            try {
                if (StringUtils.isEmpty(packageList)) {
                    context = JAXBContext.newInstance(new Class[0], contextProperties);
                } 
            } catch (JAXBException jbe) {
                throw new IllegalStateException("Unable to create JAXBContext for generated packages: "
                                                + jbe.getMessage(), jbe);
            }
    
            JAXBDataBinding databinding = new JAXBDataBinding();
            databinding.setContext(context);
            svc.setDataBinding(databinding);
    
            ServiceInfo svcfo = client.getEndpoint().getEndpointInfo().getService();
    
    
            TypeClassInitializer visitor = new TypeClassInitializer(svcfo, intermediateModel);
            visitor.walk();
    
            return client;
        }
    
        private boolean isValidPackage(JPackage jpackage) {
            if (jpackage == null) {
                return false;
            }
            String name = jpackage.name();
            if ("org.w3._2001.xmlschema".equals(name)
                || "java.lang".equals(name)
                || "java.io".equals(name)
                || "generated".equals(name)) {
                return false;
            }
            Iterator<JDefinedClass> i = jpackage.classes();
            while (i.hasNext()) {
                JDefinedClass current = i.next();
                if ("ObjectFactory".equals(current.name())) { 
                    return true;
                }
            }
            return false;
        }
    
        private void outputDebug(JCodeModel codeModel) {
            if (!LOG.isLoggable(Level.INFO)) {
                return;
            }
    
            StringBuffer sb = new StringBuffer();
            boolean first = true;
            for (Iterator<JPackage> itr = codeModel.packages(); itr.hasNext();) {
                JPackage package1 = itr.next();
    
                for (Iterator<JDefinedClass> citr = package1.classes(); citr.hasNext();) {
                    if (!first) {
                        sb.append(", ");
                    } else {
                        first = false;
                    }
                    sb.append(citr.next().fullName());
                }
            }
    
    //        LOG.log(Level.INFO, "Created classes: " + sb.toString());
    
        }
    
        private void addSchemas(String wsdlUrl, Collection<SchemaInfo> schemas, SchemaCompiler compiler) {
            int num = 1;
            for (SchemaInfo schema : schemas) {
                Element el = schema.getElement();
    
                compiler.parseSchema(wsdlUrl + "#types" + num, el);
                num++;
            }
    
            if (simpleBindingEnabled && isJaxb21()) {
                String id = "/org/apache/cxf/endpoint/dynamic/simple-binding.xjb";
                LOG.info("Loading the JAXB 2.1 simple binding for client.");
                InputSource source = new InputSource(getClass().getResourceAsStream(id));
                source.setSystemId(id);
                compiler.parseSchema(source);
            }
        }
    
        private boolean isJaxb21() {
            String id = Options.getBuildID();
            StringTokenizer st = new StringTokenizer(id, ".");
            String minor = null;
    
            // major version
            if (st.hasMoreTokens()) {
                st.nextToken();
            }
    
            if (st.hasMoreTokens()) {
                minor = st.nextToken();
            }
    
            try {
                int i = Integer.valueOf(minor);
                if (i >= 1) {
                    return true;
                }
            } catch (NumberFormatException e) {
                // do nothing;
            }
    
            return false;
        }
    
        public boolean isSimpleBindingEnabled() {
            return simpleBindingEnabled;
        }
    
        public void setSimpleBindingEnabled(boolean simpleBindingEnabled) {
            this.simpleBindingEnabled = simpleBindingEnabled;
        }
    
    
    
        private URL composeUrl(String s) {
            try {
                URIResolver resolver = new URIResolver(null, s, getClass());
    
                if (!resolver.isResolved()) 
                    throw new ServiceConstructionException(new Message("COULD_NOT_RESOLVE_URL", LOG, s));
    
                return resolver.getURI().toURL();            
            } catch (IOException e) {
                throw new ServiceConstructionException(new Message("COULD_NOT_RESOLVE_URL", LOG, s), e);
            }
        }
    
        private class InnerErrorListener implements ErrorListener {
    
            private String url;
    
            InnerErrorListener(String url) {
                this.url = url;
            }
    
            public void error(SAXParseException arg0) {
                throw new RuntimeException("Error compiling schema from WSDL at {" + url + "}: "
                                           + arg0.getMessage(), arg0);
            }
    
            public void fatalError(SAXParseException arg0) {
                throw new RuntimeException("Fatal error compiling schema from WSDL at {" + url + "}: "
                                           + arg0.getMessage(), arg0);
            }
    
            public void info(SAXParseException arg0) {
                // ignore
            }
    
            public void warning(SAXParseException arg0) {
                // ignore
            }
        }
    
        /**
         * Return the map of JAXB context properties used at the time that we create new contexts.
         * @return the map
         */
        public Map<String, Object> getJaxbContextProperties() {
            return jaxbContextProperties;
        }
    
        /**
         * Set the map of JAXB context properties used at the time that we create new contexts.
         * @param jaxbContextProperties
         */
        public void setJaxbContextProperties(Map<String, Object> jaxbContextProperties) {
            this.jaxbContextProperties = jaxbContextProperties;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 2016-08-23
      相关资源
      最近更新 更多