Apache CXF 入门

jopen 11年前

服务端和客户端都是Java Project,先看服务端代码

 

 

首先是SEI

package com.jadyer.service;    import java.util.List;    import javax.jws.WebParam;  import javax.jws.WebResult;  import javax.jws.WebService;    import com.jadyer.model.User;    @WebService(targetNamespace="http://blog.csdn.net/jadyer")  public interface HelloService {   @WebResult(name="sayHelloResult")   public String sayHello(@WebParam(name="name")String name);      /**    * 获取指定编号的用户信息    */   public User getUserByID(int id);      /**    * 只有用户jadyer才可以获取所有用户信息,其它用户只能获取自己的用户信息    */   public List<User> getUserList(User user);  }

下面是SIB

package com.jadyer.service;    import java.util.ArrayList;  import java.util.HashMap;  import java.util.List;  import java.util.Map;    import javax.jws.WebService;    import com.jadyer.model.User;    @WebService(endpointInterface="com.jadyer.service.HelloService", targetNamespace="http://blog.csdn.net/jadyer")  public class HelloServiceImpl implements HelloService {   //模拟的一个内存数据库   private static Map<Integer, User> userMap = new HashMap<Integer, User>();   static{    userMap.put(1, new User(1, "admin", "xuanyu", 11));    userMap.put(2, new User(2, "jadyer", "hongyu", 22));   }      @Override   public String sayHello(String name) {    System.out.println("Receive the name=[" + name + "]");    if(null==name){     return "Hello,World";    }else{     return "Hello," + name;    }   }     @Override   public User getUserByID(int id) {    return userMap.get(id);   }      @Override   public List<User> getUserList(User user) {    List<User> userList = new ArrayList<User>();    if(user.getUsername().equals("jadyer")){     for(Map.Entry<Integer, User> entry : userMap.entrySet()){      userList.add(entry.getValue());     }    }else{     userList.add(user);    }    return userList;   }  }

下面是用到的一个实体类User.java

package com.jadyer.model;    public class User {   private int id;   private String username;   private String password;   private int age;      /*三个属性的setter和getter略*/      public User(){}   public User(int id, String username, String password, int age) {    this.id = id;    this.username = username;    this.password = password;    this.age = age;   }  }

下面是服务端自定义的用于接收SOAPHeader信息的Handler类

package com.jadyer.handler;    import java.util.Iterator;  import java.util.Set;    import javax.xml.namespace.QName;  import javax.xml.soap.SOAPEnvelope;  import javax.xml.soap.SOAPException;  import javax.xml.soap.SOAPHeader;  import javax.xml.soap.SOAPHeaderElement;  import javax.xml.ws.handler.MessageContext;  import javax.xml.ws.handler.soap.SOAPHandler;  import javax.xml.ws.handler.soap.SOAPMessageContext;    public class LicenseHandler implements SOAPHandler<SOAPMessageContext> {   @Override   public Set<QName> getHeaders() {    return null;   }     @Override   public void close(MessageContext context) {}     @Override   public boolean handleFault(SOAPMessageContext context) {    return false;   }     @SuppressWarnings("unchecked")   @Override   public boolean handleMessage(SOAPMessageContext context) {    Boolean isOutBound = (Boolean)context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY);    if(!isOutBound){     SOAPHeader header = null;     try {      SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();      header = envelope.getHeader();      if(null == header){       header = envelope.addHeader();      }     } catch (SOAPException e) {      e.printStackTrace();     }     Iterator<SOAPHeaderElement> iterator = header.getChildElements();     while(iterator.hasNext()){      SOAPHeaderElement headerElement = iterator.next();      if(headerElement.getLocalName().equals("licenseInfo")){       System.out.println("Receive the header=[" + headerElement.getTextContent() + "]");      }     }    }    return true;   }  }

最后是服务端用于发布服务的ServerApp.java

