WebService系列CXF方式(三)
一:导包----apache-cxf-2.6.2lib 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());? }? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |