设为首页 收藏本站
查看: 1123|回复: 0

[经验分享] 转:CXF学习笔记一:如何创建、发布和访问基于CXF的服务

[复制链接]

尚未签到

发表于 2017-2-28 09:54:45 | 显示全部楼层 |阅读模式
主要参考http://cxf.apache.org的相关内容:  1.使用CXF创建服务的基本方法(使用CXF自带的jetty容器
  参考:http://cxf.apache.org/docs/a-simple-jax-ws-service.html
  分4步:
  ① 设置build环境
  ② 写服务
  ③ 发布服务
  ④ 访问服务
  1)设置build环境
  创建一个新项目,将apache-cxf-2.2.4.zip中lib目录中的下列文件添加到Build Path:
  commons-logging-1.1.1.jar
  geronimo-activation_1.1_spec-1.0.2.jar (or Sun's Activation jar)
  geronimo-annotation_1.0_spec-1.1.1.jar (JSR 250)
  geronimo-javamail_1.4_spec-1.6.jar (or Sun's JavaMail jar)
  geronimo-servlet_2.5_spec-1.2.jar (or Sun's Servlet jar)
  geronimo-ws-metadata_2.0_spec-1.1.2.jar (JSR 181)
  geronimo-jaxws_2.1_spec-1.0.jar (or Sun's jaxws-api-2.1.jar)
  geronimo-stax-api_1.0_spec-1.0.1.jar (or other stax-api jar)
  jaxb-api-2.1.jar
  jaxb-impl-2.1.12.jar
  jetty-6.1.21.jar
  jetty-util-6.1.21.jar
  neethi-2.0.4.jar
  saaj-api-1.3.jar
  saaj-impl-1.3.2.jar
  wsdl4j-1.6.2.jar
  wstx-asl-3.2.8.jar
  XmlSchema-1.4.5.jar
  xml-resolver-1.2.jar
  cxf-2.2.4.jar
  可选:添加Spring jars,为XML Configuration添加Spring支持。添加的jars如下:
  aopalliance-1.0.jar
  spring-core-2.5.5.jar
  spring-beans-2.5.5.jar
  spring-context-2.5.5.jar
  spring-web-2.5.5.jar
  2)写服务
  A)写接口
  @WebService
  public interface HelloWorld {
  String sayHi(String text);
  // JAX-WS/JAXB 不能直接支持高级用例,处理他们需要写特殊的XmlAdapter
  String sayHiToUser(User user);
  /* Map 传递
  * JAXB 不支持 Maps。它能很好的处理Lists,但Maps不能直接支持他们。
  * 他们也需要使用一个XmlAdapter来将maps映射进JAXB可以使用的beans
  */
  @XmlJavaTypeAdapter(IntegerUserMapAdapter.class)
  Map<Integer, User> getUsers();
  }
  注意:wsdl会重命名参数的名字,如果不希望这样,应该这样写:
  @WebService
  public interface HelloWorld {
  String sayHi(@WebParam(name="text") String text);
  }
  B)写实现:
  package demo.hw.server;
  import java.util.LinkedHashMap;
  import java.util.Map;
  import javax.jws.WebService;
  @WebService(endpointInterface = "demo.hw.server.HelloWorld",
  serviceName = "HelloWorld")    //告诉CXF用哪一个接口创建WSDL
  public class HelloWorldImpl implements HelloWorld {
  Map<Integer, User> users = new LinkedHashMap<Integer, User>();
  public String sayHi(String text) {
  System.out.println("sayHi called");
  return "Hello " + text;
  }
  public String sayHiToUser(User user) {
  System.out.println("sayHiToUser called");
  users.put(users.size() + 1, user);
  return "Hello "  + user.getName();
  }
  public Map<Integer, User> getUsers() {
  System.out.println("getUsers called");
  return users;
  }
  }
  3)发布服务(CXF自带Jetty服务器,所以无需Tomcat就可发布)
  A)使用jws的高层封装:
  System.out.println("Starting Server");
  HelloWorldImpl implementor = new HelloWorldImpl();
  String address = "http://localhost:9000/helloWorld";
  Endpoint.publish(address, implementor);
  B)使用下列代码比较精确地控制服务的行为:
  HelloWorldImpl implementor = new HelloWorldImpl();
  JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
  svrFactory.setServiceClass(HelloWorld.class);   //可省,但不建议,因为可能会有些小问题
  svrFactory.setAddress("http://localhost:9000/helloWorld");
  svrFactory.setServiceBean(implementor);
  svrFactory.getInInterceptors().add(new LoggingInInterceptor());
  svrFactory.getOutInterceptors().add(new LoggingOutInterceptor());
  svrFactory.create();
  自此,可以通过http://localhost:9000/helloWorld?wsdl来显示该服务的wsdl
  LoggingInInterceptor和LoggingOutInterceptor是日志拦截器,用于输入和输出时显示日志,下同。
  4)访问服务
  A)使用jws的高层封装:
  //第一个参数是接口实现类包名的反缀
  private static final QName SERVICE_NAME = new QName("http://server.hw.demo/", "HelloWorld");
  private static final QName PORT_NAME= new QName("http://server.hw.demo/", "HelloWorldPort");
  ……
  Service service = Service.create(SERVICE_NAME);
  // Endpoint Address
  String endpointAddress = "http://localhost:9000/helloWorld";
  // Add a port to the Service
  service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
  HelloWorld hw = service.getPort(HelloWorld.class);
  System.out.println(hw.sayHi("World"));
  B)或者使用下面代码更精确的控制服务:
  JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
  factory.getInInterceptors().add(new LoggingInInterceptor());
  factory.getOutInterceptors().add(new LoggingOutInterceptor());
  factory.setServiceClass(HelloWorld.class);
  factory.setAddress("http://localhost:9000/helloWorld");
  HelloWorld client = (HelloWorld) factory.create();
  String reply = client.sayHi("HI");
  System.out.println("Server said: " + reply);
  System.exit(0);
  2.wsdl2java:从wsdl文档中生成java类,供client使用
  设置环境变量CXF_HOME=D:\Program Files\apache-cxf-2.2.4,PATH后加上“;%CXF_HOME%\bin”(可选),然后执行wsdl2java批处理程序,用法如下:
