WebService 学习基础-1

WebService 学习基础-1

Schema规范

  • 所有的标签和属性都需要由schema文件来定义
  • 所有的schema文件都需要有一个命名空间(namespace)作为其id
  • schema文档的namespacetargetNamespace属性来指定,其值为一个url (不一定能够访问)
  • xml文档引入相应schema 文档,使用xmlns属性来指定其值(schema文档的targetNamespace属性)
  • 如果引入的schema不是W3C定义的,必须指定schema文档(.xsd)的地址,其值由schemaLocation属性确定.schemaLocation的值形式为“namespace值 文档位置(.xsd)”
  • schemaLocation属性的使用需引入http://www.w3.org/2001/XMLSchema-instance命名空间
  • 引入多个命名空间时,在xmlns后面使用(冒号): 别名 来指定别名,其下面定义的标签都要使用别名:标签名形式。如xmlns:xsd="http://www.w3.org/2001/XMLSchema",则有<xsd:annotation>

HTTP协议

请求(request)

  • 请求行(请求方式,协议版本等)
  • 请求头()
  • 请求体,POST请求时才有

响应(response)

  • 状态行(协议版本 状态码 原因描述)
  • 响应头
  • 响应体

WebService

常用webservice http://www.webxml.com.cn/zh_cn/web_services.aspx

  • 跨平台
  • 跨语言
  • 网络访问,远程调用

常用术语

  • wsdl—— Web Services Description Language

    定义了webservice服务端与客户端交互传递请求和响应数据的格式

    一个webservice对应一个唯一的wsdl文件

  • soap——simple object access protocol

    基于http和xml的协议,用于在web上交换结构化的数据

    soap消息:请求消息和响应消息

    http+xml片段

  • SEI ——webservice endpoint interface(终端)

    服务器端用来处理请求的接口

  • CXF

  • Axis2

使用JDK开发WebService

  1. 定义SEI

    package com.vtech.service;
    //SEI
    @WebService
    public interface HelloWS{
    @WebMethod
    String sayHi(String txt);
    }
  2. 定义实现类

    package com.vtech.service.impl;
    @WebService
    public class HelloWSImpl implements HelloWS{
    @Override
    public String sayHi(String txt){
    System.out.println("sayHi: " + txt);
    return "Hello" + txt;
    }
    }
  3. 发布服务

    public class ServiceTest
    {
    protected ServiceTest() throws Exception {
    // START SNIPPET: publish
    System.out.println("Starting Server");
    HelloWSImpl implementor = new HelloWSImpl();
    String address = "http://localhost:9000/services/hello";//服务地址
    Endpoint.publish(address, implementor);//发布
    // END SNIPPET: publish
    }
    public static void main(String args[]) throws Exception {
    new ServiceTest();
    System.out.println("Server ready...");
    //Thread.sleep(5 * 60 * 1000);
    //System.out.println("Server exiting");
    //System.exit(0);
    }
    }
  4. 查看WSDL文件

    访问http://localhost:9000/services/hello?wsdl

    (不加?wsdl访问报No binding operation info while invoking unknown method with params unknown.)

  5. 生成客户端代码

    使用jdkwsimport.exe工具生成客户端代码

    wsimport -keep -p com.vtech.ws.client http://localhost:9000/services/hello?wsdl

    命令参数说明:

    • -d: 生成客户端执行类的class文件的存放目录

    • -s: 生成客户端执行类的源文件的存放目录

    • -p: 定义生成类的包名

    • -keep 导出webservice的class文件时是否也导出源代码Java文件

    • 注意:若是在包下面执行的命令,不需要再加包名了

    • 生成sayHi方法对应的类SayHiSayHiResponseHelloWSHelloObjectFactory等类/接口,如果有服务端定义了实体类,还会生成相应的实体类。其中Hello就是生成的客户端类

      @WebServiceClient(name = "hello", targetNamespace = "http://impl.service.vtech.com/", wsdlLocation = "http://localhost:9000/services/hello?wsdl")
      public class Hello extends Service
      {
      //...其他代码
      }
  6. 测试客户端代码

    public class ClientTest
    {
    4public static void main(String args[])
    4{
    44Hello helloFactory = new Hello();
    44// 代理对象
    44HelloService service = helloFactory.getHelloServiceImplPort();
    44String hi = service.sayHi(" houzw");
    44System.out.println(hi);
    4}
    }

    注意:测试时可能报错

    IllegalAnnotationException: Two classes have the same XML type name

    两个类具有相同的 XML 类型名称 "{http://service.vtech.com/}sayHiResponse"。请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。
    4this problem is related to the following location:
    44at com.vtech.webservice.jaxws_asm.SayHiResponse
    4this problem is related to the following location:
    44at com.vtech.webservice.SayHiResponseVO
    44at public javax.xml.bind.JAXBElement com.vtech.webservice.ObjectFactory.createSayHiResponse(com.vtech.webservice.SayHiResponseVO)
    44at com.vtech.webservice.ObjectFactory

    这时候需要修改相关类上面内容。如将生成的下述代码中的XmlType中的sayHiResponse改为sayHiResponse2

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "sayHiResponse2", propOrder = {
    44"_return"
    })
    public class SayHiResponse{
    //...
    }

    这是由于JAX-WS对webservice里面的每个方法都生成一个类,生成的类名为:methodName + "Response"(查看wsdl文件中的wsdl:output 可以发现), 所以就会导致生成的类和原来的类有两个相同的xml type

    • 更换返回值对象的name (如加Msg)
    @XMLType(name="CreateProcessResponseMsg", namespace="http://xxx.yyy.com")
    • 更换返回值对象的namespace(如加message)
    @XMLType(name="CreateProcessResponse", namespace="http://xxx.yyy.com/message")
    • 给方法上加上下面的注解.这个注解其实会改变生成的类的名称,对接口是没有影响的.

      @WebMethod(operationName="differentFromMethodName")

    如果使用cxf的wsdl2java生成代码,在命令参数中加-xjc-npa

文章目录
  1. 1. WebService 学习基础-1
    1. 1.0.1. Schema规范
    2. 1.0.2. HTTP协议
      1. 1.0.2.1. 请求(request)
      2. 1.0.2.2. 响应(response)
    3. 1.0.3. WebService
      1. 1.0.3.1. 常用术语
    4. 1.0.4. 使用JDK开发WebService
|