webservice cxf soap RESTfull

    
java webservice CXF JAX-WS(SOAP) + JAX-RS(RESTfull)


一、环境说明:

1>.在ssh(Struts2+Spring+Hibernate)架构中加入webservice服务,web服务使用Apache CXF,采用cxf+spring的方式发布web服务

2>. Apache CXF Releases 2.7.5, apache-cxf-2.7.5.zip 下载地址 http://www.apache.org/dyn/closer.cgi?path=/cxf/2.7.5/apache-cxf-2.7.5.zip

二、环境配置

1>.导入jar依赖
cxf-2.7.5.jar
neethi-3.0.2.jar
spring-asm-3.0.7.RELEASE.jar
spring-beans-3.0.7.RELEASE.jar
spring-context-3.0.7.RELEASE.jar
spring-core-3.0.7.RELEASE.jar
spring-expression-3.0.7.RELEASE.jar
spring-web-3.0.7.RELEASE.jar
spring-aop-3.0.7.RELEASE.jar

slf4j-api-1.7.5.jar
xmlschema-core-2.0.3.jar

httpasyncclient-4.0-beta3.jar
httpclient-4.2.1.jar
httpcore-4.2.2.jar
httpcore-nio-4.2.2.jar
wsdl4j-1.6.3.jar
javax.ws.rs-api-2.0-m10.jar
jaxb-impl-2.2.6.jar

jettison-1.3.3.jar

wss4j-1.6.10.jar

woodstox-core-asl-4.2.0.jar
stax2-api-3.1.1.jar


2>.web.xml  中的配置(spring和cxf的servlet)

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			<!-- webservice -->
			classpath:/applicationContext_ws.xml
		</param-value>
	</context-param>

	<!-- webservice -->
	<servlet>    
		<servlet-name>CXFService</servlet-name>    
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet> 
	<servlet-mapping>    
		<servlet-name>CXFService</servlet-name>    
		<url-pattern>/cxfservlet/*</url-pattern>
	</servlet-mapping>

3>.struts.xml 配置  webservice servlet ,要不然请把struts的url-pattern尽量带上后缀,比如  *.action,而不要配置为  /* 拦截所有请求,不然就需要有这一步在struts.xml的文件里配置放过webservice servlet 的请求
	<!-- webservice -->
	<package name="cxf" extends="struts-default">
		<action name="cxfservlet/*">
			<result>cxfservlet/{1}</result>
		</action>
	</package>

4>.定义DTO,用户请求和返回xml或者json和javaBean的相互转换
package com.emcs.dm.bean;

import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
 *  使用cxf默认自带的jettison-1.3.3.jar对json支持
 *  需要返回List集合时需要使用一个包装对象
 *
*/
@XmlRootElement
@XmlType(name="",propOrder="hosts")
public class DMHostMachines
{
	private List<DMHostMechine> hosts;

	public List<DMHostMechine> getHosts()
	{
		return hosts;
	}

	public void setHosts(List<DMHostMechine> hosts)
	{
		this.hosts = hosts;
	}
}

package com.emcs.dm.bean;

import java.io.Serializable;
import java.util.Date;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement    //将类或枚举类型映射到 XML 元素
@XmlType(name="DMHostMechine")
@XmlAccessorType(XmlAccessType.FIELD)
public class DMHostMechine implements Serializable
{

	/**
	 * 
	 */
	private static final long serialVersionUID = 8206718006545121379L;
	
	private Integer hostId;
	private String enterpriseName;
	private Date lastUploadTime;
	
	public DMHostMechine()
	{
		
	}
	
	public DMHostMechine(Integer hostId,String enterpriseName,Date lastUploadTime)
	{
		this.hostId = hostId;
		this.enterpriseName = enterpriseName;
		this.lastUploadTime = lastUploadTime;
	}

	public Integer getHostId()
	{
		return hostId;
	}

	public void setHostId(Integer hostId)
	{
		this.hostId = hostId;
	}

	public String getEnterpriseName()
	{
		return enterpriseName;
	}

	public void setEnterpriseName(String enterpriseName)
	{
		this.enterpriseName = enterpriseName;
	}

	public Date getLastUploadTime()
	{
		return lastUploadTime;
	}

	public void setLastUploadTime(Date lastUploadTime)
	{
		this.lastUploadTime = lastUploadTime;
	}

	@Override
	public String toString()
	{
		return super.toString();
	}
}



5>.定义发布接口
package com.ws.service;

import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.emcs.dm.bean.DMHostMachines;
import com.emcs.dm.bean.DMHostMechine;
import com.framework.exception.BaseException;