package com.jadyer.server;    import java.util.ArrayList;  import java.util.List;    import javax.xml.ws.handler.Handler;    import org.apache.cxf.interceptor.LoggingInInterceptor;  import org.apache.cxf.interceptor.LoggingOutInterceptor;  import org.apache.cxf.jaxws.JaxWsServerFactoryBean;    import com.jadyer.handler.LicenseHandler;  import com.jadyer.service.HelloService;  import com.jadyer.service.HelloServiceImpl;    public class ServerApp {   @SuppressWarnings("unchecked")   public static void main(String[] args) {    //基于JAX-WS的发布方式    //Endpoint.publish("http://127.0.0.1:8088/myHelloService", new HelloServiceImpl());        //基于CXF的发布方式    JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();    factory.setAddress("http://127.0.0.1:8088/myHelloService");    factory.setServiceClass(HelloService.class);    factory.setServiceBean(new HelloServiceImpl());        //打印接收和响应的SOAP通信报文,这样就不用再使用tcpmon了    factory.getInInterceptors().add(new LoggingInInterceptor());    factory.getOutInterceptors().add(new LoggingOutInterceptor());        //set Handler(只需此步,无需SIB注解@HandlerChain,也不用提供xml文件)    //对于CXF而言,用Handler真的没有多大必要,我们完全可以用它的Interceptor来代替Handler    List<Handler> handlers = new ArrayList<Handler>();    handlers.add(new LicenseHandler());    factory.setHandlers(handlers);        factory.create();   }  }

OK,服务端代码示例完毕,下面是客户端代码</span>

 

 

首先是客户端自定义的用于发送SOAPHeader信息的Handler类

package com.jadyer.handler;    import java.util.Set;    import javax.xml.namespace.QName;  import javax.xml.soap.SOAPEnvelope;  import javax.xml.soap.SOAPException;  import javax.xml.soap.SOAPHeader;  import javax.xml.ws.handler.MessageContext;  import javax.xml.ws.handler.soap.SOAPHandler;  import javax.xml.ws.handler.soap.SOAPMessageContext;    public class LicenseHandler implements SOAPHandler<SOAPMessageContext> {   @Override   public Set<QName> getHeaders() {    return null;   }     @Override   public void close(MessageContext context) {}     @Override   public boolean handleFault(SOAPMessageContext context) {    return false;   }     @Override   public boolean handleMessage(SOAPMessageContext context) {    Boolean isOutBound = (Boolean)context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY);    if(isOutBound){     try {      SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();      SOAPHeader header = envelope.getHeader();      if(null == header){       header = envelope.addHeader();      }      QName qname = new QName("http://blog.csdn.net/jadyer", "licenseInfo", "ns");      header.addHeaderElement(qname).setValue("Jadyer");      return true;     } catch (SOAPException e) {      e.printStackTrace();     }    }    return false;   }  }

最后是客户端调用服务端的模拟入口ClientApp.java

注意:具体客户端代码由CXF提供的wsdj2java生成

package com.jadyer.client;    import java.util.ArrayList;  import java.util.List;    import javax.xml.ws.handler.Handler;    import net.csdn.blog.jadyer.HelloService;  import net.csdn.blog.jadyer.User;    import org.apache.commons.lang.builder.ReflectionToStringBuilder;  import org.apache.commons.lang.builder.ToStringStyle;  import org.apache.cxf.interceptor.LoggingInInterceptor;  import org.apache.cxf.interceptor.LoggingOutInterceptor;  import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;    import com.jadyer.handler.LicenseHandler;    /**   * 使用CXF提供的wsdj2java   * 1)将D:\Develop\apache-cxf-2.7.0\bin加入环境变量path中   * 2)使用CXF提供的wsdl2java.bat生成客户端代码,其用法与JAX-WS的wsimport基本相同   *   wsdl2java -d D:/Download/ -frontend jaxws21 -keep -verbose http://127.0.0.1:8088/myHelloService?wsdl   * 补充:wsimport用法见-->http://blog.csdn.net/jadyer/article/details/8692108   * @create May 30, 2013 5:09:13 PM   * @author 玄玉<http://blog.csdn.net/jadyer>   */  public class ClientApp {   @SuppressWarnings("unchecked")   public static void main(String[] args) {    /**     * 基于JAX-WS的客户端调用方式     */    //System.out.println(new HelloServiceService().getHelloServicePort().sayHello("玄玉"));    /**     * 基于CXF的客户端调用方式     */    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();    factory.setAddress("http://127.0.0.1:8088/myHelloService");    factory.setServiceClass(HelloService.class);    factory.getInInterceptors().add(new LoggingInInterceptor());    factory.getOutInterceptors().add(new LoggingOutInterceptor());    List<Handler> handlers = new ArrayList<Handler>();    handlers.add(new LicenseHandler());    factory.setHandlers(handlers);    HelloService hello = (HelloService)factory.create();    //System.out.println(hello.sayHello("玄玉"));    //System.out.println(ReflectionToStringBuilder.toString(hello.getUserByID(2), ToStringStyle.MULTI_LINE_STYLE));    User user = new User();    user.setUsername("jadyer");    List<User> userList = hello.getUserList(user);    for(User uu : userList){     System.out.println(ReflectionToStringBuilder.toString(uu, ToStringStyle.MULTI_LINE_STYLE));    }   }  }

最后再把控制台输出贴出来</span>

 

 

下面是服务端的控制台输出

2013-5-31 22:28:59 org.apache.cxf.services.HelloServiceService.HelloServicePort.HelloService  信息: Inbound Message  ----------------------------  ID: 4  Address: http://127.0.0.1:8088/myHelloService  Encoding: UTF-8  Http-Method: POST  Content-Type: text/xml; charset=UTF-8  Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[351], content-type=[text/xml; charset=UTF-8], Host=[127.0.0.1:8088], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 2.7.0]}  Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><ns:licenseInfo xmlns:ns="http://blog.csdn.net/jadyer">Jadyer</ns:licenseInfo></soap:Header><soap:Body><ns2:getUserList xmlns:ns2="http://blog.csdn.net/jadyer"><arg0><age>0</age><id>0</id><username>jadyer</username></arg0></ns2:getUserList></soap:Body></soap:Envelope>  --------------------------------------  Receive the header=[Jadyer]  2013-5-31 22:28:59 org.apache.cxf.services.HelloServiceService.HelloServicePort.HelloService  信息: Outbound Message  ---------------------------  ID: 4  Encoding: UTF-8  Content-Type: text/xml  Headers: {}  Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header/><soap:Body><ns2:getUserListResponse xmlns:ns2="http://blog.csdn.net/jadyer"><return><age>11</age><id>1</id><password>xuanyu</password><username>admin</username></return><return><age>22</age><id>2</id><password>hongyu</password><username>jadyer</username></return></ns2:getUserListResponse></soap:Body></soap:Envelope>  --------------------------------------

下面是客户端的控制台输出</span>

2013-5-31 22:28:58 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass  信息: Creating Service {http://blog.csdn.net/jadyer}HelloServiceService from class net.csdn.blog.jadyer.HelloService  2013-5-31 22:28:59 org.apache.cxf.services.HelloServiceService.HelloServicePort.HelloService  信息: Outbound Message  ---------------------------  ID: 1  Address: http://127.0.0.1:8088/myHelloService  Encoding: UTF-8  Http-Method: POST  Content-Type: text/xml  Headers: {Accept=[*/*], SOAPAction=[""]}  Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><ns:licenseInfo xmlns:ns="http://blog.csdn.net/jadyer">Jadyer</ns:licenseInfo></soap:Header><soap:Body><ns2:getUserList xmlns:ns2="http://blog.csdn.net/jadyer"><arg0><age>0</age><id>0</id><username>jadyer</username></arg0></ns2:getUserList></soap:Body></soap:Envelope>  --------------------------------------  2013-5-31 22:28:59 org.apache.cxf.services.HelloServiceService.HelloServicePort.HelloService  信息: Inbound Message  ----------------------------  ID: 1  Response-Code: 200  Encoding: UTF-8  Content-Type: text/xml;charset=UTF-8  Headers: {content-type=[text/xml;charset=UTF-8], Server=[Jetty(8.1.7.v20120910)], transfer-encoding=[chunked]}  Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header/><soap:Body><ns2:getUserListResponse xmlns:ns2="http://blog.csdn.net/jadyer"><return><age>11</age><id>1</id><password>xuanyu</password><username>admin</username></return><return><age>22</age><id>2</id><password>hongyu</password><username>jadyer</username></return></ns2:getUserListResponse></soap:Body></soap:Envelope>  --------------------------------------  net.csdn.blog.jadyer.User@168497f6[    age=11    id=1    password=xuanyu    username=admin  ]  net.csdn.blog.jadyer.User@27db0da1[    age=22    id=2    password=hongyu    username=jadyer  ]