Apache CXF前端应用(Frontend)

来源:互联网 发布:淘宝服务站加盟 编辑:程序博客网 时间:2024/05/18 03:46

Apache CXF的前端应用就是作为WebService的消费者,通过给客户端调用的服务.

ApacheCXF前端应用包括5种:

1.JAX-WS前端模式

2.JAX-RS前端模式

3.动态客户端技术

4.Provider/Dispatch服务前端模式

5.简单前端模式(Simple Frontend)

本篇文章包括的内容如下:

1.基于代码优先(Code First)的JAX-WS前端模式(这里简单略过,详情可以查阅Apache CXF 入门)

2.基于WSDL优先(WSDL First)的JAX-WS前端模式

3.简单前端模式(Simple Frontend)

4.Provider/Dispatch服务前端模式

5.CXF动态客户端技术

基于代码优先的Java First

这种前端方式在上一篇Apache CXF 入门中介绍了几种写法,主要是以先代码,后发布服务生产wsdl的形式.在这里就不再重复说明,若不了解的可以查阅Apache CXF 入门一文,相信能让你很容易理解此种方式的实际应用场景.

基于WSDL优先(WSDL First)的JAX-WS前端模式

这种WSDL优先的编程方式主要是通过已经存在的WSDL文档,然后通过CXF提供的wsdl2java工具生成相关的客户端和服务端的程序代码.

使用WSDL2java的用法:

wsdl2java -ant -impl -server -d <otuputdir> mywsdl.wsdl

-ant:此选项将生成ANT的构建文件build.xml,用于生成代码

-impl:此选项将生成一个服务实现类

-server:此选项将生成一个服务器组件,用于发布并启动服务

-d:此选项可以用来直接生成代码到一个特定的文件夹

就比如说拿上文中通过代码优先方式生成的wsdl文档:


将上面的wsdl内容复制到一个文件中,比如叫做mywsdl.wsdl

将服务器server开启起来,将服务发布出去,确保能访问到服务.之后我们打开CXF的bin目录,可以找到wadl2java.bat工具,这里为了方便,就直接将mywsdl.wsdl放在bin目录下了,在CMD中输入:wsdl2java.bat -d C:\cxftest -ant -impl -server mywsdl.wsdl

最后去就能在指定的目录下找到CXF生成的文件.

可能会发生的异常问题:


上图的问题1是因为server端没有开启服务器,将server发布出去即可.

问题2是cxf对jdk8的支持问题,解决办法是:找到jdk8的安装目录,在jdk下的jre下的lib下添加一个jaxp.properties文件(如果已经有了,那就不用创建了),添加以下内容:

javax.xml.accessExternalSchema = all

注意大小写,最好你就是复制我上面的内容.然后再重新执行一次上面的wsdl2java命令即可.

生成的内容会根据wsdl文档的内容,不过大概的样子都长这样:(我这里是因为编程风格问题,你们按照java的形式就不会像下面这个图,注意一下即可)


稍微打开每一个文档阅读之后,会发现IHelloService_HelloServicePort_Server就是server类,还有像接口类IHelloService,看名字就能看出个所以然了,基本上都不需要做更改,但唯一必须更改的是实现类,比如这里的HelloServiceImpl类,里面的sayHello只返回一个空字符串,我们需要在这里添加逻辑代码.

对于客户端调用有两种方式:

第一种采用cxf的客户端调用,和以前的一样.

 factory.setServiceClass(IHelloService.class); factory.setAddress("http://localhost:9000/HelloWorld"); IHelloService service = (IHelloService) factory.create(); System.out.println("[result]" + service.sayHello("YZR"));
第二种是基于JA-WS的客户端:

package yzr.main;import java.io.File;import java.net.URL;import cxfwebservice.HelloServiceService;import yzr.interfaces.IHelloService;public class wsdlClient {public static void main(String[] args) throws Exception {File file=new File("wsdl/mywsdl.wsdl");URL url;if(file.exists()){url=file.toURL();}else{url=new URL(args[0]);}HelloServiceService service=new HelloServiceService(url);IHelloService s=service.getHelloServicePort();System.out.println(s.sayHello("YZR"));}}

说明:HelloServiceService这个是CXF自动生成的,在使用wsdl2java.bat生成的文件夹中可以找到.

直接将这个类的代码和接口类代码拿过来客户端使用即可.

简单前端模式(Simple Frontend)

与JAX-WS实现模式不同,简单前端模式在开发和部署webService时不提供任何正式的规范或标准,简单前端模式采用简单工厂模式创建服务,工厂组件采用java反射API去动态创建服务组件和客户端组件,这种模式易于使用,不需要任何工具来构建服务.