@WebService(targetNamespace="com.ws.service")  //for SOAP
@SOAPBinding(style=Style.RPC)                  //for SOAP
@Produces("*/*")                               //for REST
public interface IDMRequestService
{
	@WebMethod(operationName="request")    //for SOAP
	@GET                                   //for REST
	@Path("/{name}/request")
	@Produces(MediaType.TEXT_PLAIN)
	String request(@PathParam("name") String name);
	
	@WebMethod(operationName="getAllHostMachine")
	@GET
	@Path("/hostmachine")
	@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
	List<DMHostMechine> getAllHostMachine() throws BaseException;
	
	@WebMethod(operationName="getHosts")
	@GET
	@Path("/hosts")
	@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
	DMHostMachines getHosts() throws BaseException;
}


6>.定义实现类
package com.ws.service.impl;

import java.util.List;

import javax.jws.WebService;

import com.emcs.dm.bean.DMHostMachines;
import com.emcs.dm.bean.DMHostMechine;
import com.framework.base.service.impl.DBServiceImpl;
import com.framework.exception.BaseException;
import com.ws.service.IDMRequestService;

/**
 * @author Admin
 * @description Expose CXF Service With REST And SOAP
 * 
 * @Consumes annotation specifies, the request is coming from the client
 *			you can specify the Mime type as @Consumes("application/xml"), if the request is in xml format
 *
 * @Produces annotation specifies, the response is going to the client
 *			you can specify the Mime type as @Produces ("application/xml"), if the response need to be in xml format
 * 
 */
@WebService(endpointInterface="com.ws.service.IDMRequestService")
public class DmRequestServiceImpl extends DBServiceImpl implements IDMRequestService
{

	@Override
	public List<DMHostMechine> getAllHostMachine() throws BaseException
	{
		String hql = "select new com.emcs.dm.bean.DMHostMechine(v.id,b.enterpriseName,v.lastUploadTime) " +
				"from DmVideo v,BbEnterprise b where v.enterpriseId=b.id";
		
		@SuppressWarnings("unchecked")
		List<DMHostMechine> ts = this.getDao().query(hql);
		
		return ts;
	}

	@Override
	public String request(String name)
	{
		return "hello world";
	}

	@Override
	public DMHostMachines getHosts() throws BaseException
	{
		List<DMHostMechine> ts = this.getAllHostMachine();
		
		DMHostMachines hosts = new DMHostMachines();
		hosts.setHosts(ts);
		
		return hosts;
	}	
}


7>.在classpath下新建webservice的受spring管理的配置文件applicationContext_ws.xml(在web.xml中加入,请参照环境配置第二步),并加入spring的上下文管理位置 contextConfigLocation
<?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:tx="http://www.springframework.org/schema/tx"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core"
	xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:wsa="http://cxf.apache.org/ws/addressing"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="      
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.1.xsd   
     http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd   
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd  
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<!-- REST -->
	<import resource="classpath:META-INF/cxf/cxf.xml" />

	<!-- SOAP -->
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />

	<!-- 注入实现类 -->
	<bean id="hello" class="com.ws.service.impl.DmRequestServiceImpl" scope="prototype">
		<property name="dao" ref="baseDao"></property>
		<property name="entity" ref="dmVideoBean"></property>
	</bean>
	
	<util:list id="jsonKeys">
		<value>hosts</value>
	</util:list>
	
	<!-- 对json提供支持 
	-->
	<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider"> 
        <property name="dropRootElement" value="true"/> 
        <property name="dropCollectionWrapperElement" value="true"/> 
        <property name="serializeAsArray" value="true"/> 
        <!-- 
        <property name="arrayKeys" ref="jsonKeys"/>
         -->
	</bean> 
	<cxf:bus>
		<cxf:inInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
		</cxf:inInterceptors>
	</cxf:bus>

	<!-- Expose CXF Service With REST And SOAP -->

	<!-- SOAP SERVER(JAX-WS) 
	<jaxws:endpoint id="soapService" address="/soap"
		implementor="#hello" publish="true" />
	-->
	<jaxws:server serviceClass="com.ws.service.IDMRequestService" serviceBean="#hello" 
	address="/soap">
	</jaxws:server>

	<!-- REST SERVER(restful/JAX-RS) -->
	<jaxrs:server address="/rest" id="base" publishedEndpointUrl="http://外网IP地址:8000/cxfservlet/rest">
		<jaxrs:serviceBeans>
			<ref bean="hello" />
		</jaxrs:serviceBeans>
		<!-- 
		 -->
			<jaxrs:providers>         
				<ref local="jsonProvider"/>
			</jaxrs:providers>
	</jaxrs:server>

	<cxf:bus>
		<cxf:features>
			<cxf:logging />
		</cxf:features>
	</cxf:bus>
</beans> 

8>.这里使用tomcat服务器,启动服务器在浏览器里输入
http://localhost:8080/cxfservlet/   访问webservice服务,出现下面画面说明发布成功


