zoukankan      html  css  js  c++  java
  • [转] WebService开发笔记 1 -- 利用cxf开发WebService竟然如此简单

    以下文章来自   http://www.blogjava.net/jacally/articles/186655.html

    现在的项目中需要用到SOA概念的地方越来越多,最近我接手的一个项目中就提出了这样的业务要求,需要在.net开发的客户端系统中访问java开发的web系统,这样的业务需求自然需要通过WebService进行信息数据的操作。下面就将我们在开发中摸索的一点经验教训总结以下,以供大家参考. 

    我们项目的整个架构使用的比较流行的WSH MVC组合,即webwork2 + Spring + Hibernate; 
    1.首先集成Apacha CXF WebService 到 Spring 框架中; 
    apache cxf 下载地址:http://people.apache.org/dist/incubator/cxf/2.0.4-incubator/apache-cxf-2.0.4-incubator.zip 
    在spring context配置文件中引入以下cxf配置 

    	<import resource="classpath*:META-INF/cxf/cxf.xml" />
    <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />


    在web.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>/services/*</url-pattern>
    </servlet-mapping>



    2.开发服务端WebService接口: 

    /**
    * WebService接口定义类.
    *
    * 使用@WebService将接口中的所有方法输出为Web Service.
    * 可用annotation对设置方法、参数和返回值在WSDL中的定义.
    */
    @WebService
    public interface WebServiceSample {


    /**
    * 一个简单的方法,返回一个字符串
    * @param hello
    * @return
    */
    String say(String hello);

    /**
    * 稍微复杂一些的方法,传递一个对象给服务端处理
    * @param user
    * @return
    */
    String sayUserName(
    @WebParam(name = "user")
    UserDTO user);

    /**
    * 最复杂的方法,返回一个List封装的对象集合
    * @return
    */
    public
    @WebResult(partName="o")
    ListObject findUsers();

    }


    由简单到复杂定义了三个接口,模拟业务需求; 

    3.实现接口 

    /**
    * WebService实现类.
    *
    * 使用@WebService指向Interface定义类即可.
    */
    @WebService(endpointInterface = "cn.org.coral.biz.examples.webservice.WebServiceSample")
    public class WebServiceSampleImpl implements WebServiceSample {

    public String sayUserName(UserDTO user) {
    return "hello "+user.getName();
    }

    public String say(String hello) {
    return "hello "+hello;
    }

    public ListObject findUsers() {
    ArrayList<Object> list = new ArrayList<Object>();

    list.add(instancUser(1,"lib"));
    list.add(instancUser(2,"mld"));
    list.add(instancUser(3,"lq"));
    list.add(instancUser(4,"gj"));
    ListObject o = new ListObject();
    o.setList(list);
    return o;
    }

    private UserDTO instancUser(Integer id,String name){
    UserDTO user = new UserDTO();
    user.setId(id);
    user.setName(name);
    return user;
    }
    }



    4.依赖的两个类:用户对象与List对象 

    /**
    * Web Service传输User信息的DTO.
    *
    * 分离entity类与web service接口间的耦合,隔绝entity类的修改对接口的影响.
    * 使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.
    *
    */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "User")
    public class UserDTO {

    protected Integer id;

    protected String name;

    public Integer getId() {
    return id;
    }

    public void setId(Integer value) {
    id = value;
    }

    public String getName() {
    return name;
    }

    public void setName(String value) {
    name = value;
    }
    }


    关于List对象,参照了有关JWS的一个问题中的描述:DK6.0 自带的WebService中 WebMethod的参数好像不能是ArrayList 或者其他List 
    传递List需要将List 包装在其他对象内部才行 (个人理解 如有不对请指出) ,我在实践中也遇到了此类问题.通过以下封装的对象即可以传递List对象. 

    /**
    * <p>Java class for listObject complex type.
    *
    * <p>The following schema fragment specifies the expected content contained within this class.
    *
    * <pre>
    * <complexType name="listObject">
    * <complexContent>
    * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
    * <sequence>
    * <element name="list" type="{http://www.w3.org/2001/XMLSchema}anyType" maxOccurs="unbounded" minOccurs="0"/>
    * </sequence>
    * </restriction>
    * </complexContent>
    * </complexType>
    * </pre>
    *
    *
    */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "listObject", propOrder = { "list" })
    public class ListObject {

    @XmlElement(nillable = true)
    protected List<Object> list;

    /**
    * Gets the value of the list property.
    *
    * <p>
    * This accessor method returns a reference to the live list,
    * not a snapshot. Therefore any modification you make to the
    * returned list will be present inside the JAXB object.
    * This is why there is not a <CODE>set</CODE> method for the list property.
    *
    * <p>
    * For example, to add a new item, do as follows:
    * <pre>
    * getList().add(newItem);
    * </pre>
    *
    *
    * <p>
    * Objects of the following type(s) are allowed in the list
    * {@link Object }
    *
    *
    */
    public List<Object> getList() {
    if (list == null) {
    list = new ArrayList<Object>();
    }
    return this.list;
    }

    public void setList(ArrayList<Object> list) {
    this.list = list;
    }

    }



    5.WebService 服务端 spring 配置文件 ws-context.xml 

    <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.xsd"
    default-autowire="byName" default-lazy-init="true">

    <jaxws:endpoint id="webServiceSample"
    address="/WebServiceSample" implementor="cn.org.coral.biz.examples.webservice.WebServiceSampleImpl"/>

    </beans>



    WebService 客户端 spring 配置文件 wsclient-context.xml 

    <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.xsd"
    default-autowire="byName" default-lazy-init="true">

    <!-- ws client -->
    <bean id="identityValidateServiceClient" class="cn.org.coral.admin.service.IdentityValidateService"
    factory-bean="identityValidateServiceClientFactory" factory-method="create" />

    <bean id="identityValidateServiceClientFactory"
    class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
    <property name="serviceClass"
    value="cn.org.coral.admin.service.IdentityValidateService" />
    <property name="address"
    value="http://88.148.29.54:8080/coral/services/IdentityValidateService"/>
    </bean>

    </beans>


    6.发布到tomcat服务器以后通过以下地址即可查看自定义的webservice接口生成的wsdl: 
    http://88.148.29.54:8080/aio/services/WebServiceSample?wsdl 

    7.调用WebService接口的Junit单元测试程序 

    package test.coral.sample;

    import org.springframework.test.AbstractDependencyInjectionSpringContextTests;

    import cn.org.coral.biz.examples.webservice.WebServiceSample;
    import cn.org.coral.biz.examples.webservice.dto.UserDTO;

    public class TestWebServiceSample extends
    AbstractDependencyInjectionSpringContextTests {
    WebServiceSample webServiceSampleClient;

    public void setWebServiceSampleClient(WebServiceSample webServiceSampleClient) {
    this.webServiceSampleClient = webServiceSampleClient;
    }

    @Override
    protected String[] getConfigLocations() {
    setAutowireMode(AUTOWIRE_BY_NAME);
    //spring 客户端配置文件保存位置
    return new String[] { "classpath:/cn/org/coral/biz/examples/webservice/wsclient-context.xml" };
    }

    public void testWSClinet(){
    Assert.hasText(webServiceSampleClient.say(" world"));
    }
    }
  • 相关阅读:
    架设证书服务器 及 让IIS启用HTTPS服务
    实验二. 使用LoadRunner进行压力测试
    loadrunner简单使用——HTTP,WebService,Socket压力测试脚本编写
    康威定律,可以学习一下
    各国iPhone5系列最新裸机价格
    .yml是什么文件
    win32多线程程序设计笔记(第五章)
    kvm libvirt: hostdev passthrough support 解决加密狗冲突问题
    九度OnlineJudge之1023:EXCEL排序
    [置顶] Android开发之XML文件的解析
  • 原文地址:https://www.cnblogs.com/jianglong-liang/p/4171289.html
Copyright © 2011-2022 走看看