默认情况下简单前端模式使用JAXB数据绑定.

简单前端模式的服务端使用ServerFactoryBean对象,客户端采用ClientProxyFactoryBean对象.ServerFactoryBean产生一个服务器实例,需要一个服务来和地址公布于服务,通过创建一个Serer,可以提供服务给外部世界.

实例1:简单实用SimpleFrontend案例

服务端:

接口类:

package yzr.interfaces;import yzr.entity.Article;public interface BlogManage {public Article getArticle(String title);}
实现类:

package yzr.service;import yzr.entity.Article;import yzr.interfaces.BlogManage;public class BlogManageImpl implements BlogManage {@Overridepublic Article getArticle(String title) {Article art=new Article(title);art.setContent("测试");return art;}}

实体类:

package yzr.entity;import java.io.Serializable;public class Article implements Serializable{/** *  */private static final long serialVersionUID = 5354767599482895519L;private String title;private String content;public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "Article [title=" + title + ", content=" + content + "]";}public Article(){}public Article(String title){this.title=title;}}

发布:

package yzr.main;import org.apache.cxf.frontend.ServerFactoryBean;import yzr.interfaces.BlogManage;import yzr.service.BlogManageImpl;public class simpledeploy {public static void main(String[] args) {BlogManage blogManage=new BlogManageImpl();ServerFactoryBean svrFactroy=new ServerFactoryBean();svrFactroy.setServiceClass(BlogManage.class);svrFactroy.setAddress("http://localhost:9000/BlogManage");svrFactroy.setServiceBean(blogManage);svrFactroy.create();System.out.println("服务启动成功");}}

客户端:

package yzr.main;import org.apache.cxf.frontend.ClientProxyFactoryBean;import yzr.interfaces.BlogManage;public class ClientProxyFactory {public static void main(String[] args) {ClientProxyFactoryBean factory=new ClientProxyFactoryBean();factory.setServiceClass(BlogManage.class);if(args!=null && args.length>0 && !"".equals(args[0])){factory.setAddress(args[0]);}else{factory.setAddress("http://localhost:9000/BlogManage");}BlogManage blogManage=(BlogManage)factory.create();System.out.println(blogManage.getArticle("YZR"));}}
需要服务端提供接口类和实体类.(BlogManage和Article)

实例2:Spring集成通过Tomcat发布服务

web.xml:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"id="WebApp_ID" version="2.5"><display-name>cxfService</display-name><context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:applicationContext-server.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- <listener><listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class></listener>     -->    <servlet><servlet-name>CXFService</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class></servlet><servlet-mapping><servlet-name>CXFService</servlet-name><url-pattern>/*</url-pattern></servlet-mapping>        </web-app>
Spring配置文件:applicationContext-server.xml:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:simple="http://cxf.apache.org/simple"xmlns:soap="http://cxf.apache.org/bindings/soap"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsdhttp://cxf.apache.org/bindings/soaphttp://cxf.apache.org/schemas/configuration/soap.xsdhttp://cxf.apache.org/simplehttp://cxf.apache.org/schemas/simple.xsd"><!-- <import resource="classpath:META-INF/cxf/cxf.xml"></import><import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"></import> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" ></import><jaxws:endpoint id="UserService" implementor="yzr.service.UserServiceImpl"address="http://localhost:9000/User"></jaxws:endpoint>--><simple:server id="BlogManage"  serviceClass="yzr.interfaces.BlogManage" address="http://localhost:9000/BlogManage"><simple:serviceBean><bean class="yzr.service.BlogManageImpl"></bean></simple:serviceBean></simple:server></beans>

客户端:

