CXF的web service 学习笔记

规范

     规范只是接口,如JAX-WS和JAX-RS有CXF具体实现,有三种规范:JAXM&SAAJ(暴露了更多细节),JAX-WS和JAX-RS(rest风格的服务规范)。

JAX-WS(JAX-RPC):

     底层使用JAXB,JAX-RPC已被JAX-WS替换,位于javax.xml.ws.* 提供api操作web服务。 WS-MetaData:是JAX-WS的依赖规范,位于javax.jws.*

实例

1. Service EndPoint Interface

  (使用@Method和@WebService 标注接口为web服务)

@WebService 

public interface IHelloService { 

  Customer selectMaxAgeStudent(Customer c1, Customer c2); 

  Customer selectMaxLongNameStudent(Customer c1, Customer c2);

}

2. 实现类:

   类如果实现有多个接口,要使用 @WebService endpointInterface 指定哪个接口是SEI

3. 参数:

   SEI中参数的类,使用JAXB注解告诉CXF 完成XML和Java Object间处理,如@XmlRootElement。

@XmlRootElement(name = "Customer") 

public class Customer { 
  private long id; 
  private String name; 
  private Date birthday;
}

4. 发布服务:

使用 javax.xml.ws.Endpint.publish 发布服务,通过 url?wsdl可查看生成的wsdl文件

public static void main(String[] args) { 
   Endpoint.publish("http://127.0.0.1:8080/helloService", 
   new HelloServiceImpl()); 
}

5. 查看wsdl

    访问 http://127.0.0.1:8080/helloService?wsdl地址

分析WSDL的构成

  <wsdl:definitions :

       name(实现类+Service),targetNamespace

  <wsdl:type:

       Xs:element:

       web service中complex数据类型的元素定义

       Xxx(方法名称)和XxxResponse:对参数和返回值的元素定义

  <xs:complexType:

       通过name关联到 xs:element,为前面定义的元素指定具体的封装内容

  <wsdl:message

       将参数、返回值和异常封装为消息

   <wsdl:portType

       Name为接口名称

   <wsdl:operation :哪些方法,<wsdl:input <wsdl:output 指定操作的输入输出,使用message绑定前面声明过的消息。

   <wsdl:binding

       绑定webservice到SOAP协议,指定消息封装格式、发布地址

   <wsdl:service

      Name: 服务名称,

   <wsdl:port name指定port名称,

   <soap:address location指定web服务的地址

实例如下:
<xs:complexType name="selectMaxAgeStudentMethod"> 
  <xs:sequence> 
     <xs:element minOccurs="0" name="arg0" type="tns:customer" />
     <xs:element minOccurs="0" name="arg1" type="tns:customer" />
  </xs:sequence> 
</xs:complexType>

可以在SEI中指定参数和返回值的名称,如:

@WebResult(name = "method") 
Customer selectMaxAgeStudent(@WebParam(name = "c1") Customer c1, 
@WebParam(name = "c2") Customer c2);

客户端

1. 根据wsdl生成java文件

   常用的方式就是 wsdljava –p 包路径–d 目标文件夹 wsdl 的url,如

wsdl2java -p net.ilkj.soap.client –d E:\ http://127.0.0.1:8080/helloService?wsdl

2. 使用JaxWsProxyFactoryBean创建webservice的代理进行调用。

public static void main(String[] args) throws ParseException { 
	JaxWsProxyFactoryBean soapFactoryBean = new JaxWsProxyFactoryBean(); 
	soapFactoryBean.setAddress("http://127.0.0.1:8080/helloService"); 
	soapFactoryBean.setServiceClass(IHelloService.class); 
	
	IHelloService helloService = (IHelloService) soapFactoryBean.create();
	Customer c1 = new Customer(); 
	c1.setId(1); 
	c1.setName("A"); 
	GregorianCalendar calendar = (GregorianCalendar) GregorianCalendar .getInstance(); 
	calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1989-01-28")); 
	c1.setBirthday(new XMLGregorianCalendarImpl(calendar)); 
	Customer c2 = new Customer(); 
	c2.setId(2); 
	c2.setName("B"); 
	calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1990-01-28")); 
	c2.setBirthday(new XMLGregorianCalendarImpl(calendar)); 

	System.out.println(helloService.selectMaxAgeStudent(c1, c2).getName()); 

} 

当wsdl可以访问,webservice 不一定能访问,还和web service的实现有关,wsdl只是接口的一种xml表示

SOAP消息格式

将【实例】中的发布改为使用 JaxWsServerFactoryBean,加入日志拦截器到输入和输出拦截器中。

   1:  public static void main(String[] args) { 
   2:     JaxWsServerFactoryBean soapFactoryBean = new JaxWsServerFactoryBean(); 
   3:     soapFactoryBean.getInInterceptors().add(new LoggingInInterceptor()); 
   4:     soapFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); 
   5:     // 注意这里是实现类不是接口
   6:     soapFactoryBean.setServiceClass(HelloServiceImpl.class); 
   7:     soapFactoryBean.setAddress("http://127.0.0.1:8080/helloService"); 
   8:     soapFactoryBean.create(); 
   9:   
  10:  }
  11:   

效果如下:

<soap:Envelope

<soap:header

<soap:Body

       Inbound Message输出的是服务器端接收到的 SOAP 信息,Outbound Message输出的服务器端响应的 SOAP 信息,SOAP 的 Headers:{}的前面是 SOAP 消息的标识、编码方式、MIME类型,Headers:{}熟悉 HTTP 应该很容易看懂这里面的消息报头的作用,Headers:{}后面的Payload(有效负载,也叫净荷)的 XML 就是 SOAP 消息的真正内容,我们看到 SOAP 消息内容被封装为<soap:Envelope …SOAP 信封,在信封之间的内容就是 SOAP 消息正文。

输入和输出参数

    对参数使用 @WebParam(name=’c2’ mode=Mode.OUT) 可定义参数显示的名称为c2,且为out类型的. Mode可以有IN,OUT,INOUT类型,对于后两种会作为返回值,客户端生成代码是Holder<Customer> c3

服务端 SEI:

@WebService 
<
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个基于Apache CXFweb service的例子: 1. 首先,创建一个Maven项目,并添加以下依赖: ```xml <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.3.7</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.3.7</version> </dependency> </dependencies> ``` 2. 创建一个接口,并定义web service的方法: ```java @WebService public interface GreetingService { @WebMethod String sayHello(String name); } ``` 3. 创建一个实现类,并实现接口中定义的方法: ```java @Service @WebService(endpointInterface = "com.example.demo.GreetingService") public class GreetingServiceImpl implements GreetingService { @Override public String sayHello(String name) { return "Hello, " + name + "!"; } } ``` 4. 在配置文件中配置CXF: ```yaml cxf: servlet: load-on-startup: 1 url-pattern: /services/* jaxws: properties: javax.xml.ws.wsdl.service: GreetingService javax.xml.ws.wsdl.port: GreetingServicePort ``` 5. 部署应用程序并启动服务器,访问以下URL即可访问web service: ``` http://localhost:8080/services/GreetingService?wsdl ``` 6. 测试web service: ```java public class Client { public static void main(String[] args) { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(GreetingService.class); factory.setAddress("http://localhost:8080/services/GreetingService"); GreetingService client = (GreetingService) factory.create(); String result = client.sayHello("World"); System.out.println(result); } } ``` 以上就是一个简单的基于Apache CXFweb service例子。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值