zoukankan      html  css  js  c++  java
  • WebService-06-CXF与Spring集成

    前言

    自3月份到一家快递公司之后,就极少有时间来写博客了,进去的第一个周末就加班。做公司的开放平台,协助一个小伙伴写WebService接口,用的就是CXF。正好这个东西曾经使用过。如今快7月了,曾经写的东西。还木有写完,今天继续。将曾经未写完的东西。写完整。

    准备工作

    这次的例子,都是在曾经的基础上写的。主要贴出基本的代码。服务端和client都与Spring集成。使用了拦截器、Map数据类型等

    服务端

    共计写了四个服务。第一个主要说明服务端有多种公布方式,第二和第三实现类是同样的。差别在于第三个有拦截器,第四个包含拦截器和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

    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>

    使用CXF的命令。生成客户端代码,加上面的配置。此外还须要一个拦截器,代码例如以下:
    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());
    		}
    	}
    
    }
    
    执行就可以








  • 相关阅读:
    echo "不允许上传该类型的文件
    php构造函数,引入数据库操作类函数
    php函数描述及例子
    php如何判断远程文件是否存在
    多线程面试题系列(16):多线程十大经典案例之一 双线程读写队列数据
    多线程面试题系列(15):关键段,事件,互斥量,信号量的“遗弃”问题
    多线程面试题系列(14):读者写者问题继 读写锁SRWLock
    多线程面试体系列(13):多线程同步内功心法——PV操作下
    多线程面试题系列(12):多线程同步内功心法——PV操作上
    多线程面试题系列(11):读者写者问题
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5207098.html
Copyright © 2011-2022 走看看