前言
自3月份到一家快递公司之后,就极少有时间来写博客了,进去的第一个周末就加班。做公司的开放平台,协助一个小伙伴写WebService接口,用的就是CXF。正好这个东西曾经使用过。如今快7月了,曾经写的东西。还木有写完,今天继续。将曾经未写完的东西。写完整。
准备工作
这次的例子,都是在曾经的基础上写的。主要贴出基本的代码。服务端和client都与Spring集成。使用了拦截器、Map数据类型等
服务端
<?第一个服务的类:xml version="1.0" encoding="UTF-8"?
> <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://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <!-- <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> --> <!-- 服务一。无client --> <!-- 多种公布方式都能够 <bean id="noInterfaceServiceImpl" class="com.wds.cxf.spring.server.impl.NoInterfaceServiceImpl"/> <jaxws:endpoint address="/noInterfaceService" implementor="#noInterfaceServiceImpl" ></jaxws:endpoint> --> <jaxws:endpoint id="noInterfaceService" address="/noInterfaceService" implementor="com.wds.cxf.spring.server.impl.NoInterfaceServiceImpl" ></jaxws:endpoint> <!-- 服务2:有client,不带拦截器 --> <jaxws:server address="/userService2"> <jaxws:serviceBean> <bean class="com.wds.cxf.spring.server.impl.UserServiceImpl"></bean> </jaxws:serviceBean> </jaxws:server> <!-- 服务3:有client。带拦截器 。与服务2是同样的代码。差别之处就是这个服务有拦截器--> <jaxws:server address="/userService" serviceClass="com.wds.cxf.spring.server.IUserService"> <jaxws:serviceBean> <bean class="com.wds.cxf.spring.server.impl.UserServiceImpl"></bean> </jaxws:serviceBean> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> <bean class="com.wds.cxf.spring.server.interceptor.HeaderHandlerInterceptor"></bean> </jaxws:inInterceptors> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> </jaxws:outInterceptors> </jaxws:server> <!-- 服务4:有拦截器,Map类型的数据结构 --> <jaxws:server address="/SecurityService" serviceClass="com.wds.cxf.spring.server.ISecurityService"> <jaxws:serviceBean> <bean class="com.wds.cxf.spring.server.impl.SecurityServiceImpl"></bean> </jaxws:serviceBean> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> <bean class="com.wds.cxf.spring.server.interceptor.HeaderHandlerInterceptor"></bean> </jaxws:inInterceptors> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> </jaxws:outInterceptors> </jaxws:server> </beans>
package com.wds.cxf.spring.server.impl; import javax.jws.WebService; @WebService public class NoInterfaceServiceImpl { public String test(){ return "Hello, this is test method"; } }
第二个和第三个服务的接口及实现类
package com.wds.cxf.spring.server; import java.util.List; import javax.jws.WebService; @WebService public interface IUserService { public List<String> getUserName(); } 实现类 package com.wds.cxf.spring.server.impl; import java.util.ArrayList; import java.util.List; import javax.jws.WebService; import javax.xml.ws.BindingType; import javax.xml.ws.soap.SOAPBinding; import com.wds.cxf.spring.server.IUserService; @WebService(endpointInterface="com.wds.cxf.spring.server.IUserService",serviceName="UserService") @BindingType(value=SOAPBinding.SOAP12HTTP_BINDING) public class UserServiceImpl implements IUserService { @Override public List<String> getUserName() { List<String> userNameList = new ArrayList<String>(); String userName = "firstName"; userNameList.add(userName); userName = "secondName"; userNameList.add(userName); userName = "thirdName"; userNameList.add(userName); return userNameList; } }第四个服务
package com.wds.cxf.spring.server; import java.util.List; import java.util.Map; import javax.jws.WebService; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.wds.cxf.spring.server.adapter.MappingUser; @WebService public interface ISecurityService { @XmlJavaTypeAdapter(value=MappingUser.class) public Map<String, List<User>> getAuthority(); } 实现类 package com.wds.cxf.spring.server.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.wds.cxf.spring.server.ISecurityService; import com.wds.cxf.spring.server.User; public class SecurityServiceImpl implements ISecurityService { @Override public Map<String, List<User>> getAuthority() { Map<String, List<User>> result = new HashMap<String, List<User>>(); User u = null; List<User> users = new ArrayList<User>(10); String key = "seriail1"; for (int i = 0; i < 10; i++) { u = new User("name" + i, "code--" + i); users.add(u); } result.put(key, users); users = new ArrayList<User>(10); key = "seriail2"; for (int i = 20; i < 30; i++) { u = new User("name" + i, "code--" + i); users.add(u); } result.put(key, users); return result; } }类型转换的适配类两个
package com.wds.cxf.spring.server.adapter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.xml.bind.annotation.adapters.XmlAdapter; import com.wds.cxf.spring.server.User; public class MappingUser extends XmlAdapter<MappingUserValue, Map<String, List<User>>>{ @Override public Map<String, List<User>> unmarshal(MappingUserValue src) throws Exception { Map<String, List<User>> target = new HashMap<String, List<User>>(); for (MappingUserValue.Entry entry : src.getEntries()) { target.put(entry.getKey(), entry.getValue()); } return target; } @Override public MappingUserValue marshal(Map<String, List<User>> src) throws Exception { MappingUserValue result = new MappingUserValue(); MappingUserValue.Entry e = null; for (Entry<String, List<User>> entry : src.entrySet()) { e = new MappingUserValue.Entry(); e.setKey(entry.getKey()); e.setValue(entry.getValue()); result.getEntries().add(e); } return result; } }
package com.wds.cxf.spring.server.adapter; import java.util.ArrayList; import java.util.List; import com.wds.cxf.spring.server.User; public class MappingUserValue { private List<Entry> entries = new ArrayList<MappingUserValue.Entry>(); public List<Entry> getEntries() { return entries; } public void setEntries(List<Entry> entries) { this.entries = entries; } public static class Entry { private String key; private List<User> value; public List<User> getValue() { return value; } public void setValue(List<User> value) { this.value = value; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } } }拦截器
package com.wds.cxf.spring.server.interceptor; import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class HeaderHandlerInterceptor extends AbstractPhaseInterceptor<Message> { public HeaderHandlerInterceptor(String phase) { super(Phase.PRE_INVOKE); } public HeaderHandlerInterceptor() { this(null); } @Override public void handleMessage(Message message) throws Fault { SoapMessage msg = (SoapMessage)message; List<Header> headers = msg.getHeaders(); if(headers == null || headers.size() < 1){ throw new Fault(new IllegalArgumentException("There have no header node!")); } Header firstHeader = headers.get(0); for (Header header : headers) { QName qName = header.getName(); System.out.println(qName); } Element element = (Element)firstHeader.getObject(); NodeList usernameNode = element.getElementsByTagName("username"); NodeList passwordNode = element.getElementsByTagName("password"); if(usernameNode == null || usernameNode.getLength() != 1){ throw new Fault(new IllegalArgumentException("not valid username")); } if(passwordNode == null || passwordNode.getLength() != 1){ throw new Fault(new IllegalArgumentException("not valid password")); } String userName = usernameNode.item(0).getTextContent(); String userPass = passwordNode.item(0).getTextContent(); if(!("admin".equals(userPass) && "admin".equals(userName))){ throw new Fault(new IllegalArgumentException("username or password is not valid")); } } }至此,服务端的代码。所有齐了
client
<?使用CXF的命令。生成客户端代码,加上面的配置。此外还须要一个拦截器,代码例如以下:xml version="1.0" encoding="UTF-8"?> <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://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <!-- 第四个服务的客户端 --> <jaxws:client id="securityService" address="http://localhost:8080/web/services/SecurityService" serviceClass="com.wds.java.cxf.client.role.code.ISecurityService" > <jaxws:outInterceptors> <bean class="com.wds.java.cxf.interceptor.ClientHeaderInterceptor"> <constructor-arg index="0" value="admin" /> <constructor-arg index="1" value="admin" /> </bean> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" /> </jaxws:outInterceptors> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" /> </jaxws:inInterceptors> </jaxws:client> <!-- 第三个服务的客户端 --> <jaxws:client id="userServiceOne" address="http://localhost:8080/web/services/userService" serviceClass="com.wds.java.cxf.client.user.code.IUserService" > <jaxws:outInterceptors> <bean class="com.wds.java.cxf.interceptor.ClientHeaderInterceptor"> <constructor-arg index="0" value="admin" /> <constructor-arg index="1" value="admin" /> </bean> </jaxws:outInterceptors> </jaxws:client> <!-- 第二个服务的客户端 --> <jaxws:client id="userServiceTwo" address="http://localhost:8080/web/services/userService2" serviceClass="com.wds.java.cxf.client.user.code.IUserService" /> </beans>
package com.wds.java.cxf.interceptor; import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.w3c.dom.Document; import org.w3c.dom.Element; public class ClientHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage>{ private String username; private String password; public ClientHeaderInterceptor(String phase) { super(Phase.PREPARE_SEND);//在准备发送SOAP消息时,调用此拦截器 } public ClientHeaderInterceptor(String username, String password) { this(""); this.username = username; this.password = password; } @Override public void handleMessage(SoapMessage msg) throws Fault { List<Header> headers = msg.getHeaders(); Document doc = DOMUtils.createDocument(); Element authEle = doc.createElement("header"); Element usernameEle = doc.createElement("username"); Element passwordEle = doc.createElement("password"); usernameEle.setTextContent(username); passwordEle.setTextContent(password); authEle.appendChild(usernameEle); authEle.appendChild(passwordEle); Header header = new Header(new QName("authHeaer"), authEle); headers.add(header); authEle = doc.createElement("headerTwo"); usernameEle = doc.createElement("username"); passwordEle = doc.createElement("password"); usernameEle.setTextContent(username); passwordEle.setTextContent(password); authEle.appendChild(usernameEle); authEle.appendChild(passwordEle); header = new Header(new QName("2authHeaer"), authEle); headers.add(header); } }
測试类
package com.wds.java.cxf.client.user; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wds.java.cxf.client.role.code.Entry; import com.wds.java.cxf.client.role.code.ISecurityService; import com.wds.java.cxf.client.role.code.MappingUserValue; import com.wds.java.cxf.client.user.code.IUserService; public class Main { @SuppressWarnings("resource") public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/conf/cxf/spring-cxf-client.xml"); IUserService service = (IUserService) context.getBean("userServiceTwo"); List<String> userNames = service.getUserName(); service = (IUserService) context.getBean("userServiceOne"); List<String> userNamesOne = service.getUserName(); for (String string : userNames) { System.out.println(string); } for (String string : userNamesOne) { System.out.println(string); } ISecurityService securityService = (ISecurityService) context.getBean("securityService"); MappingUserValue userValue = securityService.getAuthority(); List<Entry> entries = userValue.getEntries(); for (Entry entry : entries) { System.out.println("key=" + entry.getKey() + " value=" + entry.getValue()); } } }执行就可以