一:导包----apache-cxf-2.6.2\lib
maven添加cfx
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf</artifactId>
<version>2.6.2</version>
</dependency>
2:编写服务器代码
/**
*
*/
package com.hoo.service;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
/**
* @author Administrator
*
*/
@WebService
@SOAPBinding(style=Style.RPC)
public class HelloWorldService {
public String sayHello(@WebParam(name = "name")String name){
return name += " say: Hello World ";
}
}
3:编写发布服务器类
在服务器类的main方法中
HelloWorldService service = new HelloWorldService();
String address = "http://localhost:8080/helloWorld";
Endpoint.publish(address, service);
4:定制客户端调用webservice的接口
@WebService
publicinterface IHelloWorldService {
public String sayHello(@WebParam(name = "name") String name);
}
5:编写客户端调用WebService代码
publicclass HelloWorldServiceClient {
publicstaticvoid main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(IHelloWorldService.class);
factory.setAddress("http://localhost:8080/helloWorld");
IHelloWorldService service = (IHelloWorldService)factory.create();
System.out.println("[result]"+service.sayHello("hoojo"));
}
}
6:添加拦截器
例如:
MesssageInterceptor extends AbstractPhaseInterceptor<Message>
实现public void handleMessage(Message message)方法
然后再发布拦截器
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factroy.setServiceClass(HelloWorldService.class);
factory.setAddress("http://localhost:8080/helloWorld");
factory.setServiceBean(new HelloWorldService());
factory.getInInterceptors().add(new MesssageInterceptor(Phase.Receive));
factory.getInInterceptors().add(new MesssageInterceptor(Phase.SEND));
factory.create();
7:再从客户端调用,会执行拦截器
8:传递复杂类型对象
通过POJO,然后再组合成集合类,然后再发布,最终客户端执行调用;
9:CXF整合Spring
9.1:导包
9.2:新建applicationContext-Server.xml文件
9.3:编写服务器代码----接口、实现类
9.4:编写applicationContext-server.xml
9.5:编写客户端
9.6:application-client.xml
9.7:客户端请求代码
不是CXF去读取那些文件,主动权在Spring这里。Spring读取配置的例如:applicationContext-webservice.xml 。如果是server端,spring会实例化工厂JaxWsServerFactoryBean,根据配置发布服务。
如果是client端,spring会实例化工厂JaxWsProxyFactoryBean,生成soap,去和server端通信。
配置CXF框架
我的电脑->属性->高级->环境变量
创建一个CXF_HOEM变量,值为CXF框架所在根目录,修改一下
CLASSPATH=%CXF_HOME%/lib;PATH=%CXF_HOME%/bin;这时有会问为什么要配置这两个参数据呢,其实配置这两个参数用途与配置JAVA变量一下,在DOS窗口下直接运行java2ws,wsdl2java等可执行文件。当然你没有配置也可以进到CXF框架的bin目录下远行这个几个可执行文件。
配置好了后,你在DOS窗口下输入java2ws,看看配置是否效。肯定没有成功,原因是使用6.0的JDK,我们还得在%JAVA_HOME%/jre/lib目录下创建一下endorsed文件夹,将jaxb-api.jar,jaxws.jar拷贝进去。现在再运一下java2ws,成功运行,配置生效了。
三:解组和编组
解组原理
编组原理
具体代码参考:
public class SoapClient {
private final static String MODEL = "com.itdcl.model";
public static void main(String[] args) throws ParserConfigurationException, JAXBException, TransformerException{
ObjectFactory factory = new ObjectFactory();
Customer customer = factory.createCustomer();
customer.setAge(20);
customer.setName("Josen");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);
//Java对象转换成XML
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(customer, doc);
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
String xmlString = writer.toString();
System.out.println(xmlString);
//XML转换成Java对象
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(xmlString);
Customer cus = (Customer)unmarshaller.unmarshal(reader);
System.out.println("Age:"+cus.getAge());
System.out.println("Name:"+cus.getName());
}
}
也可通过Ant配置来解组,如下:
Java代码
<?xml version="1.0" encoding="utf-8" ?>
<project default="xjc-compile" basedir=".">
<property name="src.dir" location="src" />
<property name="lib.dir" location="E:/cxf-lib" />
<property name="xml-schema.dir" location="src/WEB-INF" />
<property name="schema.name" value="cxfdemo.xsd" />
<property name="package" value="com.itdcl.model" />
<path id="classpath">
<fileset dir="${lib.dir}" includes="*.jar" />
</path>
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask"
classpathref="classpath" />
<target name="xjc-compile">
<echo message="Build Jaxb Class from Schema" />
<xjc schema="${xml-schema.dir}/${schema.name}"
destdir="${src.dir}" package="${package}" >
<produces dir="src/com/itdcl/model" includes="*" />
</xjc>
</target>
</project>
四:传输过程中加密
我们就得给消息加密。CXF可以结合WSS4J来对消息安全进行管理,可以使用令牌,X.509认证对消息头或内容进行加密。这节我只对令牌加密做一个简单的描述,我们还以Demo的形式来讲解一下。
<jaxws:endpoint id="service"
implementor="com.itdcl.service.ServiceImpl" address="/Service">
<jaxws:inInterceptors>
<bean
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean
class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType"
value="PasswordText" />
<entry key="user" value="cxfServer" />
<entry key="passwordCallbackRef">
<ref bean="serverPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
action:UsernameToken指使用用户令牌
passwordType:PasswordText指密码加密策略,这里直接文本
user:cxfServer指别名
passwordCallBackRef:serverPasswordCallback指消息验证
五:CFX 结合JSON
项目中需要用到json与java List之间的转换,在此写出来自己的方法,这里采用的是jackson。请先下载jackson相关包和apache cxf下的jettison-1.2.jar
1:新建POJO类
public class TestPojo {
private String name;
private String sex;
。。。。
}
2:json与List<TestPojo>之间的转换
public static void main(String[] args) {
List<TestPojo> list = new ArrayList<TestPojo>();
for(int i = 0; i < 10; i++) {
TestPojo pojo1 = new TestPojo();
pojo1.setName(i + "11");
pojo1.setSex(i + "22");
list.add(pojo1);
}
ObjectMapper mapper = new ObjectMapper();
StringWriter sw = new StringWriter();
try {
mapper.writeValue(sw, list);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
List<TestPojo> list2 = new ArrayList<TestPojo>();
try {
JSONArray array = new JSONArray(sw.toString());
for(int i = 0; i < array.length(); i++) {
TestPojo pojoReverse = mapper.readValue(array.getString(i), TestPojo.class);
System.out.println(pojoReverse);
list2.add(pojoReverse);
}
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("list size = " + list.size());
System.out.println("list2 size = " + list2.size());
}