加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

WebService基本

发布时间:2020-12-16 22:43:32 所属栏目:安全 来源:网络整理
导读:1. 介绍和说明 Webservice的一个最基本的目的就是提供在各个不同平台的不同应用系统的协同工作能力。 它就是一个可以远程调用的类,或者说是组件。 WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交

1. 介绍和说明

Webservice的一个最基本的目的就是提供在各个不同平台的不同应用系统的协同工作能力。 它就是一个可以远程调用的类,或者说是组件。
WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息,wsld是服务者与消费者之间建立桥梁的关键。
Soap:(Simple Object Access Protocol)简单对象存取协议。是XML Web Service 的通信协议。当用户访问到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。
各种语言都对webservice进行支持,java中我们通过cxf来实现webservice,下面我们看一下如何通过cxf来实现我们的服务。

服务端公布服务:

JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
        factory.setServiceClass(Student.class);
        factory.setAddress("http://localhost:8080/myservice");
        Server server = factory.create();
        server.start();

这里使用的cxf内嵌的服务器Jetty来发布服务,其中Student类实现了Person接口,里面有一个方法sayHello,注意公布服务的时候一定要使用实现类,只有实现类才能提供服务。

客户端消耗服务:

JaxWsProxyFactoryBean client = new JaxWsProxyFactoryBean();
        client.setServiceClass(Person.class);
        client.setAddress("http://localhost:8080/myservice");
        Person std = (Person)client.create();

        System.out.println(std.sayHello("chm"));

客户端消费服务,在本地生成了远程的一个代码,我们从代理得到远程的对象必须声明为一个接口(动态代理)。

2. wsdl文件结构

访问上面公布的服务地址http://localhost:8080/myservice?wsld会看到这样一个文件

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://test.chm.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="StudentService" targetNamespace="http://test.chm.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.chm.com/" elementFormDefault="unqualified" targetNamespace="http://test.chm.com/" version="1.0">
  <xs:element name="sayHello" type="tns:sayHello"/>
  <xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>

  <xs:complexType name="sayHello"> <!-- 参数类型 包装成一个类 -->
    <xs:sequence>
      <xs:element minOccurs="0" name="name" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="sayHelloResponse"> <!-- 返回值类型 包装成一个类 -->
    <xs:sequence>
      <xs:element minOccurs="0" name="helloResult" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>
</wsdl:types>
  <wsdl:message name="sayHelloResponse">
    <wsdl:part element="tns:sayHelloResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="sayHello">
    <wsdl:part element="tns:sayHello" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="Person">
    <wsdl:operation name="sayHello"> <!-- name对应接口中方法名 -->
      <wsdl:input message="tns:sayHello" name="sayHello">
    </wsdl:input>
      <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="StudentServiceSoapBinding" type="tns:Person">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="sayHello"><!-- name对应实现类中方法名 -->
      <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="StudentService">
    <wsdl:port binding="tns:StudentServiceSoapBinding" name="StudentPort">
      <soap:address location="http://localhost:8080/myservice"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

看懂这个文件需要xml schema的一些知识,这里就不做介绍了,wsld文件结构从上往下是依次依赖与被依赖的关系,wsld:types标签里面描述了方法参数和返回值的类型,wsld:message依赖wsld:types中定义的元素,而又被下面的wsdl:portType里面的元素所依赖,wsld描述了接口的信息,而下面wsdl:binding接口实现类的信息,wsdl:operation描述的是方法的信息,所以wsdl:portType和wsdl:binding里面wsdl:operation标签中的name属性值是必须一样的,这对应到java代码中就是类实现接口并重新接口中的方法,最后wsdl:service描述了公布服务的地址信息。
了解以上信息后,我们就可以手动编写wsdl,然后通过cxf提供的工具来生成java代码,这种方式开发webservice我们称为契约优先(自顶向下)。

生成java代码命令:

  • D:apache-cxf-3.0.5bin>wsdl2java -server -impl -frontend jaxws21
    E:/myservice.
    生成服务端代码,包括实现类
  • D:apache-cxf-3.0.5bin>wsdl2java -client -frontend jaxws21
    E:/myservice.
    生成服客户端码
  • D:apache-cxf-3.0.5bin>wsdl2java -all -frontend jaxws21 E:/myservice.
    同时生成客户端和服务端代码

3. 编排与反编排

当我们从客户端调用webservice方法时,经历这样一个过程,先将我们的请求参数当成一个整体编排成soap消息发送个服务端,服务端接收到消息后进行反编排生成java代码,然后服务端处理完,将返回的内容依然编排成soap消息返回给客户端,客户端接收消息后反编排。编排与反编排可以通过JaxbContext这个类来实现,这是jdk里面的一个类。JAXB(Java Architecture for XML Binding)是一个业界的标准,cxf有对应jaxb的实现。

try {
            JAXBContext context = JAXBContext.newInstance(Person.class);
            Marshaller marshaller = context.createMarshaller();
            Person person = new Person();
            person.setName("zhangsan");
            person.setAge(30);
            marshaller.marshal(person,System.out);

            System.out.println();
            String person2 = "<person><name>lisi</name><age>20</age></person>";

            Unmarshaller unmarshaller = context.createUnmarshaller();
            Person p = (Person)unmarshaller.unmarshal(new StringReader(person2));
            System.out.println(p.getName());

        } catch (JAXBException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

4.TcpMon和JMeter的使用

TcpMon用于截取soap消息。 JMeter用于压力测试,当然除了测试webservice还可以做许多其他的测试。这里我需要TcpMon截取的soap消息进行测试。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读