Webservice

1、什么是webservice
先来考虑一个问题,如果我们要在自己的程序里面展示天气预报,那怎么弄?正确的做法是我们发送一个请求到一个系统,他会给我们返回来天气情况。这个就是一个webservice。天气预报系统就相当于webservice的服务端,我们的系统就相当于客户端。如http://www.webxml.com.cn这个网站上面就列举了多个webservice服务站点

2、JAVA中如何调用别人发布的webservice
2.1、获取webservice的wsdl文档
2.11、什么是wsdl文档
wsdl跟java一样,也是一种语言,是通过xml的形式说明该webservice如何调用。

2.12、如何获取wsdl文档
通过在webservice的url后面加?wsdl的方式,比如天气预报的的就是http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl

2.13、WSDL解析
Wsdl文档从下往上读
Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。(入参和出参的数据类型)
Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构(入参和出参)。
Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对(方法)。
PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持(服务类)。
Binding - 特定服务访问点与具体服务类的绑定(不看内容,看关系)。
Port - 定义为webservice单个服务访问点。
Service- 相关服务访问点的集合。

2.2、通过wsdl文档生成客户端调用代码
2.21、使用jdk自带的命令生成
配置java环境变量后在命令窗口中输入wsimport –s . http://xxxx.xx.xx/xxx?wsdl即可生成java代码
注意:-s不能分开,-s后面有个小点,用于指定源代码生成的目录。点即当前目录。如果使用了-s参数则会在目录下生成两份代码,一份为.class代码。一份为.java代码。.class代码,可以经过打包以后使用。.java代码可以直接Copy到我们的项目中运行
注意:可能会报错解析组件 ‘s:schema’ 时出错。在该组件中检测到 's:schem’之类的,如果报错这个请移步:这里

2.3、生成代码后如何调用
先把生成的代码复制到项目中,然后通过读wsdl文档来调用,整体的调用代码类似于下面这样

//wsdl文档中service的name
SayHelloIntefaceService ss = new SayHelloIntefaceService();
//wsdl文档中portType的name
SayHelloInteface shf=ss.getSayHelloIntefacePort();
//wdl文档中complexType的name
String str=shf.sayhellow("lisi");
//str即为webservice的服务端返回的信息
System.out.println(str);

3、一个关于WebService的Demo
3.1、服务端
package com.bxoon;

import javax.jws.WebMethod;


public interface WebServiceI {

    @WebMethod(exclude=true)
    String helloWord(String name);

    @WebMethod(exclude=true)
    String helloWord2(String name);


package com.bxoon;


import javax.jws.WebService;
import javax.xml.ws.Endpoint;


@WebService
public class HelloWebService implements WebServiceI {


    @Override
    public String helloWord(String name) {
        return"Hello: "+name;
    }

    @Override
    public String helloWord2(String name){
        return"Hello: "+name;
    }

    public static void main(String[] args) {
        Endpoint.publish("http://127.0.0.1:8080/helloWord",new HelloWebService());
    }

}


3.2 客户端
服务端启动之后通过访问http://127.0.0.1:8080/helloWord?wsdl来得到一个wsdl文档,类似于如下

然后通过命令

wsimport -s . http://127.0.0.1:8080/helloWord?wsdl

来生成具体的代码,生成的代码类似于

我们把对应的java类copy到客户端项目中,得到这样的目录结构

然后我们编写图中的Client类,代码如下

package com.bxoon;

public class Client {

    public static void main(String[] args) {
        HelloWebServiceService service = new HelloWebServiceService();
        HelloWebService webService = service.getHelloWebServicePort();
        String result = webService.helloWord("11");
        System.out.println(result);
    }
}
运行之后输出结果

Hello: 11
到此,一个简单的WebService的helloword程序就完成了,下面对具体的代码进行解释。

用Jdk1.6.0_21以后的版本发布一个WebService服务.与Web服务相关的类,都位于javax.xml.ws.*包中。
主要类有:
a) @WebService - 它是一个注解,用在类上指定将此类发布成一个webservice服务.
b) Endpoint – 此类为端点服务类,它的方法publish用于将一个已经添加了@WebService注解对象绑定到一个地址的端口上。Endpoint是jdk提供的一个专门用于发布服务的类,它的publish方法接收两个参数,一个是本地的服务地址,二是提供服务的类。它位于javax.xml.ws.*包中。
static Endpoint.publish(String address, Object implementor) 在给定地址处针对指定的实现者对象创建并发布端点。stop方法用于停止服务。

其他注意事项:

