Java Web Service-CXF
2015年11月11日
1 目标:提供web方法共享,提供网络服务。
供其它的网站或应用在线调用。使网站或应用专注于核心功能,由web服务完成基础服务。
能够提供Restful和SOAP格式的web服务。
2 原理:服务器提供的HTTP服务,与客户端使用SOAP、Restful协议交互。
SOAP、Restful协议交互:Java提供Jax-WS,Jax-RS标准,AXIS、CXF实现。
WEB服务:Java实现的业务类。
HTTP服务器:Tomcat。
为了解耦web服务与传输方法,AXIS、CXF与HTTP是独立设计的。
WSDL提供xml格式的使用说明。
3 流程:基于SOAP或Restful的Web服务
注意:SOAP需要提供Http Body作为参数,方法调用时只能使用Post调用,无法使用Get调用。
参考:http://www.coderanch.com/t/638206/Web-Services/java/Calling-Soap-JAX-WS-http
3.1 基于SOAP的Web服务:安装CXF库,配置web.xml,配置Spring,创建WebService的服务Bean。
3.1.1创建Dynamic Web Project。
3.1.2安装CXF库(自带Spring库):下载CXF,解压后将lib下所有内容copy到web-inf/lib下。将库加入ClassPath。
3.1.3配置web.xml:指定Spring为Web监听类,设置CXF的Servlet。
//web.xml
<?xmlversion="1.0" encoding="UTF-8"?>
<web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"id="WebApp_ID" version="3.1">
<display-name>CXFDemo</display-name>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
3.1.4配置Spring:添加jaxws命名空间,设置endpoint。
//applicationContext.xml
<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<importresource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpointid="webServiceHelloWorld" address="/HelloWorld"
implementor="lee.HelloWorldImpl"/>
</beans>
3.1.5创建WebService的服务Bean类:使用@WebService标记。
//IHelloWorld.java
package lee;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface IHelloWorld{
@WebMethod
String say(String msg);
@WebMethod
String sayHello();
}
//HelloWorldImpl.java
package lee;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class HelloWorldImplimplements IHelloWorld {
@Override
@WebMethod
public String say(String msg) {
// TODO Auto-generated method stub
return "Hello"+msg;
}
@Override
@WebMethod
public String sayHello() {
// TODO Auto-generated method stub
return "Hello";
}
}
3.1.6调用WebService:使用URL可以请求WSDL。
注意:由于SOAP必须发磅XML数据块作为Http Body的参数,所以不能使用GET请求方法调用,只能使用Post调用。
参考:http://www.coderanch.com/t/638206/Web-Services/java/Calling-Soap-JAX-WS-http
4 方法:基于SOAP的WEB服务
4.1 目标:使用XML进行网络交互通信,提供WEB服务,RPC的进化版。
4.2 原理:使用XML协议进行Http通信交互,使用JAX-WS进行XML与Java服务交互,Java Bean提供服务。
4.3 流程:参见基于SOAP的Web服务:安装CXF库,配置web.xml,配置Spring,创建WebService的服务Bean。
4.4 方法:SOAP+CXF
参考:http://baike.baidu.com/view/1695890.htm?fromtitle=SOAP&fromid=4684413&type=syn
http://baike.baidu.com/view/1865210.htm
4.4.1XML交互协议:SOAP,WSDL,UDDI
SOAP:Simple Object AccessProtocol,简单对象访问协议,目标是传递信息。
WSDL:Web ServiceDescription Language,Web服务描述语言,目标是描述如何访问服务接口。
UDDI:Universal DescriptionDiscovery and Integration,统一描述发现集成服务,目标是提供Web服务的管理、查询。
4.4.2XML与Java映射标准:JAX-WS
JAX-WS:Java Api forXml-base Web Service。Java提供的将XML与Java对象进行转换的标准。
参考:
4.4.2.1 目标:将Web服务的XML交互协议与Java对象进行映射。
4.4.2.2 方法:映射SEI(service endpoint interface,服务终端接口)
接口映射:SEI,定义WebService和Java服务Bean的映射。
在Spring的配置中设置jaxws:endpoint作为SEI节点。其address表示webservice路径,implementor表示Java的服务Bean。
<jaxws:endpoint id="webServiceHelloWorld"address="/HelloWorld"
implementor="lee.HelloWorldImpl" />
Java服务Bean类:类使用@WebService标记,方法使用@WebMethod标记。
数据类型映射:
boolean xsd:boolean
byte xsd:byte
short xsd:short
int xsd:int
long xsd:long
float xsd:float
double xsd:double
参考:http://www.educity.cn/wenda/116578.html
4.4.3JAX-WS实现:CXF
目标是实现JAX-WS标准,并提供WebService发送、交互等相关操作功能。
功能最强大,使用简单,开发效率高,直接与Spring结合。
4.4.4开发方式:自下向上(Bean->WSDL),自顶向下(WSDL->Bean)
自下向上(推荐):从服务类开始发布为服务。
自顶向下:从WSDL开始生成服务类。
参考:
5 方法:基于SOAP的Web服务客户端调用
5.1 目标:调用基于SOAP的Web服务。
5.2 原理:使用SOAP进行Web服务交互获取功能WSDL,根据接口,生成服务实例的代理对象。
5.3 流程:安装CXF库。配置web.xml,配置Spring,调用服务功能。
5.3.1生成Dynamic Web Application。
5.3.2安装CXF库:安装CXF库(自带Spring库):下载CXF,解压后将lib下所有内容copy到web-inf/lib下。将库加入ClassPath。
5.3.3配置web.xml:设置Spring监听器,设置Servlet
//web.xml
<?xmlversion="1.0" encoding="UTF-8"?>
<web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"id="WebApp_ID" version="3.1">
<display-name>CXFClientDemo</display-name>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>h</servlet-name>
<servlet-class>
lee.Client
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>h</servlet-name>
<url-pattern>/client/h</url-pattern>
</servlet-mapping>
</web-app>
5.3.4配置Spring:设置代理工厂,设置服务代理Bean类。
//applicationContext.xml
<?xmlversion="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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schema/jaxws.xsd">
<bean id="hello" class="lee.IHelloWorld"factory-bean="clientFactory"factory-method="create"></bean>
<bean id="clientFactory"class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<propertyname="serviceClass" value="lee.IHelloWorld"/>
<propertyname="address"value="http://192.168.41.131:8080/CXFDemo/services/HelloWorld"/>
</bean>
</beans>
5.3.5调用服务功能:指定接口,获取Bean,调用服务。
//IHelloWorld.java
package lee;
import javax.jws.WebService;
@WebService
public interface IHelloWorldextends java.rmi.Remote {
public java.lang.String sayHello() throwsjava.rmi.RemoteException;
public java.lang.Stringsay(java.lang.String arg0) throws java.rmi.RemoteException;
}
//Client.java
package lee;
importjava.rmi.RemoteException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import lee.IHelloWorld;
public class Client extendsHttpServlet {
public void service(HttpServletRequest reqest,HttpServletResponse response) throws RemoteException {
WebApplicationContextctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
IHelloWorld h =ctx.getBean("hello", IHelloWorld.class);
String resp=h.sayHello();
System.out.println("service say="+resp);
}
}
5.4 方法:SOAP+CXF
5.4.1配置代理工厂:JaxWsProxyFactoryBean。
指定工厂Bean的实现类为cxf的工厂类:org.apache.cxf.jaxws.JaxWsProxyFactoryBean。
指定要代理的服务类接口:serviceClass。
指定web服务的地址:address。
JaxWsProxyFactoryBean:cxf的代理方法工厂类。创建对象的方法为create。
Modifier and Type | Method and Description | ||
protected ClientProxy |
| ||
create Creates a JAX-WS proxy that can be used to make remote invocations. |
| ||
protected String |
| ||
Returns the configured list of JAX-WS handlers for the proxy. |
| ||
protected Class<?>[] |
| ||
boolean |
| ||
void | setHandlers Specifies a list of JAX-WS Handler implementations that are to be used by the proxy. |
| |
void | setLoadHandlers |
|
<beanid="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass"value="lee.IHelloWorld"/>
<property name="address"value="http://192.168.41.131:8080/CXFDemo/services/HelloWorld"/>
</bean>
5.4.2配置服务代理Bean类:指定class为服务接口,指定工厂Bean,指定工厂方法为create。
指定服务Bean的实现类为服务接口。
指定factory-bean为工厂Bean。
指定工厂方法为Create。
<bean id="hello"class="lee.IHelloWorld" factory-bean="clientFactory"factory-method="create"></bean>
5.4.3接口设置:使用服务器接口。
注意:接口必须与服务一致,具有@WebService标记。
@WebService
public interface IHelloWorldextends java.rmi.Remote {
参考:http://bbs.csdn.net/topics/320095163
5.4.4接口设置:由WSDL生成接口。
参考:http://blog.csdn.net/yuvmen/article/details/4790854
使用wsdl2java(位于cxf的bin目录)生成java接口。将生成多个java文件,只需copy接口java到客户端。
格式:
-p 指定其wsdl的命名空间,也就是要生成代码的包名
-d 指定要产生代码所在目录
-client 生成客户端测试web service的代码
-server 生成服务器启动web service的代码
-impl 生成web service的实现代码
-ant 生成build.xml文件
-compile 生成代码后编译
-quient 静默模式,不输出警告与错误信息
-all 生成所有开始端点代码:types,serviceproxy,service interface, server mainline, client mainline, implementationobject, and an Ant build.xml file.
5.5 示例:桌面程序客户端调用web服务:
参考:http://www.widecodes.com/0SxeqjPWqj/cxf-vs-axis-big-xml-over-soap.html
http://5148737.blog.51cto.com/5138737/1604472
5.5.1配置Spring Beans:
<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schema/jaxws.xsd">
<bean id="client" class="cxf.test.HelloWorld"
factory-bean="clientFactory"factory-method="create"/>
<beanid="clientFactory"class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<propertyname="serviceClass" value="cxf.test.HelloWorld"/>
<propertyname="address"value="http://localhost:8080/cxf2/services/HelloWorld"/>
</bean>
</beans>
5.5.2生成web服务本地类供客户端调用:
package cxf.test;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
import cxf.test.HelloWorld;// necessary
public final class Client {
private Client() { }
public static void main(String args[])throws Exception {
ClassPathXmlApplicationContext context = newClassPathXmlApplicationContext(new String[]{"cxf/test/client-beans.xml"});
HelloWorld client =(HelloWorld)context.getBean("client");
String response =client.say("Joe");
System.out.println("Response:" + response);
System.exit(0);
}
}
6 方法:基于Restful的Web服务和客户端
参见:Java-webservice-CXF-Restful服务.docx