zoukankan      html  css  js  c++  java
  • CXF

    相关dependency,我使用的版本是2.7.11:

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>${cxf.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>${cxf.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http-jetty</artifactId>
        <version>${cxf.version}</version>
    </dependency>

    以一个简单的Service为例:

    import javax.jws.WebMethod;
    import javax.jws.WebService;
    @WebService
    public interface MyCxfService {
        @WebMethod
        String saySth(String content);
    }

    以及其实现:

    import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
    import pac.testcase.ws.MyCxfService;
    public class MyCxfServiceImpl implements MyCxfService {
        public String saySth(String content) {
            return "I say "+content;
        }
    }

    启动服务:

    JaxWsServerFactoryBean server = new JaxWsServerFactoryBean();
    server.setServiceClass(MyCxfServiceImpl.class);
    server.setAddress("http://localhost:8686/ws/service");
    server.create();

    调用服务:

    JaxWsProxyFactoryBean client = new JaxWsProxyFactoryBean();
    client.setServiceClass(MyCxfService.class);
    client.setAddress("http://localhost:8686/ws/service");
    MyCxfService service = (MyCxfService)client.create();
    System.out.println(service.saySth("nothing but performance!!"));

    CXF是通过Spring为service提供XML配置的。
    需要用Servlet Listener装载Spring后加入CXF相关的Servlet。
    也就是说:

    <servlet>
      <servlet-name>CXFServlet</servlet-name>
      <display-name>CXF Servlet</display-name>
      <servlet-class>
         org.apache.cxf.transport.servlet.CXFServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    在spring的配置文件中加入:

    xmlns:jaxws="http://cxf.apache.org/jaxws"
    
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd

    继续用上一个例子中的Service接口,简单做一下配置:

    <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"/>
    
    <jaxws:endpoint implementor="pac.king.webservice.impl.MyCxfServiceImpl" address="/MyCxfService"  />

    访问:http://localhost:8080/runtrain/services/,会出现下面的效果

    客户端方面,可以使用jaxws:client配置让他调用本地bean那样简单:

    <jaxws:client id="MyCxfClient" address="http://localhost:8080/runtrain/services/MyCxfService" serviceClass="pac.king.webservice.MyCxfService" />

    如果不使用则相当于:

    <bean id="MyCxfClient" factory-bean="clientFactory" factory-method="create"/>
    <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"
        p:serviceClass="pac.king.webservice.MyCxfService"
        p:address="http://localhost:8080/runtrain/services/MyCxfService"
    />

    远程调用变得透明:

    ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext*.xml");
    MyCxfService client = (MyCxfService)context.getBean("MyCxfClient");
    System.out.println(client.saySth("nothing but show!!"));

    曾经想过一个问题,为什么我自己定义个User类什么的都可以传输,而Map却不可以?
    天天堆砌API导致很多人把这个Map想得太简单了,换个立场想想,XSD如何去表示Map这种东西?
    JAXB(Java Architecture for XML Binding)可以解决这个问题!
    简单说来就是:
    Java Architecture for XML Binding (JAXB) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects.

    这里引用一下wiki中XSD与JAXB对对照:

    XML Schema TypeJava Data Type
    xsd:string java.lang.String
    xsd:integer java.math.BigInteger
    xsd:positiveInteger java.math.BigInteger
    xsd:int int
    xsd:long long
    xsd:short short
    xsd:decimal java.math.BigDecimal
    xsd:float float
    xsd:double double
    xsd:boolean boolean
    xsd:byte byte
    xsd:QName javax.xml.namespace.QName
    xsd:dateTime javax.xml.datatype.XMLGregorianCalendar
    xsd:base64Binary byte[]
    xsd:hexBinary byte[]
    xsd:unsignedInt long
    xsd:unsignedShort int
    xsd:unsignedByte short
    xsd:unsignedLong java.math.BigDecimal
    xsd:time javax.xml.datatype.XMLGregorianCalendar
    xsd:date javax.xml.datatype.XMLGregorianCalendar
    xsd:g javax.xml.datatype.XMLGregorianCalendar
    xsd:anySimpleType java.lang.Object
    xsd:anySimpleType java.lang.String
    xsd:duration javax.xml.datatype.Duration
    xsd:NOTATION javax.xml.namespace.QName

    简单记录一下操作步骤。
    首先我需要写一个Adapter来进行marsal/unmarshal。
    可以使用javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>
    简单说来就是用前者解释后者,引用一下javaDoc中对ValueType与BoundType的说明:

    * @param <BoundType>
    *      The type that JAXB doesn't know how to handle. An adapter is written
    *      to allow this type to be used as an in-memory representation through
    *      the <tt>ValueType</tt>.
    * @param <ValueType>
    *      The type that JAXB knows how to handle out of the box.

    我现在试着写一个返回Map的方法,但是我不能用java.util.Map,因为JAXB无法处理interface。
    于是我这样定义我的服务:

    import java.util.HashMap;
    import javax.jws.WebMethod;
    import javax.jws.WebParam;
    import javax.jws.WebResult;
    import javax.jws.WebService;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    import pac.king.pojo.User;
    import pac.king.webservice.utils.MyMapAdapter;
    @WebService
    public interface MyCxfService {
        @WebMethod
        @XmlJavaTypeAdapter(MyMapAdapter.class)
        public @WebResult HashMap<String,String> convertUserInfoToMap(@WebParam User user);
    }

    以及实现:

    import java.util.HashMap;
    import pac.king.pojo.User;
    import pac.king.webservice.MyCxfService;
    public class MyCxfServiceImpl implements MyCxfService {
        public HashMap<String, String> convertUserInfoToMap(User user) {
            HashMap<String,String> result = new HashMap<String, String>();
            result.put("name", user.getName());
            result.put("id", user.getId());
            result.put("password", user.getPassword());
            return result;
        }
    }

    写User时需要提供一个没有参数的constructor:

    package pac.king.pojo;
    public class User {
                                                                                                                                                                         
        private String id;
        private String name;
        private String password;
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public User() {}
        public User(String id, String name, String password) {
            super();
            this.id = id;
            this.name = name;
            this.password = password;
        }
    }

    注意服务方法上的注解@XmlJavaTypeAdapter(MyMapAdapter.class)。
    这是继承XmlAdapter写的一个Adapter:

    import java.util.HashMap;
    import java.util.Map.Entry;
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    public class MyMapAdapter extends XmlAdapter<MyGeneralBean[], HashMap<String,String>>{
        @Override
        public HashMap<String, String> unmarshal(MyGeneralBean[] v)
                throws Exception {
            HashMap<String,String> resultMap = new HashMap<String, String>();
            for (MyGeneralBean e : v) {
                resultMap.put(e.getKey(), e.getValue());
            }
            return resultMap;
        }
        @Override
        public MyGeneralBean[] marshal(HashMap<String, String> v) throws Exception {
            MyGeneralBean[] m = new MyGeneralBean[10];
            int i=0;
            for (Entry<String, String> entry : v.entrySet()) {
                m[++i] = new MyGeneralBean(entry.getKey(), entry.getValue());
            }
            return m;
        }
                                                                                                                          
    }

    MyGeneralBean是用来解释Map结构的一个简单类型,这个也需要提供一个无参数的constructor:

    public class MyGeneralBean {
        private String key;
        private String value;
        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        public MyGeneralBean() {}
        public MyGeneralBean(String key, String value) {
            super();
            this.key = key;
            this.value = value;
        }
                                                      
    }

    这样就可以调用了,继续使用上一个例子中的jaxws:client配置,直接使用服务。

    ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext*.xml");
            MyCxfService client = (MyCxfService) context.getBean("MyCxfClient");
            Map<String,String> map = client.convertUserInfoToMap(new User("100001","King.","t;stmdtkg"));
            System.out.println(map.get("id"));
            System.out.println(map.get("name"));
            System.out.println(map.get("password"));
  • 相关阅读:
    IDA 动态调试 ELF 文件
    双机调试环境搭建[win7+Windbg+VirtualKD]
    从域环境搭建到 MS14-068 提升为域权限
    栈溢出原理与 shellcode 开发
    Flask_0x05 大型程序结构
    rest-framework 框架的基本组件
    restful 规范
    Django的CBV和FBV
    Django-model 进阶
    Django-Ajax
  • 原文地址:https://www.cnblogs.com/kavlez/p/4071951.html
Copyright © 2011-2022 走看看