目录
含义:webService即web服务,他是一种跨编程语言和跨操作系统平台的远程调用技术。
注意:客户端与服务端可能使用不同语言开发的,但是通过webservice提供的服务接口,客户端与服务端之间可以传递对象。
JAX-WS:java API for XML-WebService,jdk1.6版本自带JAX-WS2.1,其底层支持JAXB;JAX-WX规范的API位于javax.xml.ws.*包内,其中大部分都是注解,提供API操作web服务
JAXM&SAAJ:
- JAXM:java API for XML Message,其主要定义了包含发送和接收消息的API,相当于Web服务的服务器端,其API位于javax.messaging.*包,他是javaEE的可选包,因此需要单独下载
- SAAJ:soap with Attachment API for java,其为与JAXM搭配使用的API,为构建soap包和解析soap包提供了重要的支持;其支持附件传输,他在客户端和服务端都需要使用,其API位于javax.xml.soap.*包
JAX-RS:java API for RESTful Web Services,其是java针对REST风格定制的一套web服务规范,该API位于javax.ws.rs.*包内。
注意:
含义:simple object access protocol——简单对象访问协议,它是用于交换XML编码信息的轻量级协议。
理解:
含义:WSDL(网络服务描述语言,Web Services Description Language)是一门基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问。
理解:
含义:UDDI是一个跨产业、跨平台的开放性架构,其可帮助web服务提供商在互联网上发布web服务的信息
理解:
由于soap是基于xml传输的,本身使用xml传输会传输一些无关的内容进而影响效率,随着soap的完善,soap协议增加了许多内容,这样就导致了使用soap去完成简单的数据传输而携带的信息变得更多进而影响效率
注意:基于JAX-RS规范下的webservice也可以传输json格式数据,这在一定程度上弥补了传输效率问题
含义:面向服务架构,其是一种思想,它将应用程序的不通功能单元通过中立的契约联系起来,使得各种形式的功能单元相互集成,目前来说webservice是soa的一种较好的实现方式。
含义:其是Apache开源基金组织提供的优秀的webservice实现框架
导入依赖
-
- <dependencies>
- <dependency>
- <groupId>org.apache.cxfgroupId>
- <artifactId>cxf-rt-frontend-jaxwsartifactId>
- <version>3.0.1version>
- dependency>
-
- <dependency>
- <groupId>org.apache.cxfgroupId>
- <artifactId>cxf-rt-transports-http-jettyartifactId>
- <version>3.0.1version>
- dependency>
-
- <dependency>
- <groupId>org.slf4jgroupId>
- <artifactId>slf4j-log4j12artifactId>
- <version>1.7.12version>
- dependency>
-
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>4.11version>
- <scope>testscope>
- dependency>
- dependencies>
在resources文件内添加日志(log4j.properties)
- #info等级的日志输出到CONSOLE和LOGFILE这两个目的地(LOGFILE表示将日志写到文件中,CONSOLE则将日志写到控制台)
- log4j.rootCategory=info,CONSOLE,LOGFILE
- #设置日志优先控制台输出
- log4j.logger.org.apache.axis.enterprise=FATAL,CONSOLE
- #定义控制台日志输出器
- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
- #控制台日志布局
- log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
- #控制台日志布局的设置
- log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601}%-6r[%15.15t]%-5p %30.30c %x-%m\n
- #定义文件日志输出器
- log4j.appender.LOGFILE=org.apache.log4j.FileAppender
- #日志的存放位置
- log4j.appender.LOGFILE.File=C:\\All\\jax.log
- #启用文件日志追加模式
- log4j.appender.LOGFILE.Append=true
- #文件日志布局
- log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
创建服务接口
- @WebService
- public interface HelloWorld {
- //对外发布服务的接口的方法
- public String sayHello(String name);
- }
注意:对外发布服务的接口,需要用@webservice注解来标识这是一个webservice接口
创建接口实现类
- public class HelloWorldImpl implements HelloWorld {
- public String sayHello(String name) {
- return name+"hello webservice!";
- }
- }
测试类内发布服务
- public class WsTest {
- public static void main(String[] args) {
- //创建发布服务的工厂
- JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
- //设置服务地址
- factory.setAddress("http://localhost:8000/ws/hello");
- //设置发布的服务类
- factory.setServiceBean(new HelloWorldImpl());
- //添加日志输入、输出拦截器,观察soap请求以及soap响应内容
- factory.getInInterceptors().add(new LoggingInInterceptor());
- factory.getOutInterceptors().add(new LoggingOutInterceptor());
- //发布服务
- factory.create();
- System.out.println("发布服务成功,端口8000放行");
- }
- }
访问wsdl说明书
注意:在之前设置服务的地址后面加?wsdl
- <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.tedu.cn/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://tedu.cn/" name="HelloWorldImplService" targetNamespace="http://impl.tedu.cn/">
- <wsdl:import location="http://localhost:8000/ws/hello?wsdl=HelloWorld.wsdl" namespace="http://tedu.cn/"> wsdl:import>
- <wsdl:binding name="HelloWorldImplServiceSoapBinding" type="ns1:HelloWorld">
- <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
- <wsdl:operation name="sayHello">
- <soap:operation soapAction="" style="document"/>
- <wsdl:input name="sayHello">
- <soap:body use="literal"/>
- wsdl:input>
- <wsdl:output name="sayHelloResponse">
- <soap:body use="literal"/>
- wsdl:output>
- wsdl:operation>
- wsdl:binding>
- <wsdl:service name="HelloWorldImplService">
- <wsdl:port binding="tns:HelloWorldImplServiceSoapBinding" name="HelloWorldImplPort">
- <soap:address location="http://localhost:8000/ws/hello"/>
- wsdl:port>
- wsdl:service>
- wsdl:definitions>
导入依赖(和服务端使用的依赖一样)
获得服务端接口
- @WebService
- public interface HelloWorld {
- public String sayHello(String name);
- }
注意:客户端获得的服务端接口的包名.接口名必须与服务端的包名.接口名都相同才可以进行远程调用(也必须有@WebService注解)
远程访问服务端
- public class ClientTest {
- public static void main(String[] args) {
- //服务接口的访问地址:http://localhost:8000/ws/hello
- //创建cxf代理工厂
- JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
- //设置远程访问服务端的地址
- factory.setAddress("http://localhost:8000/ws/hello");
- //设置接口的类型
- factory.setServiceClass(HelloWorld.class);
- //对该接口生成代理对象
- HelloWorld helloWorld = factory.create(HelloWorld.class);
- //打印代理对象类型
- System.out.println(helloWorld.getClass());
- //远程访问服务端方法
- String msg = helloWorld.sayHello("lili");
- System.out.println(msg);
- }
- }
导入依赖
-
-
-
-
org.apache.cxf -
cxf-rt-frontend-jaxrs -
3.0.1 -
-
-
-
org.apache.cxf -
cxf-rt-transports-http-jetty -
3.0.1 -
-
-
-
org.slf4j -
slf4j-log4j12 -
1.7.12 -
-
-
-
org.apache.cxf -
cxf-rt-rs-client -
3.0.1 -
-
-
-
org.apache.cxf -
cxf-rt-rs-extension-providers -
3.0.1 -
-
-
org.codehaus.jettison -
jettison -
1.3.7 -
-
-
-
junit -
junit -
4.11 -
test -
-
-
-
-
-
-
org.apache.maven.plugins -
maven-compiler-plugin -
3.1 -
-
-
1.8 -
UTF-8 -
true -
-
-
-
在resources文件内添加日志(log4j.properties)
- #info等级的日志输出到CONSOLE和LOGFILE这两个目的地(LOGFILE表示将日志写到文件中,CONSOLE则将日志写到控制台)
- log4j.rootCategory=info,CONSOLE,LOGFILE
- #设置日志优先控制台输出
- log4j.logger.org.apache.axis.enterprise=FATAL,CONSOLE
- #定义控制台日志输出器
- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
- #控制台日志布局
- log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
- #控制台日志布局的设置
- log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601}%-6r[%15.15t]%-5p %30.30c %x-%m\n
- #定义文件日志输出器
- log4j.appender.LOGFILE=org.apache.log4j.FileAppender
- #日志的存放位置
- log4j.appender.LOGFILE.File=C:\\All\\jax.log
- #启用文件日志追加模式
- log4j.appender.LOGFILE.Append=true
- #文件日志布局
- log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
创建实体类(User)
- @XmlRootElement(name="User")
- public class User {
- private String name;
- private String city;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getCity() {
- return city;
- }
- public void setCity(String city) {
- this.city = city;
- }
- @Override
- public String toString() {
- return "User{" +
- "name='" + name + '\'' +
- ", city='" + city + '\'' +
- '}';
- }
- }
@XmlRootElement(name="User")
作用:基于restful风格的webservice,客户端与服务端之间的通讯可以传递xml数据、json数据;而@XmlRootElement用于指定对象序列化为xml或json数据时根节点的名称。
- xml形式
-
张三 -
北京 -
- json形式
- {"User":{"name":"张三","city":"北京"}}
创建服务端接口(IUserService)
- @Path("/userService")
- @Produces("*/*")
- public interface IUserService {
- @POST
- @Path("/save")
- @Consumes({"application/xml","application/json"})
- String saveUser(User user);
- @GET
- @Path("/get/{name}")
- @Consumes("application/xml")
- @Produces({"application/xml","application/json"})
- User findUserByName(@PathParam("name") String name);
- }
@Path("/userService")
理解:该注解可以用在类上以及方法上,表示当前服务接口或接口方法对应的路径(若要访问接口方法则必须先访问接口,在接口的基础上进行path路径拼接)
@POST或@GET
含义:处理接口对应方法的请求类型
@Produces({"application/xml","application/json"})
含义:服务器所支持的返回的数据格式(xml格式或json格式)
@Consumes("application/xml")
含义:服务器所支持的请求数据的格式类型
@PathParam
作用:注解用于路径中的参数与接口方法中的参数进行绑定
创建接口实现类(UserServiceImpl)
- public class UserServiceImpl implements IUserService {
- @Override
- public String saveUser(User user) {
- System.out.println("保存了"+user.toString());
- return "user保存成功";
- }
- @Override
- public User findUserByName(String name) {
- User user = new User();
- if ("lili".equals(name)){
- user.setName("lili");
- user.setCity("北京");
- }else {
- user.setName("随机");
- user.setCity("随机");
- }
- return user;
- }
- }
发布服务
- public class JaxrsTest {
- public static void main(String[] args) {
- //创建发布服务的工厂
- JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean();
- //设置服务地址
- factoryBean.setAddress("http://localhost:8001/");
- //设置服务类
- factoryBean.setServiceBean(new UserServiceImpl());
- //添加日志输入输出拦截器
- factoryBean.getInInterceptors().add(new LoggingInInterceptor());
- factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
- //发布服务
- factoryBean.create();
- System.out.println("发布服务成功。端口:8001");
- }
- }
导入依赖(和服务端使用的依赖一样)
制作需要使用的实体类
- @XmlRootElement(name="User")
- public class User {
- private String name;
- private String city;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getCity() {
- return city;
- }
- public void setCity(String city) {
- this.city = city;
- }
- @Override
- public String toString() {
- return "User{" +
- "name='" + name + '\'' +
- ", city='" + city + '\'' +
- '}';
- }
- }
注意:这里实体类所用的包名可以和服务端的不一样,但是@XmlRootElement(name="User")注解必须存在
远程调用服务端
前言:这里远程调用服务端只需要使用WebClient工具类即可完成,他调用请求方法后所返回的返回值为Response对象,该对象可以通过readEntity()方法来获取特定类型的返回值供我们使用。
WebClient中的静态方法
注意:以上方法除了post()和get()等请求的方法返回值为Response类型,其他方法的返回值均为WebClient类型,所以可以实现链式调用
- public class ClientTest {
- public static void main(String[] args) {
- User user = new User();
- user.setName("nana");
- user.setCity("广东");
- //通过WebClient对象远程调用服务端(post请求)
- Response response = WebClient.create("http://localhost:8001/userService/save").type("xml").accept("json").post(user);
- //读取response中请求体的内容,并获取特定类型的返回值
- String s = response.readEntity(String.class);
- System.out.println(s);
- //通过WebClient对象远程调用服务端(get请求)
- Response response1 = WebClient.create("http://localhost:8001/userService/get/lili").accept("xml").type("json").get();
- //读取response中请求体的内容,并获取特定类型的返回值
- User user1 = response1.readEntity(User.class);
- System.out.println(user1);
- }
- }