Java WebService-CXF
基于SOAP的Web服务
2015年12月11日
注意:SOAP需要提供Http Body作为参数,方法调用时只能使用Post调用,无法使用Get调用。
参考:http://www.coderanch.com/t/638206/Web-Services/java/Calling-Soap-JAX-WS-http
Eclipse中有CXF的Runtime库(?)。
//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/javaee http://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>
Spring配置详情参见:JavaEE-Spring.docx
//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>
//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";
}
}
Get描述请求:http://192.168.41.131:8080/CXFDemo/services/HelloWorld?WSDL
注意:由于SOAP必须发送XML数据块作为Http Body的参数,所以不能使用GET请求方法调用,只能使用Post调用。
参考:http://www.coderanch.com/t/638206/Web-Services/java/Calling-Soap-JAX-WS-http
参考:http://baike.baidu.com/view/1695890.htm?fromtitle=SOAP&fromid=4684413&type=syn
http://baike.baidu.com/view/1865210.htm
SOAP:Simple Object AccessProtocol,简单对象访问协议,目标是传递信息。
WSDL:Web ServiceDescription Language,Web服务描述语言,目标是描述如何访问服务接口。
UDDI:Universal DescriptionDiscovery and Integration,统一描述发现集成服务,目标是提供Web服务的管理、查询。
JAX-WS:Java Api forXml-base Web Service。Java提供的将XML与Java对象进行转换的标准。
参考:
http://wenku.baidu.com/link?url=e7O8uCSRSW_VE1IzKl3fpfJjvixwIrOShVdHbu6S38kyR3a0I4jyyKZOm1aLW03iCvRsjIavlkKEBy7_HpStzJZ8XnUdThPeKZ6pULELY-7
接口映射: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
目标:实现JAX-WS标准,并提供WebService发送、交互等相关操作功能。
功能最强大,使用简单,开发效率高,直接与Spring结合。
自下向上(推荐):从服务类开始发布为服务。
自顶向下:从WSDL开始生成服务类。
参考:
http://wenku.baidu.com/link?url=e7O8uCSRSW_VE1IzKl3fpfJjvixwIrOShVdHbu6S38kyR3a0I4jyyKZOm1aLW03iCvRsjIavlkKEBy7_HpStzJZ8XnUdThPeKZ6pULELY-7
//web.xml
<?xmlversion="1.0" encoding="UTF-8"?>
<web-app xmlns: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>
//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/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>
//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.String say(java.lang.Stringarg0) 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;
importorg.springframework.web.context.support.WebApplicationContextUtils;
import lee.IHelloWorld;
public class Client extendsHttpServlet {
public void service(HttpServletRequest reqest, HttpServletResponseresponse) throws RemoteException {
WebApplicationContextctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
IHelloWorld h =ctx.getBean("hello", IHelloWorld.class);
String resp=h.sayHello();
System.out.println("service say="+resp);
}
}
指定工厂Bean的实现类为cxf的工厂类:org.apache.cxf.jaxws.JaxWsProxyFactoryBean。
指定要代理的服务类接口:serviceClass。
指定web服务的地址:address。
JaxWsProxyFactoryBean:cxf的代理方法工厂类。创建对象的方法为create。
Modifier and Type |
Method and Description |
||
protected ClientProxy |
clientClientProxy |
|
|
Object |
create Creates a JAX-WS proxy that can be used to make remote invocations. |
|
|
protected String |
getConfiguredName |
|
|
List<Handler> |
getHandlers Returns the configured list of JAX-WS handlers for the proxy. |
|
|
protected Class<?>[] |
getImplementingClasses |
|
|
boolean |
isLoadHandlers |
|
|
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>
指定服务Bean的实现类为服务接口。
指定factory-bean为工厂Bean。
指定工厂方法为Create。
<bean id="hello"class="lee.IHelloWorld" factory-bean="clientFactory"factory-method="create"></bean>
注意:接口必须与服务一致,具有@WebService标记。
@WebService
public interface IHelloWorldextends java.rmi.Remote {
参考:http://bbs.csdn.net/topics/320095163
参考: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.
参考:http://www.widecodes.com/0SxeqjPWqj/cxf-vs-axis-big-xml-over-soap.html
http://5148737.blog.51cto.com/5138737/1604472
<?xml version="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"/>
<bean id="clientFactory"class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<propertyname="serviceClass" value="cxf.test.HelloWorld"/>
<propertyname="address" value="http://localhost:8080/cxf2/services/HelloWorld"/>
</bean>
</beans>
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);
}
}
参见:基于SOAP的Web服务AJAX客户端.docx
同域:参见:基于SOAP的Web服务AJAX客户端.docx示例。
跨域:参见:跨域WebService请求-Nginx_SOAP服务_Ajax客户端.docx流程。
参见:跨域WebService请求-Nginx_SOAP服务_Ajax客户端.docx