发布成功的SOAP,也可以通过 http://localhost:8080/cxfservlet/soap?wsdl查看wsdl


发布成功的REST,也可以通过 http://127.0.0.1:8080/cxfservlet/rest?_wadl查看wadl

9>.客户端调用,远程调用
[list]
  • 导入cxfjar依赖,
  • SOAP访问
  •   ①.通过cxf SDK 生成客户端
        操作步骤:
        DOS命令窗口→切换到cxf SDK bin目录
        通过执行wsdl2java -h 命令查看各参数作用
        执行命令

    wsdl2java -p soap.client –d E:\ http://localhost:8080/cxfservlet/soap?wsdl


    在E盘下生成soap.client文件夹,并在文件夹中生成客户端代码


    其中package-info.java、ObjectFactory.java 是JAXB 需要的文件;IDMRequestServiceService.java
    继承自 javax.xml.ws.Service   类,用于提供 WSDL          的客户端视图
    package com.ws.service.test;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    import javax.ws.rs.core.MediaType;
    
    import org.apache.cxf.jaxrs.client.WebClient;
    import org.apache.cxf.jaxrs.provider.json.JSONProvider;
    
    import com.emcs.dm.bean.DMHostMechine;
    
    public class WsClient
    {
    	public static void main(String[] args)
    	{	
    		/* ----------------------标准 JAX-WS API-----------------------------------*/
    		/**
    		 * new QName(arg0,arg1)
    		 * arg0 -------------------- targetNamespace
    		 * arg1 -------------------- 对应<wsdl:service 的那么属性,也就是在发布service是的serviceName
    		 */
    		QName qname = new QName("com.ws.service","IDMRequestServiceService");
    		String wsdlLocation = "http://localhost:8080/cxfservlet/soap?wsdl";
    		try
    		{
    			IDMRequestServiceService serviceName = new IDMRequestServiceService(new URL(wsdlLocation),qname);
    			IDMRequestService jaxWsService = serviceName.getIDMRequestServicePort();
    			DMHostMechineArray arr = jaxWsService.getAllHostMachine();
    			List<DMHostMechine> list = arr.getItem();
    			if(list.size() > 0)
    			{
    				System.out.println(list.size());
    			}
    		}
    		catch (MalformedURLException e)
    		{
    			e.printStackTrace();
    		}
    		catch (BaseException_Exception e)
    		{
    			e.printStackTrace();
    		}
    
    	/* ----------------------------CXF-----------------------------------
    		JaxWsProxyFactoryBean jwpf = new JaxWsProxyFactoryBean(); 
    		
    		jwpf.setAddress("http://localhost:8080/cxfservlet/soap");
    		jwpf.setServiceClass(IDMRequestService.class);
    		Object o = jwpf.create();
    		IDMRequestService service = (IDMRequestService)o;
    		
    		try
    		{
    			DMHostMechineArray arr = service.getAllHostMachine();
    			List<DMHostMechine> list = arr.getItem();
    			if(list.size() > 0)
    			{
    				System.out.println(list.size());
    			}
    		}
    		catch (BaseException_Exception e)
    		{
    			e.printStackTrace();
    		}
    		--------------------------------------------------------------------------*/
    	}
    }


  • REST访问
  • package com.ws.service.test;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    import javax.ws.rs.core.MediaType;
    
    import org.apache.cxf.jaxrs.client.WebClient;
    import org.apache.cxf.jaxrs.provider.json.JSONProvider;
    
    import com.emcs.dm.bean.DMHostMechine;
    
    public class WsClient
    {
    	public static void main(String[] args)
    	{
    		String restBaseUrl = "http://localhost:8080/cxfservlet/rest";
    		
    		WebClient client = WebClient.create(restBaseUrl);		client.type(MediaType.APPLICATION_XML).accept(MediaType.APPLICATION_XML);
    	
    		Collection<? extends DMHostMechine> c = client.path("hostmachine").getCollection(DMHostMechine.class);
    		
    
    		if(!c.isEmpty())
    		{
    			System.out.println(c.size());
    		}
    /*
    		String restBaseUrl = "http://localhost:8080/cxfservlet/rest";
    		
    		WebClient client = WebClient.create(restBaseUrl);		client.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
    		
    
    		DMHostMachines c = client.path("hosts").get(DMHostMachines.class);
    		
    		if(c != null)
    		{
    			List<DMHostMechine> l = c.getHosts();
    		}
    */
    	}
    }


    RESTFull  使用http协议,可以在浏览器里直接访问
    比如可以通过后缀?_type=xml 或者 ?_type=json  来请求响应  XML数据 或者  json 数据,比如:
    http://localhost:8080/cxfservlet/rest/hosts?_type=xml


    [/list]

    猜你喜欢

    转载自yuxiatongzhi.iteye.com/blog/1898029