package yzr.main;import org.springframework.context.support.ClassPathXmlApplicationContext;import yzr.interfaces.BlogManage;public class simpleClient {public static void main(String[] args) {//CXF方式ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"/yzr/main/CXFSimpleClient-beans.xml"});BlogManage service2=(BlogManage)context.getBean("client");System.out.println(service2.getArticle("YZR"));}}
CXFSimpleClient-beans.xml的内容如下:

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:simple="http://cxf.apache.org/simple"      xmlns:soap="http://cxf.apache.org/bindings/soap"      xsi:schemaLocation="              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd              http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd              http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd">                              <simple:client id="client" serviceClass="yzr.interfaces.BlogManage"          address="http://localhost:9000/BlogManage">      </simple:client>  </beans>  
Provider/Dispatch服务前端模式
当WeService客户端和WebService服务端之间通过XML来传输XML时,信息非常大,同时,开发人员也不想在JAVA对象和XML消息之间的转换上开销大.在这种情况下,使用Provider和Dispatch就非常有优势.作为WebService的组成部分,开发人员可以直接吹XML,或者采用更有效的方式来解析XML,从而不必把这些工作全部都提交到WebService框架去处理.

采用DOMSource(message)的Provider/Dispatch前端模式实现

主要处理大型的,复杂的XML文件

服务端server:

package yzr.main;import javax.xml.ws.Endpoint;public class Server2 {    protected Server2() throws Exception {                    System.out.println("Starting HelloWorld");        Object implementor = new GreeterDOMSourceMessageProvider();        String address = "http://localhost:9000/HelloWorld";        Endpoint.publish(address, implementor);    }    public static void main(String args[]) throws Exception {        new Server2();        System.out.println("Server ready...");        Thread.sleep(5 * 60 * 1000);        System.out.println("Server exiting");        System.exit(0);    }}

GreeterDOMSourceMessageProvider类:

package yzr.main;import java.io.InputStream;import javax.xml.soap.MessageFactory;import javax.xml.soap.SOAPMessage;import javax.xml.soap.SOAPPart;import javax.xml.transform.dom.DOMSource;import javax.xml.ws.Provider;import javax.xml.ws.Service;import javax.xml.ws.ServiceMode;import javax.xml.ws.WebServiceProvider;@WebServiceProvider(portName = "HelloPort", serviceName = "HelloService",                    targetNamespace = "http://yzr.interfaces/IHelloService")@ServiceMode(value=Service.Mode.MESSAGE)public class GreeterDOMSourceMessageProvider implements Provider<DOMSource> {@Overridepublic DOMSource invoke(DOMSource request) {        DOMSource response = new DOMSource();        try {            MessageFactory factory = MessageFactory.newInstance();            SOAPMessage soapReq = factory.createMessage();            soapReq.getSOAPPart().setContent(request);                System.out.println("Incoming Client Request as a DOMSource data in MESSAGE Mode");            System.out.println("aaa");            soapReq.writeTo(System.out);            System.out.println("bbb");            System.out.println("\n");                InputStream is = getClass().getResourceAsStream("/yzr/main/GreetMeDocLiteralResp2.xml");            SOAPMessage greetMeResponse =  factory.createMessage(null, is);            is.close();            response.setNode(greetMeResponse.getSOAPPart());        } catch (Exception ex) {            ex.printStackTrace();        }        return response;    }public GreeterDOMSourceMessageProvider(){}}

GreetMeDocLiteralResp2.xml文件:

<?xml version="1.0" encoding="utf-8" ?><!--  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.--><SOAP-ENV:Envelope     xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:xs="http://www.w3.org/2001/XMLSchema"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <SOAP-ENV:Body>        <ns4:greetMeResponse xmlns:ns4="http://yzr.interfaces/IHelloService">            <ns4:responseType>Hi YZR1</ns4:responseType>            <ns4:responseType>Hi YZR2</ns4:responseType>            <ns4:responseType>Hi YZR3</ns4:responseType>        </ns4:greetMeResponse>         <ns4:greetMeResponse xmlns:ns4="http://yzr.interfaces/IHelloService">            <ns4:responseType>Hi YZR4</ns4:responseType>            <ns4:responseType>Hi YZR5</ns4:responseType>            <ns4:responseType><content>this content</content></ns4:responseType>        </ns4:greetMeResponse>    </SOAP-ENV:Body></SOAP-ENV:Envelope>

客户端:

public static void main(String args[]) throws Exception {        /*        if (args.length == 0) {            System.out.println("please specify wsdl");            System.exit(1);        }        URL wsdlURL;        File wsdlFile = new File(args[0]);        if (wsdlFile.exists()) {            wsdlURL = wsdlFile.toURI().toURL();        } else {            wsdlURL = new URL(args[0]);        }        */    URL wsdlURL=new URL("http://localhost:9000/HelloWorld?wsdl");        MessageFactory factory = MessageFactory.newInstance();        System.out.println(wsdlURL + "\n\n");                        QName serviceName2 = new QName("http://yzr.interfaces/IHelloService", "HelloService");        QName portName2 = new QName("http://yzr.interfaces/IHelloService", "HelloPort");        HelloService service2 = new HelloService(wsdlURL, serviceName2);        InputStream is2 =  Client.class.getResourceAsStream("/yzr/main/GreetMeDocLiteralReq2.xml");        if (is2 == null) {            System.err.println("Failed to create input stream from file "                               + "GreetMeDocLiteralReq2.xml, please check");            System.exit(-1);        }        SOAPMessage soapReq2 = factory.createMessage(null, is2);        DOMSource domReqMessage = new DOMSource(soapReq2.getSOAPPart());        Dispatch<DOMSource> dispDOMSrcMessage = service2.createDispatch(portName2,                                                                        DOMSource.class, Mode.MESSAGE);        System.out.println("Invoking server through Dispatch interface using DOMSource in MESSAGE Mode");        DOMSource domRespMessage = dispDOMSrcMessage.invoke(domReqMessage);        System.out.println("Response from server: "                           + domRespMessage.getNode().getLastChild().getTextContent());                System.exit(0);    }

HelloService类:

package cxfwebservice;import java.net.URL;import javax.xml.namespace.QName;import javax.xml.ws.Service;public class HelloService extends Service {public HelloService(URL wsdlDocumentLocation, QName serviceName) {super(wsdlDocumentLocation, serviceName);}public HelloService() {super(null, null);}public HelloService(URL wsdlDocumentLocation) {super(wsdlDocumentLocation, null);}}

GreetMeDocLiteralReq2.xml:

<?xml version="1.0" encoding="utf-8" ?><!--  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.--><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns4:greetMe xmlns:ns4="http://yzr.interfaces/IHelloService"><ns4:requestType>Param</ns4:requestType></ns4:greetMe></SOAP-ENV:Body></SOAP-ENV:Envelope>

测试结果:


采用DOMSource(Payload)的Provider/Dispatch前端模式实现

主要处理大型的,复杂的XML文件.

代码与上面的DOMSource<Message>方式大同小异.

package yzr.main;import javax.xml.ws.Endpoint;public class Server2 {    protected Server2() throws Exception {                    System.out.println("Starting HelloWorld2");        Object implementor = new GreeterDOMSourcePayloadProvider();        String address = "http://localhost:9000/HelloWorld2";        Endpoint.publish(address, implementor);                        /*        System.out.println("Starting HelloWorld");        Object implementor = new GreeterDOMSourceMessageProvider();        String address = "http://localhost:9000/HelloWorld";        Endpoint.publish(address, implementor);        */    }    public static void main(String args[]) throws Exception {        new Server2();        System.out.println("Server ready...");        Thread.sleep(5 * 60 * 1000);        System.out.println("Server exiting");        System.exit(0);    }}

GreeterDOMSourcePayloadProvider类:

package yzr.main;import java.io.InputStream;import javax.xml.soap.MessageFactory;import javax.xml.soap.SOAPMessage;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import javax.xml.ws.Provider;import javax.xml.ws.WebServiceProvider;@WebServiceProvider(portName = "HelloPort2", serviceName = "HelloService2",                    targetNamespace = "http://yzr.interfaces/IHelloService")public class GreeterDOMSourcePayloadProvider implements Provider<DOMSource> {    public GreeterDOMSourcePayloadProvider() {        //Complete    }    public DOMSource invoke(DOMSource request) {        DOMSource response = new DOMSource();        try {            System.out.println("Incoming Client Request as a DOMSource data in PAYLOAD Mode");            Transformer transformer = TransformerFactory.newInstance().newTransformer();            StreamResult result = new StreamResult(System.out);            transformer.transform(request, result);            System.out.println("\n");                        InputStream is = getClass().getResourceAsStream("/yzr/main/GreetMeDocLiteralResp3.xml");                        SOAPMessage greetMeResponse =  MessageFactory.newInstance().createMessage(null, is);            is.close();                        response.setNode(greetMeResponse.getSOAPBody().extractContentAsDocument());        } catch (Exception ex) {            ex.printStackTrace();        }        return response;    }}

响应的GreetMeDocLiteralResp3.xml:

<?xml version="1.0" encoding="utf-8" ?><!--  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.--><SOAP-ENV:Envelope     xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:xs="http://www.w3.org/2001/XMLSchema"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <SOAP-ENV:Body>        <ns4:greetMeResponse xmlns:ns4="http://yzr.interfaces/IHelloService">            <ns4:responseType>DOMSource Payload Provider</ns4:responseType>        </ns4:greetMeResponse>     </SOAP-ENV:Body></SOAP-ENV:Envelope>

客户端:

package yzr.main;import java.io.File;import java.io.InputStream;import java.net.URL;import javax.xml.namespace.QName;import javax.xml.soap.MessageFactory;import javax.xml.soap.SOAPMessage;import javax.xml.transform.dom.DOMSource;import javax.xml.ws.Dispatch;import javax.xml.ws.Service.Mode;import org.w3c.dom.Element;import org.w3c.dom.Node;import cxfwebservice.HelloService;public final class Client2 {    private Client2() {    }    public static void main(String args[]) throws Exception {        /*        if (args.length == 0) {            System.out.println("please specify wsdl");            System.exit(1);        }        URL wsdlURL;        File wsdlFile = new File(args[0]);        if (wsdlFile.exists()) {            wsdlURL = wsdlFile.toURI().toURL();        } else {            wsdlURL = new URL(args[0]);        }        */                   /*        //DOMSource<Message>    URL wsdlURL=new URL("http://localhost:9000/HelloWorld?wsdl");        MessageFactory factory = MessageFactory.newInstance();        System.out.println(wsdlURL + "\n\n");        QName serviceName2 = new QName("http://yzr.interfaces/IHelloService", "HelloService");        QName portName2 = new QName("http://yzr.interfaces/IHelloService", "HelloPort");        HelloService service2 = new HelloService(wsdlURL, serviceName2);        InputStream is2 =  Client.class.getResourceAsStream("/yzr/main/GreetMeDocLiteralReq2.xml");        if (is2 == null) {            System.err.println("Failed to create input stream from file "                               + "GreetMeDocLiteralReq2.xml, please check");            System.exit(-1);        }        SOAPMessage soapReq2 = factory.createMessage(null, is2);        DOMSource domReqMessage = new DOMSource(soapReq2.getSOAPPart());        Dispatch<DOMSource> dispDOMSrcMessage = service2.createDispatch(portName2,                                                                        DOMSource.class, Mode.MESSAGE);        System.out.println("Invoking server through Dispatch interface using DOMSource in MESSAGE Mode");        DOMSource domRespMessage = dispDOMSrcMessage.invoke(domReqMessage);        System.out.println("Response from server: "                           + domRespMessage.getNode().getLastChild().getTextContent());        */        //DOMSource(payload)        URL wsdlURL=new URL("http://localhost:9000/HelloWorld2?wsdl");        System.out.println(wsdlURL + "\n\n");        QName serviceName3 = new QName("http://yzr.interfaces/IHelloService", "HelloService2");        QName portName3 = new QName("http://yzr.interfaces/IHelloService", "HelloPort2");        HelloService service3 = new HelloService(wsdlURL, serviceName3);        InputStream is3 =  Client.class.getResourceAsStream("/yzr/main/GreetMeDocLiteralReq3.xml");        if (is3 == null) {            System.err.println("Failed to create input stream from file "                               + "GreetMeDocLiteralReq3.xml, please check");            System.exit(-1);        }        SOAPMessage soapReq3 = MessageFactory.newInstance().createMessage(null, is3);        DOMSource domReqPayload = new DOMSource(soapReq3.getSOAPBody().extractContentAsDocument());        Dispatch<DOMSource> dispDOMSrcPayload = service3.createDispatch(portName3,                                                                        DOMSource.class, Mode.PAYLOAD);        System.out.println("Invoking server through Dispatch interface using DOMSource in PAYLOAD Mode");        DOMSource domRespPayload = dispDOMSrcPayload.invoke(domReqPayload);        System.out.println("Response from server: "                           + fetchElementByName(domRespPayload.getNode(),                                                 "greetMeResponse").getTextContent());                System.exit(0);    }    private static Element fetchElementByName(Node parent, String name) {        Element ret = null;                Node node = parent.getFirstChild();        while (node != null) {            if (node instanceof Element && ((Element)node).getLocalName().equals(name)) {                ret = (Element)node;                break;            }            node = node.getNextSibling();        }        return ret;    }}

参数XML文件GreetMeDocLiteralReq3.xml:

<?xml version="1.0" encoding="utf-8" ?><!-- 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. --><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns4:greetMe xmlns:ns4="http://yzr.interfaces/IHelloService"><ns4:requestType>this Param Content</ns4:requestType></ns4:greetMe></SOAP-ENV:Body></SOAP-ENV:Envelope>

测试结果和DOMSource<Message>一样.

采用SOAPMessage的Provider/Dispatch前端实现

主要处理大型的,复杂的XML文件

server:

package yzr.main;import javax.xml.ws.Endpoint;public class Server2 {    protected Server2() throws Exception {            System.out.println("Starting Server");        System.out.println("Starting BlogManage");        Object implementor = new GreeterSoapMessageProvider();        String address = "http://localhost:9000/BlogManage";        Endpoint.publish(address, implementor);                        /*        System.out.println("Starting HelloWorld2");        Object implementor = new GreeterDOMSourcePayloadProvider();        String address = "http://localhost:9000/HelloWorld2";        Endpoint.publish(address, implementor);                */        /*        System.out.println("Starting HelloWorld");        Object implementor = new GreeterDOMSourceMessageProvider();        String address = "http://localhost:9000/HelloWorld";        Endpoint.publish(address, implementor);        */    }    public static void main(String args[]) throws Exception {        new Server2();        System.out.println("Server ready...");        Thread.sleep(5 * 60 * 1000);        System.out.println("Server exiting");        System.exit(0);    }}

GreeterSoapMessageProvider类:

package yzr.main;import java.io.InputStream;import javax.xml.soap.MessageFactory;import javax.xml.soap.SOAPMessage;import javax.xml.ws.Provider;import javax.xml.ws.Service;import javax.xml.ws.ServiceMode;import javax.xml.ws.WebServiceProvider;@WebServiceProvider(portName = "BlogManagePort", serviceName = "BlogManage",                      targetNamespace = "http://interfaces.yzr/",                      wsdlLocation = "/yzr/main/hello_world3.wsdl")//wsdlLocation只作为前端网页解释说明作用,就是在网页上访问http://localhost:9000/BlogManage?wsdl时显示的内容@ServiceMode(value = Service.Mode.MESSAGE)public class GreeterSoapMessageProvider implements Provider<SOAPMessage> {    public GreeterSoapMessageProvider() {        //Complete    }    public SOAPMessage invoke(SOAPMessage request) {        SOAPMessage response = null;        try {            System.out.println("Incoming Client Request as a SOAPMessage");            MessageFactory factory = MessageFactory.newInstance();            //传入的XML            request.writeTo(System.out);                        InputStream is = getClass().getResourceAsStream("/yzr/main/GreetMeDocLiteralResp1.xml");            response =  factory.createMessage(null, is);            is.close();        } catch (Exception ex) {            ex.printStackTrace();        }        return response;    }}
GreetMeDocLiteralResp1.xml:
<?xml version="1.0" encoding="utf-8" ?><!--  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.--><SOAP-ENV:Envelope     xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:xs="http://www.w3.org/2001/XMLSchema"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <SOAP-ENV:Body>        <ns4:greetMeResponse xmlns:ns4="http://interfaces.yzr/">            <ns4:responseType>Hi YZR</ns4:responseType>        </ns4:greetMeResponse>            </SOAP-ENV:Body></SOAP-ENV:Envelope>

客户端:

package yzr.main;import java.io.File;import java.io.InputStream;import java.net.URL;import javax.xml.namespace.QName;import javax.xml.soap.MessageFactory;import javax.xml.soap.SOAPMessage;import javax.xml.transform.dom.DOMSource;import javax.xml.ws.Dispatch;import javax.xml.ws.Service;import javax.xml.ws.Service.Mode;import javax.xml.ws.soap.SOAPBinding;import org.apache.cxf.frontend.ClientProxyFactoryBean;import org.w3c.dom.Element;import org.w3c.dom.Node;import cxfwebservice.HelloService;import yzr.interfaces.BlogManage;public final class Client2 {    private Client2() {    }    public static void main(String args[]) throws Exception {        /*        if (args.length == 0) {            System.out.println("please specify wsdl");            System.exit(1);        }        URL wsdlURL;        File wsdlFile = new File(args[0]);        if (wsdlFile.exists()) {            wsdlURL = wsdlFile.toURI().toURL();        } else {            wsdlURL = new URL(args[0]);        }        */                    URL wsdlURL=new URL("http://localhost:9000/BlogManage?wsdl");        MessageFactory factory = MessageFactory.newInstance();        System.out.println(wsdlURL + "\n\n");        QName serviceName1 = new QName("http://interfaces.yzr/", "BlogManage");        QName portName1 = new QName("http://interfaces.yzr/", "BlogManagePort");                HelloService service1 = new HelloService(wsdlURL, serviceName1);        InputStream is1 =  Client.class.getResourceAsStream("/yzr/main/GreetMeDocLiteralReq1.xml");        if (is1 == null) {            System.err.println("Failed to create input stream from file "                               + "GreetMeDocLiteralReq1.xml, please check");            System.exit(-1);        }        SOAPMessage soapReq1 = factory.createMessage(null, is1);        Dispatch<SOAPMessage> dispSOAPMsg = service1.createDispatch(portName1,                                                                    SOAPMessage.class, Mode.MESSAGE);        System.out.println("Invoking server through Dispatch interface using SOAPMessage");        SOAPMessage soapResp = dispSOAPMsg.invoke(soapReq1);        System.out.println("Response from server: " + soapResp.getSOAPBody().getTextContent());                     /*        //DOMSource<Message>    URL wsdlURL=new URL("http://localhost:9000/HelloWorld?wsdl");        MessageFactory factory = MessageFactory.newInstance();        System.out.println(wsdlURL + "\n\n");        QName serviceName2 = new QName("http://yzr.interfaces/IHelloService", "HelloService");        QName portName2 = new QName("http://yzr.interfaces/IHelloService", "HelloPort");        HelloService service2 = new HelloService(wsdlURL, serviceName2);        InputStream is2 =  Client.class.getResourceAsStream("/yzr/main/GreetMeDocLiteralReq2.xml");        if (is2 == null) {            System.err.println("Failed to create input stream from file "                               + "GreetMeDocLiteralReq2.xml, please check");            System.exit(-1);        }        SOAPMessage soapReq2 = factory.createMessage(null, is2);        DOMSource domReqMessage = new DOMSource(soapReq2.getSOAPPart());        Dispatch<DOMSource> dispDOMSrcMessage = service2.createDispatch(portName2,                                                                        DOMSource.class, Mode.MESSAGE);        System.out.println("Invoking server through Dispatch interface using DOMSource in MESSAGE Mode");        DOMSource domRespMessage = dispDOMSrcMessage.invoke(domReqMessage);        System.out.println("Response from server: "                           + domRespMessage.getNode().getLastChild().getTextContent());        */    /*    //DOMSource(payload)        URL wsdlURL=new URL("http://localhost:9000/HelloWorld2?wsdl");        System.out.println(wsdlURL + "\n\n");        QName serviceName3 = new QName("http://yzr.interfaces/IHelloService", "HelloService2");        QName portName3 = new QName("http://yzr.interfaces/IHelloService", "HelloPort2");        HelloService service3 = new HelloService(wsdlURL, serviceName3);        InputStream is3 =  Client.class.getResourceAsStream("/yzr/main/GreetMeDocLiteralReq3.xml");        if (is3 == null) {            System.err.println("Failed to create input stream from file "                               + "GreetMeDocLiteralReq3.xml, please check");            System.exit(-1);        }        SOAPMessage soapReq3 = MessageFactory.newInstance().createMessage(null, is3);        DOMSource domReqPayload = new DOMSource(soapReq3.getSOAPBody().extractContentAsDocument());        Dispatch<DOMSource> dispDOMSrcPayload = service3.createDispatch(portName3,                                                                        DOMSource.class, Mode.PAYLOAD);        System.out.println("Invoking server through Dispatch interface using DOMSource in PAYLOAD Mode");        DOMSource domRespPayload = dispDOMSrcPayload.invoke(domReqPayload);        System.out.println("Response from server: "                           + fetchElementByName(domRespPayload.getNode(),                                                 "greetMeResponse").getTextContent());        */        System.exit(0);    }    private static Element fetchElementByName(Node parent, String name) {        Element ret = null;                Node node = parent.getFirstChild();        while (node != null) {            if (node instanceof Element && ((Element)node).getLocalName().equals(name)) {                ret = (Element)node;                break;            }            node = node.getNextSibling();        }        return ret;    }}
GreetMeDocLiteralReq1.xml:

<?xml version="1.0" encoding="utf-8" ?><!-- 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. --><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns4:greetMe xmlns:ns4="http://yzr.interfaces/"><ns4:requestType>XXX</ns4:requestType></ns4:greetMe></SOAP-ENV:Body></SOAP-ENV:Envelope>

补充说明:在server中的GreeterSoapMessageProvider中的WebService注释中如果没有加入wsdlLocation = "/yzr/main/hello_world3.wsdl",那么访问http://localhost:9000/BlogManage?wsdl的时候,看到的wsdl文档中没有详细的关于BlogManage的xml信息,如下图:

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://interfaces.yzr/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://main.yzr/" name="BlogManage" targetNamespace="http://interfaces.yzr/"><wsdl:import location="http://localhost:9000/BlogManage?wsdl=GreeterSoapMessageProvider.wsdl" namespace="http://main.yzr/"></wsdl:import><wsdl:binding name="BlogManageSoapBinding" type="ns1:GreeterSoapMessageProvider"><soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation name="invoke"><soap:operation soapAction="" style="document"/><wsdl:input name="invoke"><soap:body use="literal"/></wsdl:input><wsdl:output name="invokeResponse"><soap:body use="literal"/></wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="BlogManage"><wsdl:port binding="tns:BlogManageSoapBinding" name="BlogManagePort"><soap:address location="http://localhost:9000/BlogManage"/></wsdl:port></wsdl:service></wsdl:definitions>

这就是访问的结果,但如果加上wsdlLocation = "/yzr/main/hello_world3.wsdl",hello_world3.wsdl的内容为:

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://interfaces.yzr/"xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"name="BlogManage" targetNamespace="http://interfaces.yzr/"><wsdl:types><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns="http://interfaces.yzr/" attributeFormDefault="unqualified"elementFormDefault="unqualified" targetNamespace="http://interfaces.yzr/"><xs:complexType name="article"><xs:sequence><xs:element minOccurs="0" name="content" type="xs:string" /><xs:element minOccurs="0" name="title" type="xs:string" /></xs:sequence></xs:complexType><xs:element name="getArticle" type="getArticle" /><xs:complexType name="getArticle"><xs:sequence><xs:element minOccurs="0" name="arg0" type="xs:string" /></xs:sequence></xs:complexType><xs:element name="getArticleResponse" type="getArticleResponse" /><xs:complexType name="getArticleResponse"><xs:sequence><xs:element minOccurs="0" name="return" type="article" /></xs:sequence></xs:complexType></xs:schema></wsdl:types><wsdl:message name="getArticleResponse"><wsdl:part element="tns:getArticleResponse" name="parameters"></wsdl:part></wsdl:message><wsdl:message name="getArticle"><wsdl:part element="tns:getArticle" name="parameters"></wsdl:part></wsdl:message><wsdl:portType name="BlogManagePortType"><wsdl:operation name="getArticle"><wsdl:input message="tns:getArticle" name="getArticle"></wsdl:input><wsdl:output message="tns:getArticleResponse" name="getArticleResponse"></wsdl:output></wsdl:operation></wsdl:portType><wsdl:binding name="BlogManageSoapBinding" type="tns:BlogManagePortType"><soap:binding style="document"transport="http://schemas.xmlsoap.org/soap/http" /><wsdl:operation name="getArticle"><soap:operation soapAction="" style="document" /><wsdl:input name="getArticle"><soap:body use="literal" /></wsdl:input><wsdl:output name="getArticleResponse"><soap:body use="literal" /></wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="BlogManage"><wsdl:port binding="tns:BlogManageSoapBinding" name="BlogManagePort"><soap:address location="http://localhost:9000/BlogManage" /></wsdl:port></wsdl:service></wsdl:definitions>

此时在访问http://localhost:9000/BlogManage?wsdl的结果为:

This XML file does not appear to have any style information associated with it. The document tree is shown below.<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://interfaces.yzr/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="BlogManage" targetNamespace="http://interfaces.yzr/"><wsdl:types><xs:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://interfaces.yzr/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns="http://interfaces.yzr/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://interfaces.yzr/"><xs:complexType name="article"><xs:sequence><xs:element minOccurs="0" name="content" type="xs:string"/><xs:element minOccurs="0" name="title" type="xs:string"/></xs:sequence></xs:complexType><xs:element name="getArticle" type="getArticle"/><xs:complexType name="getArticle"><xs:sequence><xs:element minOccurs="0" name="arg0" type="xs:string"/></xs:sequence></xs:complexType><xs:element name="getArticleResponse" type="getArticleResponse"/><xs:complexType name="getArticleResponse"><xs:sequence><xs:element minOccurs="0" name="return" type="article"/></xs:sequence></xs:complexType></xs:schema></wsdl:types><wsdl:message name="getArticleResponse"><wsdl:part element="tns:getArticleResponse" name="parameters"></wsdl:part></wsdl:message><wsdl:message name="getArticle"><wsdl:part element="tns:getArticle" name="parameters"></wsdl:part></wsdl:message><wsdl:portType name="BlogManagePortType"><wsdl:operation name="getArticle"><wsdl:input message="tns:getArticle" name="getArticle"></wsdl:input><wsdl:output message="tns:getArticleResponse" name="getArticleResponse"></wsdl:output></wsdl:operation></wsdl:portType><wsdl:binding name="BlogManageSoapBinding" type="tns:BlogManagePortType"><soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/><wsdl:operation name="getArticle"><soap:operation soapAction="" style="document"/><wsdl:input name="getArticle"><soap:body use="literal"/></wsdl:input><wsdl:output name="getArticleResponse"><soap:body use="literal"/></wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="BlogManage"><wsdl:port binding="tns:BlogManageSoapBinding" name="BlogManagePort"><soap:address location="http://localhost:9000/BlogManage"/></wsdl:port></wsdl:service></wsdl:definitions>

采用Apache CXF的动态客户端技术

WebService客户端通常使用服务接口来调用服务方法,在有些情况下,需要提供一个在运行时动态生成的客户端,由于动态客户端动态检查WSDL,并在WSDL定义基础上动态的创建客户端输入和输出对象,它也验证WSDL文件和输入输出消息格式,但实际上动态客户端并没有调用web服务作为单元测试环境的一部分.

更多案例,读者自行查看下载下来自带的cxf案例吧


案列代码下载:点击



























1 0