WebService的注解都位于javax.jws包下:
@WebService-定义服务,在类上边
targetNamespace:指定命名空间,一般是接口的包名倒序
name:portType的名称,客户端生成代码时 为接口名称
portName:port的名称
serviceName:服务名称
endpointInterface:SEI接口地址,如果一个服务类实现了多个接口,只需要发布一个接口的方法,可通过此注解指定要发布服务的接口。
@WebMethod-定义方法,在公开方法上边
operationName:方法名
exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法,默认是false
@WebResult-定义返回值,在方法返回值前边
name:返回结果值的名称
@WebParam-定义参数,在方法参数前边
name:指定参数的名称
Java项目中 发布 一个WebService服务:
@WebService
EndPoint
publish()
方法用于将一个已经添加了@WebService 注解对象绑定到一个地址的端口上,用于发布package cn.tgb.ws;
importjavax.jws.WebMethod;
importjavax.jws.WebService;
importjavax.xml.ws.Endpoint;
@WebService
public classHelloWebService {
publicString HelloWord(String name){
return"Hello: "+name;
}
/**
* @WebMethod-定义方法,在公开方法上边
* exclude:设置为true表示此方法不是webservice方法
* 添加exclude=true后,HelloWord2()方法不会被发布
*/
@WebMethod(exclude=true)
public String HelloWord2(String name){
return"Hello: "+name;
}
publicstatic void main(String[] args) {
/**
* 参数1:服务的发布地址
* 参数2:服务的实现者
*/
Endpoint.publish("http://192.168.24.138:456/helloWord",
new HelloWebService());
}
}
运行以上程序进行发布
然后浏览器访问:http://192.168.24.138:456/helloWord?wsdl
只要在客户端浏览器能看到此WSDL文档,说明服务发布成功
注意:
EndPoint
是 jdk 提供的一个专门用于发布服务的类,该类的publish()
方法接收两个参数,一个是本地的服务地址,二是提供服务的类。位于javax.xml.ws.Endpoint包中- 类上添加注解
@WebService
类中所有 非静态方法 都会被发布;
静态方法和 final 方法不能被发布;
方法上加@WebMentod(exclude=true)后,此方法不被发布
wsimport是jdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码)
wsimport.exe位于JAVA_HOME\bin目录下
常用参数为:
-d<目录> - 将生成.class文件。默认参数。
-s<目录> - 将生成.java文件。
-p<生成的新包名> -将生成的类,放于指定的包下
根据WSDL文档来在客户端编写代码,访问发布的服务
wsimport
是JDK自带的,可以根据WSDL文档生成客户端调用代码的工具。无论服务器端WebService使用什么语言编写的,都将在客户端生成Java代码
wsimport.exe命令参数:
-d
:生成 .class 文件。默认参数。-s
:生成 .java 文件-p
:自定义包结构。将生成的类,放于指定的包下例如:
解析地址生成源码到E盘
wsimport -s . http://192.168.24.138:456/helloWord?wsdl
自定义包结构的命令:
wsimport -s . -p com.test.ws.client http://192.168.24.138:456/helloWord?wsdl
webservice 主流框架:CXF官网、XFire、Axis1/2
这里学习的是 ApacheCXF 框架下的 WebService,Apache CXF = Celtix + XFire,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用
在服务端启动后,访问暴露的地址加上 ?wsdl
,得到报文,总览如下:
<definitions>
<types> 定义 webservice 使用的数据类型
<message> 每个消息均有一个或多个部件,可看作是 Java 中方法调用的参数
<portType>类似Java中的一个函数库/一个模块/一个类
<binding>为每个端口定义消息格式和协议细节
definitions>
在 Java 中定义的服务接口中方法的输入参数和返回值
图片中的报文,参数和返回值的名字都是默认的
可以在方法中修改为自定义的,修改方式如下:
修改重启后如下:
JAXB 可以实现 java 对象与 XML格式之间的转换
Unmarshaller
类将XML转化为Java对象
Marshaller
类将Java对象转化为XML
@XmlRootElement
注解使用在 pojo 类上,表明xml的根元素用类名表示
提供实体类:
@XmlRootElement
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Book {
private Long id;
private String bookName;
private double price;
}
编写 Unmarshaller + Marshaller 程序:
public static void main(String[] args) throws JAXBException {
myMarshaller();
myUnMarshaller();
}
private static void myMarshaller() throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");
marshaller.marshal(new Book(1L,"入门",33.45d),System.out);
}
private static void myUnMarshaller() throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
String xmlString = ""+
"" +
" 入门 "+
" 1 "+
" 33.45 "+
"";
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Book book = (Book) unmarshaller.unmarshal(new StringReader(xmlString));
System.out.println(book.toString());
}
就可以实现 Java 对象与 XML 格式之间的转换
JAX-WS 会将 API 的调用转换成对应的 SOAP 消息,可以完成 wsdl 到 Java 的转换,是关于 WebService 的开发标准
客户端根据命令和 服务的提供的地址,得到一系列的 .java 文件
将其中关键的两个类打包成 jar 包,作为客户端的依赖引用,即可实现业务调用执行
客户端就可以使用这些代码得到服务端使用的业务接口
上面的情况还是需要自己调用方法来返回业务接口。使用以下命令可以直接生成业务接口,供调用执行