CXF创建WebService实例


一、概述
1、ApacheCXF项目是由ObjectWeb Celtix和CodeHaus XFire合并成立。ObjectWeb Celtix是
由IONA公司赞助,于2005年成立的开源Java ESB产品,XFire则是业界知名的SOAP堆栈。
合并后的ApacheCXF融合该两个开源项目的功能精华,提供了实现SOA所需要的核心ESB功能框架,
包括SOA服务创建,服务路由,及一系列企业级QoS功能。
2.支持标准
(1)JAX-WS, JSR-181, SAAJ, JAX-RS
(2)SOAP 1.1, 1.2, WS-I BasicProfile, WS-Security, WS-Addressing, WS-RM, WS-Policy
(3)WSDL 1.1
(4)MTOM
3.传输方式,绑定,数据绑定,传送数据格式
(1)绑定: SOAP, REST/HTTP
(2)数据绑定: JAXB 2.x, Aegis, XMLBeans, SDO
(3)传送数据格式: XML, JSON, FastInfoset
(4)传输方式: HTTP, Servlet, JMS

二、基于SOAP发布webservice

(1)pom.xml文件中导入CXF相关包
Xml代码  收藏代码
<dependency>  
    <groupId>org.apache.cxf</groupId>  
    <artifactId>cxf-rt-core</artifactId>  
    <version>2.6.2</version>                  
</dependency>  
<dependency>  
    <groupId>org.apache.cxf</groupId>  
    <artifactId>cxf-rt-frontend-jaxws</artifactId>  
    <version>2.6.2</version>                  
</dependency>  
<dependency>  
    <groupId>org.apache.cxf</groupId>  
    <artifactId>cxf-rt-transports-http</artifactId>  
    <version>2.6.2</version>  
</dependency>

 

(2)web.xml文件中配置
Xml代码  收藏代码
<servlet>  
<servlet-name>CXFServlet</servlet-name>       
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>  
</servlet>  
<servlet-mapping>  
<servlet-name>CXFServlet</servlet-name>  
<url-pattern>/cxf/*</url-pattern>  
</servlet-mapping> 


(3)创建webService接口UserService
Java代码  收藏代码
package com.icsshs.dmis.webservice.soap;  
import javax.jws.WebParam;  
import javax.jws.WebService;  
import com.icsshs.dmis.webservice.soap.response.UserDTO;  
/** 
* JAX-WS2.0的WebService接口定义类 *  
* 使用JAX-WS2.0 annotation设置WSDL中的定义. 
* 使用WSResult及其子类包裹返回结果. 
* 使用DTO传输对象隔绝系统内部领域对象的修改对外系统的影响. 
*  
*/  
//name 指明wsdl中<wsdl:portType>元素的名称  
@WebService(name = "UserService", targetNamespace = WsConstants.NS)  
public interface UserService {  
  
    //@WebService是必须的;@WebParam不是必须的。  
    //如果没有@WebParam的描述,在wsdl文件内描述的方法中,参数名将变为arg0,arg1…以此类推.  
    public String getUserName(@WebParam(name = "userId")String userId);  
    public UserDTO getUser(@WebParam(name = "userId")String userId);  
} 




UserService接口实现类:
Java代码  收藏代码
package com.icsshs.dmis.webservice.soap;  
import javax.jws.WebService;  
import com.icsshs.dmis.webservice.soap.response.UserDTO;  
/** 
* WebService服务端实现类. 
*/  
//serviceName指明WSDL中<wsdl:service>与<wsdl:binding>元素的名称,  
//endpointInterface属性指向Interface类全称.  
@WebService(serviceName = "UserService",   
        endpointInterface = "com.icsshs.dmis.webservice.soap.UserService",  
targetNamespace = WsConstants.NS)  
public class UserServiceImpl implements UserService {  
    @Override  
    public UserDTO getUser(String userId) {  
        UserDTO dto = new UserDTO();  
        dto.setId(Long.parseLong("1001"));  
        dto.setLoginName("dongwq");  
        dto.setName("张三");  
        dto.setEmail("[email protected]");  
        return dto;  
    }  
  
    @Override  
    public String getUserName(String userId) {  
        return "dongwq";  
    }  
}  


传输的对象UserDTO类:
Java代码  收藏代码
package com.icsshs.dmis.webservice.soap.response;  
import javax.xml.bind.annotation.XmlRootElement;  
import javax.xml.bind.annotation.XmlType;  
import org.apache.commons.lang3.builder.ToStringBuilder;  
import com.icsshs.dmis.webservice.soap.WsConstants;  
/** 
* Web Service传输User信息的DTO.*  
* 只传输外部接口需要的属性.使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.*  
* @XmlRootElement指定User为XML的根元素。User类的属性默认指定映射为@XmlElement。 
* @XmlElement用来定义XML中的子元素。 
* @XmlType-映射一个类或一个枚举类型成一个XML Schema类型 
*/  
@XmlRootElement  
@XmlType(name = "User", namespace = WsConstants.NS)  
public class UserDTO {  
    private Long id;  
    private String loginName;  
    private String name;  
    private String email;  
    // 相关get、set方法省略。  
}  