wsdl2java –p 包名 –d 目录名 wsdl路径
如:wsdl2java –p demo.service.client –d e:\src htt://localhost:8080/helloWorld?wsdl
-p  指定其wsdl的命名空间,也就是要生成代码的包名
-d  指定要产生代码所在目录
-client 生成客户端测试web service的代码
-server 生成服务器启动web  service的代码
-impl 生成web service的实现代码
-ant  生成build.xml文件
-all 生成所有开始端点代码:types,service proxy,,service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.
详细用法见http://cwiki.apache.org/CXF20DOC/wsdl-to-java.html

  3.定义复杂类型(基本类型如int,String,无须额外定义),参考资料:http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.html
  例如:
  package com.example.customerservice;
  @XmlAccessorType( XmlAccessType.FIELD )
  public class Customer {  //自定义类
  String name;
  String\[\] address;
  int numOrders;
  double revenue;
  BigDecimal test;
  Date birthDate;
  CustomerType type; //自定义枚举类型
  }
  public enum CustomerType {
  PRIVATE, BUSINESS
  }
  //定义Exception
  @WebFault(name="NoSuchCustomer")
  @XmlAccessorType( XmlAccessType.FIELD )
  public class NoSuchCustomerException extends RuntimeException {
  /**
  * We only define the fault details here. Additionally each fault has a message
  * that should not be defined separately
  */
  String customerName;
  }     //定义Exceptions的默认行为是在后面生成Java code时创建Exception_Exception,所以必须用@WebFault标记来为Bean取一个名字,以与Exception名字相区别
  @WebService    //标记本接口为一个服务
  public interface CustomerService {
  public Customer[] getCustomersByName(@WebParam(name="name") String name) throws NoSuchCustomerException;     //@WebParam标记wsdl中的参数名。如果省略,wsdl将使用arg0代替
  }
  // @WebService还可用来自定义接口名和服务名,分别对应:endpointInterface和serviceName,如:
  @WebService(endpointInterface = "com.example.customerservice", serviceName = "HelloWorld")
  生成的WSDL
  <xs:complexType name="customer">  //复杂类型
  <xs:sequence>
  <xs:element minOccurs="0" name="name" type="xs:string"/>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="address" nillable="true" type="xs:string"/>
  <xs:element name="numOrders" type="xs:int"/>
  <xs:element name="revenue" type="xs:double"/>
  <xs:element minOccurs="0" name="test" type="xs:decimal"/>
  <xs:element minOccurs="0" name="birthDate" type="xs:dateTime"/>
  <xs:element minOccurs="0" name="type" type="tns:customerType"/>
  </xs:sequence>
  </xs:complexType>
  minOccurs="0"是可选项,这样可以随时加入新元素,保持兼容性。如果不想要这个选项,可以使用标记@XmlElement(required=true)
  maxOccurs="unbounded"是为了便于后面的xml重复该元素以形成数组。
  <xs:simpleType name="customerType">    //枚举类型
  <xs:restriction base="xs:string">
  <xs:enumeration value="PRIVATE"/>
  <xs:enumeration value="BUSINESS"/>
  </xs:restriction>
  </xs:simpleType>
  <xs:element name="NoSuchCustomer" type="tns:NoSuchCustomer"/> //异常类
  <xs:complexType name="NoSuchCustomer">
  <xs:sequence>
  <xs:element name="customerName" nillable="true" type="xs:string"/>
  </xs:sequence>
  </xs:complexType>
  <wsdl:message name="NoSuchCustomerException">
  <wsdl:part name="NoSuchCustomerException" element="tns:NoSuchCustomer">
  </wsdl:part>
  </wsdl:message>
  // 注意:Element和Message的名字是不同的,这是通过标记@Webfault标记来实现的。也可以让他们同名,但那样会话,生成的Exception的名字会比较丑:NoSuchCustomerException_Exception

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348260-1-1.html 上篇帖子: (转)CXF学习笔记一:如何创建、发布和访问基于CXF的服务 下篇帖子: Mule 3 快速入门
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表