zoukankan      html  css  js  c++  java
  • WebService

    完好格式见:https://www.zybuluo.com/Spancymath/note/1623555

    什么是WebService?

    基于web的服务,使用Web(HTTP)方式,接收和响应外部系统的某种请求,从而实现远程调用。

    名词解释

    1. XML: Extensible Markup Language - 扩展性标记语言
      用于传输格式化数据
    2. WSDL: WebService Description Language - Web服务描述语言
      通过XML形式说明服务在什么地方
      通过XML形式说明服务提供什么样的方法
    3. SOAP: Simple Object Access Protocol - 简单对象访问协议
      SOAP = 在HTTP的基础上+XML数据
      组成:Envelope(必须)+ Headers(可选)+ Body(必须)

    在Java项目中发布WS服务

    1. 在类上添加@WebService注解
    2. 通过EndPoint发布一个WebService
      a.给类添加@WebService注解后,类中的所有非静态、非final方法都将会对外公布
      b.如果不希望某个方法不对外公开,可以在方法上添加@WebService(Exclude=true)
    //1、添加注解
    @WebService
    public class OneService {
       //2、至少包含一个可以对外公开的服务
       public String sayHello(String name){
       System.err.println("invoke "+name);
       return "Hello "+name;
       }
       public static void main(String[] args) {
       //3、第一个参数称为Binding即绑定地址,
       //第二个参数是实现者,即谁提供服务
       Endpoint.publish("http://localhost:9999/one", new OneService());
       }
    }
    //4.在IE地址栏输入以下地址访问说明文件:
    http://localhost:9999/one?wsdl
    
    1. 通过wsimport生成本地代码

    常用参数为:
    -d<目录> - 将生成.class文件。默认参数。
    -s<目录> - 将生成.java文件。
    -p<生成的新包名> -将生成的类,放于指定的包下。
    (wsdlurl) - http://server:port/service?wsdl,必须的参数。
    示例:
    C:/> wsimport –s . http://192.168.0.100/one?wsdl

    1. 总结
      WebService和Web服务器的区别:WebService是Web服务器的应用,Web服务器是WebService运行所必须的容器。
      WebService其内部是通过Socket实现的。

    WebService的特点:

    • WebService通过HTTP POST方式接受客户的请求
    • WebService与客户端之间一般使用SOAP协议传输XML数据.
    • 它本身就是为了跨平台或跨语言而设计的。

    客户端调用WebService

    1. 通过wsimport生成客户端代码
    2. 通过客户端编程的方式调用
    3. 通过ajax调用 (js+XML)
    var xhr = new XMLHttpRequest();
               function sedAjax() {
                   var url = "http://localhost:8081/hello";
                   var nameText = document.getElementById("name").value;
                   var request = "<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">" +
                       "<soap:Body><ns2:sayHi xmlns:ns2="http://server/">" +
                       "<arg0>" + nameText + "</arg0></ns2:sayHi></soap:Body></soap:Envelope>";
                   $.ajax({
                       url: url,
                       type: "post",
                       contentType: "application/soap+xml;charset=utf-8",
                       data: request,
                       success: function (data) {
                           alert($(data).find("return").text());
                       }
                   })
    
               }
    
    1. 通过URLConnection调用

    SOAP请求过程分析

    • 使用get方式获取wsdl文件,称为握手。
      对于JDK1.6生成的ws服务,由于内部有一两个配置文件,所以会发出两次get请求。其他的一般为一次。
    • 用户发出请求将使用post方式。
    • 服务器响应成功。

    CXF

    1. 使用ServerFactoryBean发布应用
    • 使用CXF发布一个服务,与JDK6发布一个服务完全不同
      即使是不使用@WebService注解,一样可以发布成功
      即使此类没有对外公布的方法一样可以发布成功
    public class CxfServer1 implements ICxfServer1 {
    
       public String sayHi(String name) {
           return "Hello " + name;
       }
    
       public static void main(String[] args) {
           //声明实例,使用ServerFactoryBean发布服务
           //使用CXF发布一个服务,与JDK6发布一个服务完全不同
           //* 即使是不使用@WebService注解,一样可以发布成功
           //* 即使此类没有对外公布的方法一样可以发布成功
           ServerFactoryBean bean = new ServerFactoryBean();
           //绑定到发布地址的端口
           bean.setAddress("http://localhost:8080/cxf");
           //设置服务接口,如果没有接口,则为本类
           bean.setServiceClass(ICxfServer1.class);
           //设置接口实现类,即服务类
           bean.setServiceBean(new CxfServer1());
           //发布服务
           bean.create();
    
           System.err.println("启动成功");
       }
    }
    
    1. 使用JaxWsServerFactoryBean(建议使用此类)发布应用
    • JaxWsServerFactoryBean是ServerFactoryBean的子类,也是功能扩展类。
    • 但在CXF的API文档中没有提供此类API,请通过查看源代码的方式获取此类的帮助。
    • 此类,必须要在被发布为服务的类上添加@WebService注解,如果不加注解,虽然不
      出错,但也不会对外暴露任何方法。
      使用此类生成的wsdl文件更加规范。
    public class HelloImpl implements IHello {
       @Override
       public String sayHi(String name) {
           System.out.println("syaHi called");
           return "Hello2 " + name;
       }
    
       public static void main(String[] args) {
           //使用jaxWs对其进行发布
           JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();
           //设置访问地址
           bean.setAddress("http://localhost:8081/hello");
           //注册服务接口
           bean.setServiceClass(IHello.class);
           //注册服务实现类
           bean.setServiceBean(new HelloImpl());
    
           //添加消息拦截器
           bean.getInInterceptors().add(new LoggingInInterceptor());
           bean.getOutInterceptors().add(new LoggingOutInterceptor());
    
           //启动
           bean.create();
           System.out.println("服务启动完成...");
       }
    

    WebService-CXF-Spring 基于web的cxf

    1. 由于cxf的web项目已经集成了Spring所以,cxf的服务类都是在spring的配置文件中完成的。以下是步骤:
    • 第一步:建立一个web项目。
    • 第二步:准备所有jar包。将cxf_homelib项目下的所有jar包全部copy到新项目的lib目录下,里面已经包含了spring3.0的jar包。
    • 第三步:在web.xml中配置cxf的核心servlet,CXFServlet。
       <servlet>
           <servlet-name>cxf</servlet-name>
           <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
           <!--<init-param>
               <param-name>config-location</param-name>
               <param-value>classpath:cxf-servlet.xml</param-value>
           </init-param>-->
           <load-on-startup>1</load-on-startup>
       </servlet>
    
       <servlet-mapping>
           <servlet-name>cxf</servlet-name>
           <url-pattern>/ws/*</url-pattern>
       </servlet-mapping>
    
    • 第四步:创建(最好是Copy)cxf-servlet.xml文件。这是一个spring的配置文件。
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:jaxws="http://cxf.apache.org/jaxws"
          xmlns:soap="http://cxf.apache.org/bindings/soap"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://cxf.apache.org/bindings/soap
          http://cxf.apache.org/schemas/configuration/soap.xsd
          http://cxf.apache.org/jaxws
          http://cxf.apache.org/schemas/jaxws.xsd">
       <!-- 引入CXF Bean定义如下,早期的版本中使用 -->
       <import resource="classpath:META-INF/cxf/cxf.xml" />
       <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
       <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
       <!-- 简单发布,没有接口 -->
       <jaxws:endpoint id="helloService" address="/hello" implementor="com.zhang.server1.HelloImpl">
           <!--客户端请求的消息拦截器-->
           <jaxws:inInterceptors>
               <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
           </jaxws:inInterceptors>
           <!--服务端响应的消息拦截器-->
           <jaxws:outInterceptors>
               <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
           </jaxws:outInterceptors>
    
       </jaxws:endpoint>
    

    生成客户端代码遇到的问题

    元素类型 * 必须后跟属性规范 ">" 或 "/>"

    控制台报错,是xsd文件中有错,通过百度得知问题可能是缺少空格,但在xsd文件中没有找到有该问题的地方。进而查看wsdl文件,确实存在此类问题。

    查看是否存在

    #在editPlus中,开启正则表达式,搜索如下字符串
    "S*=
    

    查到匹配的内容则有问题。

    我的有问题的都是如下的内容(前后字符省略了)

    "type="
    

    全局替换"type="" type=",问题解决

    undefined simple or complex type 'ns1:string'

    这个问题,在wsdl中添加

    <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>
    

    由于公司内网,该网址访问不了,所以直接用浏览器打开网址,保存内容到encode_schemas.xml,改上边引入为

    <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="encode_schemas.xml"/>
    

    XmlElementRef中没有required属性

    生成的java文件导入idea,报XmlElementRef中没有required属性

    此问题更改生成命令即可

    wsdl2java -verbose -frontend jaxws21 -client Service.wsdl
    

    去除JAXBElement引起的混乱代码

    如下博客解决JAXBElement引起的混乱代码
    https://blog.csdn.net/bob007abc/article/details/8599685

  • 相关阅读:
    Keepass无法导入密钥文件
    数据库交互方式之一
    Grey encoder and decoder
    SystemVerilog 序列运算符与属性运算符
    避免int 与 pointer的隐式类型转换
    xxx.lib(xxx.obj)fatal error LNK1103: debugging information corrupt; recompile module 的解决方案
    c++ static 关键字用法
    影响中国软件开发的人(摘录)
    链接
    有助于事业发展和幸福感提升的四个约定
  • 原文地址:https://www.cnblogs.com/so-easy/p/11701284.html
Copyright © 2011-2022 走看看