统一命名空间类定义:
Java代码  收藏代码
public class WsConstants {  
    /**项目内统一的NameSpace定义.**/  
    /**wsdl2java生成客户端代码时默认按定义的namespace倒序生成包路径 **/  
    public static final String NS = "http://soap.webservice.dmis.icsshs.com";  
}  


(4)在spring的applicationContext.xml文件中进行配置:
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:jaxws="http://cxf.apache.org/jaxws"  
    xsi:schemaLocation="http://cxf.apache.org/jaxws   
    http://cxf.apache.org/schemas/jaxws.xsd   
    http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"  
    default-lazy-init="true">  
  
<description>SOAP Web Service配置</description>  
<!--  
1、访问接口服务:http://localhost:8080/dmis/cxf/soap/userService?wsdl  
2、访问接口中的方法:  
http://localhost:8080/dmis/cxf/soap/userService/getUserName?userId=aaa  
或:http://localhost:8080/dmis/cxf/soap/userService/getUserName?arg0=aaa  
-->  
<!-- jax-ws endpoint定义  -->  
<jaxws:endpoint address="/soap/userService">  
<jaxws:implementor ref="userService" />  
</jaxws:endpoint>  
<!-- WebService的实现Bean定义 -->  
<bean id="userService" class="com.icsshs.dmis.webservice.soap.UserServiceImpl" />  
</beans> 



(5)启动web应用,测试webservice应用是否发布成功。
访问:http://localhost:8080/dmis/cxf/soap/userService?wsdl

三、基于SOAP的客户端调用

(1)通过代理API调用,依赖于服务端的接口
Java代码  收藏代码
/** 
* 通过代理API调用,依赖于服务端的接口 
*/  
public static void testClientByProxy(){  
    // 调用WebService  
    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();  
    factory.setServiceClass(UserService.class);  
    factory.setAddress("http://localhost:8080/dmis/cxf/soap/userService");  
    UserService service = (UserService) factory.create();  
    UserDTO user = service.getUser("1001");  
    System.out.println(user.getName());  
}  


(2)不依赖服务端的接口
Java代码  收藏代码
/** 
* 不依赖服务端的接口 
* @throws Exception  
*/  
public static void testClient() throws Exception{  
    //不依赖服务器端接口来完成调用的,也就是不仅仅能调用Java的接口   
    JaxWsDynamicClientFactory clientFactory =   
        JaxWsDynamicClientFactory.newInstance();   
    Client client = clientFactory.createClient(  
            "http://localhost:8080/dmis/cxf/soap/userService?wsdl");   
    Object[] result = client.invoke("getUserName", "1001");   
    System.out.println(result[0]);  
}  


(3)先通过wsdl2Java生成客户端代码,再进行调用
Java代码  收藏代码
/** 
* 先通过wsdl2Java生成客户端代码,再进行调用 
*/  
public static void testClient2() {  
    UserService_Service serivce = new UserService_Service();  
    UserService impl = serivce.getUserServiceImplPort();  
    String userName = impl.getUserName("1001");  
    System.out.println(userName);  
}  



四、基于JAX-RS的方式发布WebService

(1)pom.xml文件中导入CXF相关包
Xml代码  收藏代码
<dependency>  
    <groupId>org.apache.cxf</groupId>  
    <artifactId>cxf-rt-frontend-jaxrs</artifactId>  
    <version>2.6.2</version>  
</dependency>  
<dependency>  
    <groupId>com.fasterxml.jackson.jaxrs</groupId>  
    <artifactId>jackson-jaxrs-json-provider</artifactId>  
    <version>2.0.5</version>  
</dependency>  


