菜鸟笔记
提升您的技术认知

webservice总结-ag真人游戏

webservice简介

含义:webservice即web服务,他是一种跨编程语言和跨操作系统平台的远程调用技术。

webservice架构图

理解:

  • 跨语言:右侧为服务端,左侧为客户端;若右边的服务使用php语言实现的,那么调用右边服务端的客户端不管是用什么语言实现的,都可以去远程访问右边的客户端的接口。
  • 跨平台:无论右边的服务端部署在那个系统平台,只要其提供了一个接口给外界去调用,那么左边的客户端部署在哪里,使用什么语言,一样可以远程调用服务端。
  • webservice主要适用于多个系统之间的交互以及数据传递

注意:客户端与服务端可能使用不同语言开发的,但是通过webservice提供的服务接口,客户端与服务端之间可以传递对象。

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.*包内。

注意:

  • jax-ws和jaxm&saaj是基于soap协议,而jax-rs基于http协议。
  • 三者规范中,只有jax-rs规范支持传递json数据,其他的规范都仅支持传递xml数据

含义:simple object access protocol——简单对象访问协议,它是用于交换xml编码信息的轻量级协议。

soap的组成

  • envelope:其为必须的部分,以xml的根元素出现
  • headers:可选的
  • body:必须的,在body部分包含了要执行的服务器的方法和发送给服务器的数据

理解:

  • soap作为一个基于xml语言的协议用于网上传输数据
  • soap是基于http的,他相当于在http的基础上 xml数据格式
  • soap可以运行在任何其他传输协议上
  • xml-envelope为描述信息内容和如何处理内容定义了框架,将程序编码成了xml对象的规则,执行远程调用(rpc)的约定 

含义:wsdl(网络服务描述语言,web services description language)是一门基于 xml 的语言,用于描述 web services 以及如何对它们进行访问。

理解:

  • 通过wsdl说明书,就可以描述webservice服务端对外发布的服务
  • wsdl说明书基于xml文件,其可以通过xml语言来描述整个服务
  • 在wsdl中描述了:对外发布的服务名称(类)、接口的方法名称(方法)、接口参数(方法参数)、服务返回的数据类型(方法返回值)
  • 一般在webservice的url后面跟上?wsdl来获取wsdl信息

含义:uddi是一个跨产业、跨平台的开放性架构,其可帮助web服务提供商在互联网上发布web服务的信息

理解:

  • uddi就是一种目录服务,企业可以通过uddi来注册和搜索web服务
  • uddi通过soap进行通讯,其构建于.net之上

webservice优点

  • 异构平台的互通性(跨平台)
  • 更广泛的软件复用(远程调用实现复用)
  • 成本低,可读性强,应用范围广(基于soap协议)
  • 更迅捷的软件发行方式

webservice缺点

由于soap是基于xml传输的,本身使用xml传输会传输一些无关的内容进而影响效率,随着soap的完善,soap协议增加了许多内容,这样就导致了使用soap去完成简单的数据传输而携带的信息变得更多进而影响效率

注意:基于jax-rs规范下的webservice也可以传输json格式数据,这在一定程度上弥补了传输效率问题

含义:面向服务架构,其是一种思想,它将应用程序的不通功能单元通过中立的契约联系起来,使得各种形式的功能单元相互集成,目前来说webservice是soa的一种较好的实现方式。

含义:其是apache开源基金组织提供的优秀的webservice实现框架

cxf分为jax-ws和jax-rs两种开发方式

  • jax-ws:基于xml协议的webservice技术
  • jax-rs:基于restful风格的开发方式

服务端发布服务

导入依赖

       
       
        
            org.apache.cxf
            cxf-rt-frontend-jaxws
            3.0.1
        
        
        
            org.apache.cxf
            cxf-rt-transports-http-jetty
            3.0.1
        
        
        
            org.slf4j
            slf4j-log4j12
            1.7.12
        
        
        
            junit
            junit
            4.11
            test
        
    

在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[.15t]%-5p 0.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说明书

访问:http://localhost:8000/ws/hello?wsdl

注意:在之前设置服务的地址后面加?wsdl


 

















客户端访问服务

导入依赖(和服务端使用的依赖一样)

获得服务端接口

@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
                    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[.15t]%-5p 0.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");
    }
}

访问:http://localhost:8001/userservice/get/lili

客户端访问服务

导入依赖(和服务端使用的依赖一样)

制作需要使用的实体类

@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中的静态方法

  • create(string url):表示请求的服务端url地址
  • type(string type):指定请求的数据格式(xml、json)
  • accept(string type):指定接收响应的数据格式(xml、json)
  • post(请求参数):表示要带着该参数来发起post请求

注意:以上方法除了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);
    }
}
网站地图