目录
引言
相比大家都或多或少的了解过或者听说过关于Webservice的相关知识, 常见的WebService实现方式有很多种:
- –Axis1
- –Axis2
- –xfire
- –CXF
采用每种实现方式都可以, 本例将采用CXF方式, 采用CXF是spring搭建webservice 最流行的一种方式, 可以用较少的代码来很容易实现一个Webservice的接口, 并且还可以通过注解的方式来自定义WSDL页面的内容, 使得接口的调用更加友好
实现
1. 引入依赖
<!-- Start CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<!-- 如果CXF不集成到Web服务器中,必须添加该引用 -->
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.2</version>
</dependency>
<!-- End CXF -->
2. 定义接口
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import org.apache.cxf.annotations.WSDLDocumentation;
import org.apache.cxf.annotations.WSDLDocumentationCollection;
@WebService
(
name="diWebInter", // 服务实现类的名称
serviceName="diWebInterService", // 默认在发布的服务实现者的名称后面添加Service
portName="diWebInterPort", // 服务类型的名称: 默认在 发布的服务实现者(MyWebService) 后面添加 port
targetNamespace="http://www.dix.com" // 发布ws服务的命名空间,此空间默认为当前服务包路径的 "倒写"此名称也是 wsimport 命令生成 java类时默认的包路径 -p
)
@WSDLDocumentationCollection(
{
@WSDLDocumentation(value = "webserviceDemo "
+ "调用的方法为: diWebIntegration(String jsArr), "
+ "参数格式: JSONArray格式的字符串.",
placement = WSDLDocumentation.Placement.TOP)
}
)
public interface IUserService {
// 注意 一定要加 action: 命名空间+方法名, 如果不加, 使用非cxf客户端调用的时候报错
@WebMethod(operationName="diWebIntegration", action = "http://www.dix.com/diWebIntegration")
@WSDLDocumentation( "调用该接口进行数据传输")
public String diWebIntegration(@WebParam(name="jsArr", targetNamespace="http://www.dix.com") String jsArr);
}
}
3. 实现类
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import org.apache.cxf.annotations.WSDLDocumentation;
import org.apache.cxf.annotations.WSDLDocumentationCollection;
@WebService
(
name="diWebInter", // 服务实现类的名称
serviceName="diWebInterService", // 默认在发布的服务实现者的名称后面添加Service
portName="diWebInterPort", // 服务类型的名称: 默认在 发布的服务实现者(MyWebService) 后面添加 port
targetNamespace="http://www.dix.com" // 发布ws服务的命名空间,此空间默认为当前服务包路径的 "倒写"此名称也是 wsimport 命令生成 java类时默认的包路径 -p
)
@WSDLDocumentationCollection(
{
@WSDLDocumentation(value = "webserviceDemo "
+ "调用的方法为: diWebIntegration(String jsArr), "
+ "参数格式: JSONArray格式的字符串.",
placement = WSDLDocumentation.Placement.TOP)
}
)
public class IUserServiceImpl implements IUserService {
// 注意 一定要加 action: 命名空间+方法名, 如果不加, 使用非cxf客户端调用的时候报错
@WebMethod(operationName="diWebIntegration", action = "http://www.dix.com/diWebIntegration")
@WSDLDocumentation( "调用该接口进行数据传输")
public String diWebIntegration(@WebParam(name="jsArr", targetNamespace="http://www.dix.com") String jsArr) {
System.out.println("WebService sayHello "+jsArr);
return "sayHello "+jsArr;
}
}
4. 启动类
启动类调用有两种方式可以实现, 一种是JDK Endpoint, 还有一种是cxf.frontend, 但是在测试过程中发现自定义的一些注解不生效
import javax.xml.ws.Endpoint;
import org.apache.cxf.frontend.ServerFactoryBean;
public class WebServicePublish {
public static void main(String[] args) {
// JDK Endpoint方式调用
String address = "http://localhost:10068/webservice/path";
Endpoint.publish(address , new IUserServiceImpl ());
System.out.println("发布webservice成功!");
/*cxf.frontend方式调用, 在测试时, 发现该方法调用, 自定的注释不生效*/
// ServerFactoryBean sf=new ServerFactoryBean();
// //服务实现类
// sf.setServiceClass(IUserServiceImpl .class);
// //服务的发布地址
// sf.setAddress("http://localhost:8080/WS_Server/Webservice");
// //服务的实例
// sf.setServiceBean(new WebServiceImpl());
// //发布服务
// sf.create();
// System.out.println("server ready……");
}
}
5.启动成功效果图
当我们发布成之后, 在浏览器访问我们的接口地址http://192.168.1.183:10068/webservice/path
+ ?wsdl
后缀, 看到如下结果
具体内容:
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.dix.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="diWebInterService"targetNamespace="http://www.dix.com">
<wsdl:documentation>
数据对接接口: 供第三方系统调用, 调用的方法为: diWebIntegration(String jsArr), 参数格式: JSONArray格式的字符串.
</wsdl:documentation>
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.dix.com" elementFormDefault="unqualified" targetNamespace="http://www.dix.com" version="1.0">
<xs:element name="diWebIntegration" type="tns:diWebIntegration"/>
<xs:element name="diWebIntegrationResponse" type="tns:diWebIntegrationResponse"/>
<xs:complexType name="diWebIntegration">
<xs:sequence>
<xs:element form="qualified" minOccurs="0" name="jsArr" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="diWebIntegrationResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="diWebIntegrationResponse">
<wsdl:part element="tns:diWebIntegrationResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="diWebIntegration">
<wsdl:part element="tns:diWebIntegration" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="diWebInter">
<wsdl:operation name="diWebIntegration">
<wsdl:documentation>调用该接口进行数据传输</wsdl:documentation>
<wsdl:input message="tns:diWebIntegration" name="diWebIntegration"></wsdl:input>
<wsdl:output message="tns:diWebIntegrationResponse" name="diWebIntegrationResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="diWebInterServiceSoapBinding" type="tns:diWebInter">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="diWebIntegration">
<soap:operation soapAction="http://www.dix.com/diWebIntegration" style="document"/>
<wsdl:input name="diWebIntegration">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="diWebIntegrationResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="diWebInterService">
<wsdl:port binding="tns:diWebInterServiceSoapBinding" name="diWebInterPort">
<soap:address location="http://localhost:8080/WS_Server/Webservice"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
6. 总结(注解解释)
可以看到,一个webservice的接口就发布成功了, 注意到我们在上面用了好多注解, 那么具体都是什么意思呢, 一起来看下:
@WebService
- –1、
serviceName
: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service。缺省值为 Java 类的简单名称 + Service。(字符串) - –2、
endpointInterface
: 服务接口全路径, 指定做SEI(Service EndPoint Interface)服务端点接口 - – 3、
name
:此属性的值包含XML Web Service的名称。在默认情况下,该值是实现XML Web Service的类的名称,wsdl:portType 的名称。缺省值为 Java 类或接口的非限定名称。(字符串) - –4、
portName
: wsdl:portName。缺省值为 WebService.name+Port。 - –5、
targetNamespace
:指定你想要的名称空间,认是使用接口实现类的包名的反缀 - –6、
wsdlLocation
:指定用于定义 Web Service 的 WSDL 文档的 Web 地址。Web 地址可以是相对路径或绝对路径。(字符串)注意:实现类上可以不添加Webservice注解
@WebMethod
该注释表示作为一项 Web Service 操作的方法,将此注释应用于客户机或服务器服务端点接口(SEI)上的方法,或者应用于 JavaBeans 端点的服务器端点实现类。
要点: 仅支持在使用 @WebService 注释来注释的类上使用 @WebMethod 注释
- –1、
operationName
:指定与此方法相匹配的wsdl:operation 的名称。缺省值为 Java 方法的名称。(字符串) - –2、
action
:定义此操作的行为。对于 SOAP 绑定,此值将确定 SOAPAction 头的值。缺省值为 Java 方法的名称。(字符串) - – 3、
exclude
:指定是否从 Web Service 中排除某一方法。缺省值为 false。(布尔值)
@WebParam
注释用于定制从单个参数至 Web Service 消息部件和 XML 元素的映射。将此注释应用于客户机或服务器服务端点接口(SEI)上的方法,或者应用于 JavaBeans 端点的服务器端点实现类。
- –1、
name
:参数的名称。如果操作是远程过程调用(RPC)类型并且未指定partName 属性,那么这是用于表示参数的 wsdl:part 属性的名称。
如果操作是文档类型或者参数映射至某个头,那么 -name 是用于表示该参数的 XML 元素的局部名称。如果操作是文档类型、
参数类型为 BARE 并且方式为 OUT 或 INOUT,那么必须指定此属性。(字符串) - –2、
partName
:定义用于表示此参数的 wsdl:part属性的名称。仅当操作类型为 RPC 或者操作是文档类型并且参数类型为BARE 时才使用此参数。(字符串) - –3、
targetNamespace
:指定参数的 XML 元素的 XML 名称空间。当属性映射至 XML 元素时,仅应用于文档绑定。缺省值为 Web Service 的 targetNamespace。(字符串) - –4、
mode
:此值表示此方法的参数流的方向。有效值为 IN、INOUT 和 OUT。(字符串) - –5、
header
:指定参数是在消息头还是消息体中。缺省值为 false。(布尔值)
@WebResult
注释用于定制从返回值至 WSDL 部件或 XML 元素的映射。将此注释应用于客户机或服务器服务端点接口(SEI)上的方法,或者应用于 JavaBeans 端点的服务器端点实现类。
- –1、
name
:当返回值列示在 WSDL 文件中并且在连接上的消息中找到该返回值时,指定该返回值的名称。对于 RPC 绑定,这是用于表示返回值的 wsdl:part属性的名称。对于文档绑定,-name参数是用于表示返回值的 XML 元素的局部名。对于 RPC 和 DOCUMENT/WRAPPED 绑定,缺省值为 return。对于 DOCUMENT/BARE 绑定,缺省值为方法名 + Response。(字符串) - –2、
targetNamespace
:指定返回值的 XML 名称空间。仅当操作类型为 RPC 或者操作是文档类型并且参数类型为 BARE 时才使用此参数。(字符串) - –3、
header
:指定头中是否附带结果。缺省值为false。(布尔值) - –4、
partName
:指定 RPC 或 DOCUMENT/BARE 操作的结果的部件名称。缺省值为
@HandlerChain
注释用于使 Web Service 与外部定义的处理程序链相关联。只能通过对 SEI 或实现类使用 @HandlerChain 注释来配置服务器端的处理程序。
但是可以使用多种方法来配置客户端的处理程序。可以通过对生成的服务类或者 SEI 使用 @HandlerChain 注释来配置客户端的处理程序。此外,可以按程序在服务上注册您自己的 HandlerResolver 接口实现,或者按程序在绑定对象上设置处理程序链。
- –1、
file
:指定处理程序链文件所在的位置。文件位置可以是采用外部格式的绝对 java.net.URL,也可以是类文件中的相对路径。(字符串) - –2、
name
:指定配置文件中处理程序链的名称。
@Oneway
注释将一个方法表示为只有输入消息而没有输出消息的 Web Service 单向操作。将此注释应用于客户机或服务器服务端点接口(SEI)上的方法,或者应用于 JavaBeans 端点的服务器端点实现类
@WSDLDocumentationCollection
自定义wsdl页面的提示, 使用在接口或者类上
@WSDLDocumentation
自定义wsdl页面提示, 使用在方法上
看到这, 是不是感觉实现一个webservice
的服务端接口也并不是很繁琐呢