(2)web.xml文件中配置,同上
Xml代码  收藏代码
<servlet>  
<servlet-name>CXFServlet</servlet-name>       
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>  
</servlet>  
<servlet-mapping>  
<servlet-name>CXFServlet</servlet-name>  
<url-pattern>/cxf/*</url-pattern>  
</servlet-mapping>  


(3)创建webService接口UserJaxRsService
Java代码  收藏代码
package com.icsshs.dmis.webservice.jaxrs;  
import java.io.IOException;  
import javax.ws.rs.GET;  
import javax.ws.rs.POST;  
import javax.ws.rs.Path;  
import javax.ws.rs.PathParam;  
import javax.ws.rs.Produces;  
import javax.ws.rs.WebApplicationException;  
import javax.ws.rs.core.MediaType;  
import javax.ws.rs.core.Response;  
import javax.ws.rs.core.Response.Status;  
import org.springframework.beans.factory.annotation.Autowired;  
import com.icsshs.dmis.entity.bi.BiPerson;  
import com.icsshs.dmis.service.bi.BiService;  
import com.icsshs.dmis.webservice.soap.response.UserDTO;  
  
@Path("/user")  
public class UserJaxRsService {  
    @Autowired  
    private BiService biService;//业务系统类接口,省略  
  
    @GET  
    @Path("/{personCode}.xml")  
    @Produces(MediaType.APPLICATION_XML)  
    public UserDTO getAsXml(@PathParam("personCode") String personCode) {  
        BiPerson person = biService.findBiPersonByPersonCode(personCode);  
        if (person == null) {  
            String message = "用户不存在(id:" + personCode + ")";  
            throw buildException(Status.NOT_FOUND, message);  
        }  
        UserDTO dto = new UserDTO();  
        dto.setName(person.getPersonName());  
        dto.setLoginName(person.getR1PersonId());  
        return dto;  
    }  
  
    @GET  
    @Path("/{personCode}.json")  
    @Produces(MediaType.APPLICATION_JSON)  
    public UserDTO getAsJson(@PathParam("personCode") String personCode) {  
        BiPerson person = biService.findBiPersonByPersonCode(personCode);  
        if (personCode == null) {  
            String message = "用户不存在(id:" + personCode + ")";  
            throw buildException(Status.NOT_FOUND, message);  
        }  
        UserDTO dto = new UserDTO();  
        dto.setName(person.getPersonName());  
        dto.setLoginName(person.getR1PersonId());  
        return dto;  
    }  
  
    @POST  
    @Path("/addUser")  
    @Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })  
    public UserDTO addUser(UserDTO user) throws IOException {  
        System.out.println(user);  
        user.setName("jojo##12321321");  
        return user;  
    }  
  
    private WebApplicationException buildException(Status status, String message){  
        return new WebApplicationException(Response.status(status).entity(  
            message).type(MediaType.TEXT_PLAIN).build());  
    }  
}  


(4)在spring的applicationContext.xml文件中进行配置:
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:jaxrs="http://cxf.apache.org/jaxrs"  
xsi:schemaLocation="http://cxf.apache.org/jaxrs   
http://cxf.apache.org/schemas/jaxrs.xsd   
http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"  
default-lazy-init="true">  
<description>Apache CXF的Restful Web Service配置</description>  
<!-- jax-rs endpoint定义  -->  
<jaxrs:server id="serviceContainer" address="/jaxrs">  
<jaxrs:serviceBeans>  
    <ref bean="userJaxRsService" />  
</jaxrs:serviceBeans>  
<jaxrs:providers>  
    <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" />  
</jaxrs:providers>  
</jaxrs:server>  
<!-- WebService的实现Bean定义 -->  
<bean id="userJaxRsService"   
      class="com.icsshs.dmis.webservice.jaxrs.UserJaxRsService" />  
</beans>  


(5)启动web应用,测试webservice应用是否发布成功。
访问:http://localhost:8080/dmis/cxf/jaxrs?_wadl

五、基于JAX-RS的Restful客户端调用
(1)依赖服务端的接口,通过代理API调用
Java代码  收藏代码
/** 
* 依赖服务端的接口 
* 代理API允许你使用RESTful服务的资源类和接口。 
* 代理类是客户端直接调用接口方法,使用户不需要手工创建HTTP请求。 
*/  
public static void testClientByProxy(){       
    UserJaxRsService store = JAXRSClientFactory  
            .create("http://localhost:8080/dmis/cxf/jaxrs",   
                    UserJaxRsService.class);  
    System.out.println(store.getAsXml("15811006"));  
}  


(2)通过HTTP客户端进行调用
Java代码  收藏代码
/** 
* HTTP客户端 
* 使用org.apache.cxf.jaxrs.client.WebClient调用RESTful服务 
* 
*/  
public static void testClientByHttp(){        
    String format = MediaType.APPLICATION_XML;  
    WebClient client = WebClient.create("http://localhost:8080/dmis/cxf/jaxrs");     
    client.path("/user/15811006.xml").accept(format).type(format);     
    UserDTO user = client.get(UserDTO.class);         
    System.out.println("userName: " + user.getName());        
}  


3、通过HTTP客户端进行调用,并传递对象
Java代码  收藏代码
/** 
* HTTP客户端(传递对象)   
* 
*/  
public static void testClientByObject(){          
    String format = MediaType.APPLICATION_XML;  
    System.out.println("testAddCategory called with format " );     
    WebClient client = WebClient.create("http://localhost:8080/dmis/cxf/jaxrs");     
    client.path("/user/addUser").accept(format).type(format);     
    UserDTO userDTO = new UserDTO();  
    userDTO.setName("userName");  
    userDTO.setLoginName("loginName");  
    UserDTO returnUser = client.post(userDTO,UserDTO.class);          
    System.out.println("userName: " + returnUser.getName()  
            +" lgoinName: "+returnUser.getLoginName());        
} 


注:HTTP客户端调用时,如果不依赖于服务端接口,可通过wsdl2java或wadl2java生成客户端代码。

你可能感兴趣的:(CXF创建WebService实例)