给类添加上@WebService注解后,类中所有的非静态方法都将会对外公布。不支持静态方法,final方法。
如果希望某个方法(非static,非final)不对外公开,可以在方法上添加@WebMethod(exclude=true),阻止对外公开。
如果一个类上,被添加了@WebService注解,则必须此类至少有一个可以公开的方法,否则将会启动失败。
服务类中不能没有方法
@WebMethod(exclude=true)屏蔽方法
4、其他调用webservice的方式
这里只写了一种最基本的调用webService的方式,实际上调用webService有很多种方式,下面一一介绍。

4.11、 使用ajax调用
var xhr;
function invoke(){
    if(window.ActiveXObject){
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        xhr = new XMLHttpRequest();
    }
    //指定请求地址
    var url = "http://127.0.0.1:7777/hello?wsdl";
    //定义请求类型和地址和异步
    xhr.open("POST", url, true);
    //设置Content-Type
    xhr.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");
    //指定回调方法
    xhr.onreadystatechange = back;
    
    var textVal = document.getElementById("mytext").value;
    //组装消息体的数据
    var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.hm.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
    +'<soapenv:Body>'
    +'<q0:sayHello>'
    +'<arg0>'+textVal+'</arg0>'
    +'</q0:sayHello>'
    +'</soapenv:Body>'
    +'</soapenv:Envelope>';
    xhr.send(data);
 
}
function back(){
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            var doc = xhr.responseXML;
            alert(doc);
            alert(xhr.responseText);
            var tag = doc.getElementsByTagName("return")[0];
            alert(tag)
            
        }
    }
}

4.12、通过URLConnection调用
//创建url地址
URL url = new URL("http://192.168.1.104:8080/hello");
//打开连接
URLConnection conn = url.openConnection();
//转换成HttpURL
HttpURLConnection httpConn = (HttpURLConnection) conn;
//打开输入输出的开关
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
//设置请求方式
httpConn.setRequestMethod("POST");
//设置请求的头信息
httpConn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");
//拼接请求消息
String data = "<soapenv:Envelope xmlns:soapenv=" +
        "\"http://schemas.xmlsoap.org/soap/envelope/\" " +
        "xmlns:q0=\"http://server.rl.com/\" " +
        "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
        +"<soapenv:Body>"
        +"<q0:sayHello>"
        +"<arg0>renliang</arg0> "
      +"</q0:sayHello>"
      +"</soapenv:Body>"
      +"</soapenv:Envelope>";
//获得输出流
OutputStream out = httpConn.getOutputStream();
//发送数据
out.write(data.getBytes());
//判断请求成功
if(httpConn.getResponseCode() == 200){
    //获得输入流
    InputStream in = httpConn.getInputStream();
    //使用输入流的缓冲区
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuffer sb = new StringBuffer();
    String line = null;
    //读取输入流
    while((line = reader.readLine()) != null){
        sb.append(line);
    }
    //创建sax的读取器
    SAXReader saxReader = new SAXReader();
    //创建文档对象
    Document doc = saxReader.read(new StringReader(sb.toString()));
    //获得请求响应return元素
    List<Element> eles = doc.selectNodes("//return");
    for(Element ele : eles){
        System.out.println(ele.getText());
    }
}
4.13、使用jquery调用cxf
$(function(){
        $("#mybutton").click(function(){
            var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.web.cxf.rl.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
                  +'<soapenv:Body>'
                  +'<q0:sayHello>'
                  +'   <arg0>sss</arg0>'
                  +' </q0:sayHello>'
                  +'</soapenv:Body>'
                  +'</soapenv:Envelope>';
                  
                $.ajax({
                    url:'http://localhost:8080/cxf-web-server/services/hello',
                    type:'post',
                    dataType:'xml',
                    contentType:'text/xml;charset=UTF-8',
                    data:data,
                    success:function(responseText){
                        alert($(responseText).find('return').text());
                    },
                    error:function(){
                        alert("error");
                    }
                })
        })
    })

5、wsdl文档元素名称修改
有时,自动生成的WSDL文档的名字可能不规范,我们是可以自定义的。在注解@webservice中可以指定一些属性来完成这个功能。

@WebService(
    portName="myHelloService",修改端口名字
    serviceName="HelloServices",修改服务访问点集合名字
    name="HelloService",修改服务类的名字
    targetNamespace="hello.rl.com" 修改命名空间名字
)

或者使用如下方式

@WebResult(name="sirHello")修改返回值的元素的父标签名字
@WebParam(name="sir")修改传入参数的元素的父标签名字

6、其他发布WebService的方式
其实上面说的使用jdk自带的方式发布WebService只是众多发布WebService的方式中的一种。现阶段发布方式主要有以下5种

CXF(常用)
Xfire(比较古老)
Axis2 (常用)
Axis1
HttpClient
jws的发布对java webservice框架产生了巨大的影响,经过大浪淘沙,目前java开发webservice的框架主要包括axis2和cxf。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值