首页 > 代码库 > 初探webService

初探webService

webService提供了一种规范,可以用于不同语言或者不同平台之间数据传输。

 

复习socket通信以便更好的理解ws。

socket通信图示:

技术分享

平台a与平台b无法进行直接通信,通过socket进行通信。

 

socket通信举例(回复相同的字符串):

客户端

package com.bxw.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketClient {
    private Socket socket;
    private OutputStream os;//输出流,获取用户输入的信息
    private InputStream is;//输入流,接受来自服务器的数据
    
    public SocketClient() {
    }
    /**
     * 构造方法
     * @param url
     * @param port
     */
    public SocketClient(String url,int port) {
        try {
            socket = new Socket(url, port);
            is = socket.getInputStream();
            os = socket.getOutputStream();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public Socket getSocket() {
        return socket;
    }
    public void setSocket(Socket socket) {
        this.socket = socket;
    }
    public OutputStream getOs() {
        return os;
    }
    public void setOs(OutputStream os) {
        this.os = os;
    }
    public InputStream getIs() {
        return is;
    }
    public void setIs(InputStream is) {
        this.is = is;
    }
    public void close(){
        try {
            os.close();
            is.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        SocketClient sc = new SocketClient("127.0.0.1", 9999);//创建客户端
        Scanner scan = new Scanner(System.in);//控制台接受用户输入
        OutputStream os = sc.getOs();//获得输出流,到服务端
        InputStream is = sc.getIs();//获得输入流,用户输入
        String data="";
        while(!data.equals("bye")){
            System.out.println("------请输入要转化的字母------");
            data = scan.next();//获取控制台输入
            //写入到输出流
            try {
                os.write(data.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        sc.close();
    }
}

服务端

package com.bxw.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {
    private ServerSocket ss;
    private OutputStream os;//输出流,输出到客户端处理过后的信息
    private InputStream is;//输入流,接受客户端的信息
    
    public SocketServer() {
    }
    
    public SocketServer(int port){
        try {
            ss = new ServerSocket(port);
            System.out.println("--------空闲中,等待请求--------");
            Socket socket = ss.accept();
            System.out.println("--------握手成功--------");
            while(true){
                is = socket.getInputStream();
                os = socket.getOutputStream();
                byte[] b = new byte[1024];
                int len = is.read(b);
                String data = new String(b, 0, len);
                System.out.println("客户端发来的数据为:"+data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public ServerSocket getSs() {
        return ss;
    }

    public void setSs(ServerSocket ss) {
        this.ss = ss;
    }

    public OutputStream getOs() {
        return os;
    }

    public void setOs(OutputStream os) {
        this.os = os;
    }

    public InputStream getIs() {
        return is;
    }

    public void setIs(InputStream is) {
        this.is = is;
    }
    public void close(){
        try {
            is.close();
            os.close();
            ss.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

        public static void main(String[] args) {
        new SocketServer(9999);
    }    
}
    

先开启服务端的程序,然后等待,一旦客户端向服务端发送消息,握手成功则该socket通信成功。

 

由于我们的项目大多是web项目,于是通过浏览器发起请求的方式访问socket服务。

服务端不变。

客户端采用jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>sockie客户端</title>
</head>
<body>
    <form name="form" action="http://localhost:9999" method="post">
        <input type="text" name="vname">
        <input type="submit" value="提交"> 
    </form>
</body>
</html>

运行结果:

技术分享

显然这么一大串是不要的,我们只需要的是sname的信息。

以下记录如何调用已经封装好的ws。

 http://www.webxml.com.cn,该站点提供了很多ws服务,请求ws服务的方式大致有以下几种(get,post,soap)

package com.bxw.client;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;


public class TranslateClient {
    /**
     * get请求
     * @param number
     * @throws HttpException
     * @throws IOException
     */
    private void get(String number) throws HttpException, IOException {
        HttpClient hc = new HttpClient();//创建一个浏览器对象
        //填写数据,指定发送get请求
        GetMethod gm = new GetMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx"
                + "/getMobileCodeInfo?mobileCode=" + number + "&userID=");
        gm.setRequestHeader("Content-Type", "text/xml; charset=utf-8");//指定传输格式
        int code = hc.executeMethod(gm);//发送请求
        System.out.println("该请求的状态码"+code);
        String result = gm.getResponseBodyAsString();
        System.out.println("返回的结果:"+result);
    }
    
    /**
     * post请求
     * @param number
     * @throws IOException 
     * @throws HttpException 
     */
    private void post(String number) throws HttpException, IOException {
        //HttpClient模拟http请求
        HttpClient hc = new HttpClient();//浏览器对象
        //post请求
        PostMethod pm = new PostMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo");
        //指定post传输格式
        pm.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        //传输参数
        pm.setParameter("mobileCode", number);
        pm.setParameter("userId", "");
        //发送请求
        int code = hc.executeMethod(pm);
        System.out.println("状态码"+code);
        String result = pm.getResponseBodyAsString();
        System.out.println("结果"+result);
    }
    
    /**
     * soap方式(有1.1和1.2两个版本,jdk1.7以上才可以使用soap1.2)
     * @param number
     * @throws IOException 
     * @throws HttpException 
     */
    private void soap(String number) throws HttpException, IOException {
        HttpClient hc = new HttpClient();//浏览器对象
        PostMethod pm = new PostMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");//post提交
        //指定传输格式为xml格式
        pm.setRequestHeader("Content-Type", "application/soap+xml;charset=utf-8");
        //传输xml
        pm.setRequestBody(new FileInputStream("C:/Users/Admin/Desktop/service.xml"));
        //发送post请求
        int code = hc.executeMethod(pm);
        System.out.println("状态码"+code);
        String result = pm.getResponseBodyAsString();
        System.out.println("结果"+result);
    }
    public static void main(String[] args) {
        TranslateClient tl = new TranslateClient();
        try {
            //tl.get("18819465153");
            //tl.post("18819465153");
            tl.soap("18819465153");
        } catch (HttpException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

输入xml。

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <getMobileCodeInfo xmlns="http://WebXml.com.cn/">
      <mobileCode>18312345678</mobileCode>
      <userID></userID>
    </getMobileCodeInfo>
  </soap12:Body>
</soap12:Envelope>

还有一种利用命令行生成接口的方式:

使用wsimport:

每个ws都会有一个WSDL,WSDL即WebService Description Language – Web服务描述语言。它是通过XML形式说明服务在什么地方-地址。通过XML形式说明服务提供什么样的方法 – 如何调用。

目前只需要复制一下那个url即可,然后打开命令提示符窗口,随便进入一个目录下(该目录要保存等会生成的和ws相关的文件,自己事先建一个即可),运行 
wsimport http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL 
  就会生成相应的javabean,当然了,是.class文件,但是我们不想要class文件,我们想要java文件,所以可以使用如下命令: 
wsimport -s http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL 
  这样不仅生成了class文件,还生成了java文件,如果我们想要在固定的包下生成这些文件,等会方便直接拷贝到项目里,可以使用下面的命令: 
wsimport -s . -p ws.client.c http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL 
  这样就会在目录ws/client/c/下生成所需要的class和java代码,然后我们删掉class文件,直接拷贝ws目录到工程中即可。

初探webService