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

WebService入门

发布时间:2020-12-16 21:46:12 所属栏目:安全 来源:网络整理
导读:转载:http://blog.csdn.net/opopopwqwqwq/article/details/51758862 Webservice : 跨语言跨平台的远程调用技术 WebService定义 : 顾名思义就是基于Web的服务。它使用Web(HTTP)方式,接收和响应外部系统的某种请求。从而实现远程调用。 ? Webservice理解 :

转载:http://blog.csdn.net/opopopwqwqwq/article/details/51758862

Webservice:跨语言跨平台的远程调用技术

WebService定义: 顾名思义就是基于Web的服务。它使用Web(HTTP)方式,接收和响应外部系统的某种请求。从而实现远程调用。

?

Webservice理解:我们可以调用互联网上查询天气信息Web服务,然后将它嵌入到我们的程序(C/S或B/S程序)当中来,当用户从我们的网点看到天气信息时,他会认为我们为他提供了很多的信息服务,但其实我们什么也没有做,只是简单了调用了一下服务器上的一段代码而已。WebSerice可以将你的服务(一段代码)发布到互联网上让别人去调用,也可以调用别人机器上发布的WebService,就像使用自己的代码一样.。

?

1?????远程调用的案例(模拟远程调用天气预报服务)

便民查询网站的分析

?

天气信息必须通过远程调用的方式获得。

远程调用的方法

1.1.1???????Socket实现远程调用

?

1.1.1.1????实现步骤:

服务端:

第一步:创建一个Java工程

第二步:使用ServerSocket创建一个服务。需要指定服务的端口号。

第三步:调用accept()方法等待客户端建立连接。

第四步:建立连接后使用输入流读取客户端发送的城市名称

第五步:查询天气信息。模拟。

第六步:使用输出流返回天气信息。

第七步:关闭输入输出流。服务端不关闭连接,等待客户端关闭。

客户端

第一步:创建一个java工程

第二步:使用Socket类和服务端建立连接。需要指定ip和端口。

第三步:使用输出流发送城市名称

第四步:使用输入流读取服务端返回的结果

第五步:打印结果。

1.1.1.2??? 代码实现

开发环境:要求jdk1.7以上

开发工具:eclipse indigo

服务端

[java]? view plain ?copy
  1. public?class?WeatherServer?{??
  2. ??
  3. ????static?void?main(String[]?args)?{??
  4. ??????????
  5. ????????try?{??
  6. ????????????//?创建一个Socket服务??
  7. ????????????//?参数:服务的端口号,建议大一些0-1024是系统留用端口??
  8. ????????????ServerSocket?serverSocket?=?new?ServerSocket(12345);??
  9. ????????????System.out.println("服务端已启动。。。。。");??
  10. ????????????while(true)?{??
  11. ????????????????//?等待客户端建立连接??
  12. ????????????????//?阻塞的方法,建立连接后向下执行??
  13. ????????????????final?Socket?socket?=?serverSocket.accept();??
  14. ????????????????Runnable?runnable?=?new?Runnable()?{??
  15. ??????????????????????
  16. ????????????????????@Override??
  17. ????????????????????void?run()?{??
  18. ????????????????????????DataInputStream?inputStream?=?null;??
  19. ????????????????????????DataOutputStream?outputStream?=?null;??
  20. ????????????????????????try?{??
  21. ????????????????????????//?使用输入流读取客户端发送的数据??
  22. ????????????????????????inputStream?=?new?DataInputStream(socket.getInputStream());??
  23. ????????????????????????String?cityName?=?inputStream.readUTF();??
  24. ????????????????????????System.out.println("接收到客户端发送的数据:"?+?cityName);??
  25. //?根据城市查询天气??
  26. ????????????????????????System.out.println("查询天气。。。。");??
  27. ????????????????????????Thread.sleep(1000);??
  28. ????????????????????????String?resultString?=?"阴天转雷阵雨";??
  29. ????????????????????????outputStream?=?new?DataOutputStream(socket.getOutputStream());??
  30. ????????????????????????//?返回查询结果??
  31. ????????????????????????System.out.println("返回查询结果:"?+?resultString);??
  32. ????????????????????????outputStream.writeUTF(resultString);??
  33. ????????????????????????}?catch?(Exception?e)?{??
  34. ????????????????????????????//?TODO:?handle?exception??
  35. ????????????????????????}finally?{??
  36. //?关闭流??
  37. ???????????????????????????? ????????????????????????????????inputStream.close();??
  38. ????????????????????????????????outputStream.close();??
  39. ????????????????????????????}?catch?(IOException?e)?{??
  40. ????????????????????????????????//?TODO?Auto-generated?catch?block??
  41. ????????????????????????????????e.printStackTrace();??
  42. ????????????????????????????}??
  43. ????????????????????????}??
  44. ??????????????????????????
  45. ????????????????????}??
  46. ????????????????};??
  47. //启动线程??
  48. new?Thread(runnable).start();??
  49. ????????????}??
  50. ????????}? ????????}???
  51. ????}??
  52. }??


客户端

copy

    class?WeatherClient?{??
  1. void?main(String[]?args)?throws?Exception?{??
  2. ????????while?(//?创建一个socket连接??
  3. ????????????Socket?socket?=?new?Socket("127.0.0.1",?//?使用输出流发送城市名称??
  4. ????????????DataOutputStream?outputStream?=?new?DataOutputStream(??
  5. ????????????????????socket.getOutputStream());??
  6. //?发送城市名称??
  7. ????????????outputStream.writeUTF("北京");??
  8. //?接收返回的结果??
  9. ????????????DataInputStream?inputStream?=?new?DataInputStream(??
  10. ????????????????????socket.getInputStream());??
  11. ????????????String?resultString?=?inputStream.readUTF();??
  12. ????????????System.out.println("天气信息:"?+?resultString);??
  13. //?关闭流??
  14. ????????????inputStream.close();??
  15. ????????????outputStream.close();??
  16. ????????}??
  17. }??

Socket要求服务端有持续服务能力,而且要实现多线程。编码比较麻烦。

?

1.1.2?????? Webservice实现远程调用

1.1.2.1????实现步骤

服务端

1.??? 编写SEI(ServiceEndpoint Interface),SEI在WSDL中称为portType,在java中称为接口。

2.??? 编写sei实现类,需要实现SEI接口,而且还要求在实现类上添加一个@Webservice注解。

3.??? 发布服务。使用Endpoint的静态方法publish。

1.1.2.2????代码实现

Sei

copy

    interface?WeatherInterface?{??
  1. ????String?queryWeather(String?cityName);??

  2. SEI实现类

    ?

    [cpp]? copy
      //指定服务的url,可以是wsdl的地址也可以是服务的地址??
    1. ????????URL?url?=?null;??
    2. ????????????url?=?new?URL("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL");??
    3. catch?(MalformedURLException?e)?{??
    4. //?TODO?Auto-generated?catch?block??
    5. ????????????e.printStackTrace();??
    6. //第一个参数是wsdl的命名空间??
    7. //第二个参数是service节点的name属性??
    8. ????????QName?qName?=?new?QName("http://WebXml.com.cn/",?"WeatherWebService");??
    9. ????????Service?service?=?Service.create(url,?qName);??
    10. //从服务视图获得portType对象??
    11. //WeatherWebServiceSoap?portType?=?service.getWeatherWebServiceSoap();??
    12. ????????WeatherWebServiceSoap?portType?=?service.getPort(WeatherWebServiceSoap.class);??
    13. 4???? Soap

      soap是什么

      SOAP 是一种网络通信协议

      SOAP即Simple Object Access Protocol简易对象访问协议

      SOAP 用于跨平台应用程序之间的通信

      SOAP 被设计用来通过因特网(http)进行通信

      SOAP = HTTP+XML,其实就是通过HTTP发xml数据

      SOAP 很简单并可扩展支持面向对象

      SOAP 允许您跨越防火墙

      SOAP 将被作为 W3C 标准来发展

      使用TCP/IP Monitor监视Soap协议

      TCP/IPMonitor是eclipse自带的工具。

      是一个代理方式的查看协议体内容的工具。

      ?

      Soap1.1

      Webservice默认使用的是1.1版本的soap协议。

      4.1.1?????? 请求的协议体

      头信息

      [sql]? copy
        Accept:?application/soap+xml,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> Content-Type:?application/soap+xml;?charset=utf-8;??
      1. action="http://jaxws.itheima.com/WeatherInterfaceImpl/queryWeatherRequest"??
      2. User-Agent:?JAX-WS?RI?2.2.4-b01??
      3. Connection:?keep-alive??
      4. Content-Length:?208??
      5. <?xml?version="1.0"??>??
      6. <S:Envelope?xmlns:S="http://www.w3.org/2003/05/soap-envelope">??
      7. ????????<ns2:queryWeather?xmlns:ns2="http://jaxws.itheima.com/">??
      8. 4.1.4?????? 响应的协议体

        copy

          Content-type:?application/soap+xml;?charset=utf-8??
        1. <?xml?version='1.0'?encoding='UTF-8'?>??
        2. <S:Envelope?xmlns:S="http://www.w3.org/2003/05/soap-envelope">??
        3. Soap1.1和soap1.2的区别

          Content-type:

          Soap1.1:Content-type: text/xml; charset=utf-8

          Soap1.2:Content-type: application/soap+xml; charset=utf-8

          Envelope标签的命名空间:

          Soap1.1:<S:Envelopexmlns:S="http://schemas.xmlsoap.org/soap/envelope/">

          Soap1.2:<S:Envelopexmlns:S="http://www.w3.org/2003/05/soap-envelope">

          模拟httpclient调用webservice

          4.1.5?????? 实现步骤

          第一步:创建一java工程

          第二步:创建一个HttpURLConnection对象。可以使用URL对象的openConnection方法获得。

          第三步:设置content-type,根据服务端使用的版本,设置不同的content-type。

          第四步:编辑一个请求的xml格式的协议体发送给服务端。

          第五步:接收服务端响应的内容。打印出来

          4.1.6?????? 代码的实现

          使用http的方式调用服务端方法

          copy

            class?SoapHttpClient?{??
          1. ????????URL?url?=?new?URL("http://127.0.0.1:54321/weather");??
          2. //创建一个HttpURLConnection对象??
          3. ????????HttpURLConnection?connection?=?(HttpURLConnection)?url.openConnection();??
          4. //设置content-type??
          5. //服务端是soap1.2的协议??
          6. ????????connection.setRequestProperty("Content-Type",?"?application/soap+xml;?charset=utf-8;");??
          7. //设置使用connection对象进行输入输出??
          8. ????????connection.setDoInput(true);??
          9. ????????connection.setDoOutput(true);??
          10. //使用输出流向服务端发送xml数据??
          11. ????????connection.getOutputStream().write(getRequestBody("北京").getBytes());??
          12. //接收服务端响应的内容??
          13. ????????InputStream?inputStream?=?connection.getInputStream();??
          14. byte[]?b?=?new?byte[1024];??
          15. int?len?=?0;??
          16. ????????ByteArrayOutputStream?data?=?new?ByteArrayOutputStream();??
          17. while((len?=?inputStream.read(b,0); background-color:inherit">0,0); background-color:inherit">1024))?!=?-1)?{??
          18. ????????????data.write(b,? ??????????
          19. ????????System.out.println(data);??
          20. ????//拼装请求协议体??
          21. ????private?static?String?getRequestBody(String?cityName)?{??
          22. ????????String?body?=?"<?xml?version="1.0"??>n"?+??
          23. ????????????????"<S:Envelope?xmlns:S="http://www.w3.org/2003/05/soap-envelope">n"?+??
          24. ????????????????"???<S:Body>n"?+??
          25. ????????????????"???????<ns2:queryWeather?xmlns:ns2="http://jaxws.itheima.com/">n"?+??
          26. ????????????????"???????????<arg0>"+cityName+"</arg0>n"?+??
          27. ????????????????"???????</ns2:queryWeather>n"?+??
          28. ????????????????"???</S:Body>n"?+??
          29. ????????????????"</S:Envelope>";??
          30. return?body;??
          31. ??????
          32. 拼装xml字符串小技巧


            5???? 案例:区域查询系统

            5.1区域查询系统的结构

            6.2需求

            创建区域查询服务系统,对外发布WebService服务,供客户端调用,根据parentid查询区域信息。客户端向服务端传递xml格式数据,服务端向客户端响应xml格式数据。

            6.3分析

            基于soap协议的webservice就可以传递对象。

            5.1.1?????? 传递xml数据的原因:

            1、跨语言时可能会花很长时间来调试,如果直接传递xml省去的调试的时间。参数和返回值都是字符串类型,非常简单。

            2、如果参数发生变化后,可以不用修改接口,不用重新生成客户端调用代码。

            3、Xml格式的数据是跨语音跨平台的。

            5.1.2?????? 架构分析

            ?

            ??

            5.1.3?????? 实现步骤:

            服务端:

            第二步:导入jar包需要MySQL的数据库驱动,dom4j的jar包。

            第三步:创建一个SEI。

            第四步:创建SEI实现类。调用dao查询区域列表。

            1、接收客户端发送的xml

            2、需要解析xml数据转换成java对象

            3、查询数据库得到区域列表,使用jdbc查询。

            4、把区域列表转换成xml数据

            5、返回xml数据

            第五步:发布服务,使用Endpoint的publish方法发布服务。

            客户端:

            1、生成客户端调用代码

            2、创建服务视图

            3、从服务视图获得porttype

            4、调用服务端方法。

            5.1.4?????? 接口描述:

            客户端发送数据格式:

            copy

              <?xml?version="1.1"??encoding="utf-8"?>??
            1. <queryarea>??
            2. <parentid>?</parentid>//父级区域id??
            3. <start></start>//起始记录,从1开始??
            4. <end></end>//结束记录??
            5. </queryarea>??

            服务端响应数据格式:

            copy

              <?xml?version="1.0"?encoding="UTF-8"?>??
            1. <areas>??
            2. <area>??
            3. <areaid>?</areaid>//区域id??
            4. <areaname></areaname>//区域名称??
            5. <arealevel></arealevel>//区域等级??
            6. <parentid></parentid>//父级区域id??
            7. </area>??
            8. //…..??
            9. </areas>??

            5.1.5?????? 代码实现

            5.1.5.1??? Dao

            copy

              class?AreaDao?{??
            1. public?List<AreaModel>?queryArea(String?parentid,153); background-color:inherit; font-weight:bold">int?start,153); background-color:inherit; font-weight:bold">int?end)?{??
            2. ????????Connection?connection?=? ????????PreparedStatement?preparedStatement?=? ????????ResultSet?resultSet?=? ????????List<AreaModel>?areaList?=?new?ArrayList<>();??
            3. //加载数据库驱动??
            4. ????????????Class.forName("com.mysql.jdbc.Driver");??
            5. //获得connection??
            6. ????????????connection?=?DriverManager.getConnection("jdbc:mysql:///webservice",?"root",?"root");??
            7. //获得preparedStatement??
            8. ????????????String?sql?=?"select?*?from?area?where?parentid?=???limit??,?";??
            9. ????????????preparedStatement?=?connection.prepareStatement(sql);??
            10. //设置参数??
            11. ????????????preparedStatement.setString(1,?parentid);??
            12. ????????????preparedStatement.setInt(2,?start?-?1);??
            13. ????????????preparedStatement.setInt(3,?end?-?start?+?1);??
            14. //执行查询??
            15. ????????????resultSet?=?preparedStatement.executeQuery();??
            16. ??????????????
            17. //取区域列表??
            18. while(resultSet.next())?{??
            19. ????????????????AreaModel?model?=?new?AreaModel();??
            20. ????????????????model.setAreaid(resultSet.getString("areaid"));??
            21. ????????????????model.setAreaname(resultSet.getString("areaname"));??
            22. ????????????????model.setArealevel(resultSet.getString("arealevel"));??
            23. ????????????????model.setParentid(resultSet.getString("parentid"));??
            24. //添加到区域列表??
            25. ????????????????areaList.add(model);??
            26. ????????????e.printStackTrace();??
            27. ????????????????resultSet.close();??
            28. ????????????}?catch?(SQLException?e)?{??
            29. ????????????????e.printStackTrace();??
            30. ????????????}??
            31. ????????????????preparedStatement.close();??
            32. ????????????????connection.close();??
            33. return?areaList;??
            34. 5.1.5.2??? Service

              copy

                class?AreaInterfaceImpl?implements?AreaInterface?{??
              1. public?String?queryArea(String?area)?{??
              2. //解析xml查询条件??
              3. ????????AreaModel?model?=? ????????String?result?=? ????????????model?=?parseXml(area);??
              4. ????????????AreaDao?dao?=?new?AreaDao();??
              5. ????????????List<AreaModel>?list?=?dao.queryArea(model.getParentid(),?model.getStart(),?model.getEnd());??
              6. ????????????result?=?list2xml(list);??
              7. ????????}?catch?(Exception?e)?{??
              8. ????/*?
              9. ????<?xml?version="1.1"??encoding="utf-8"?>?
              10. ????<queryarea>?
              11. ????<parentid>?</parentid>//父级区域id?
              12. ????<start></start>//起始记录,从1开始?
              13. ????<end></end>//结束记录?
              14. ????</queryarea>?
              15. ?????
              16. ????*/??
              17. private?AreaModel?parseXml(String?xml)? ????????Document?document?=?DocumentHelper.parseText(xml);??
              18. ????????String?parentid?=?document.selectSingleNode("/queryarea/parentid").getText();??
              19. ????????String?start??=?document.selectSingleNode("/queryarea/start").getText();??
              20. ????????String?end??=?document.selectSingleNode("/queryarea/end").getText();??
              21. ????????model.setParentid(parentid);??
              22. ????????model.setStart(Integer.parseInt(start));??
              23. ????????model.setEnd(Integer.parseInt(end));??
              24. return?model;??
              25. /**?
              26. ??????
              27. ????<?xml?version="1.0"?encoding="UTF-8"?>?
              28. ????<areas>?
              29. ????<area>?
              30. ????<areaid>?</areaid>//区域id?
              31. ????<areaname></areaname>//区域名称?
              32. ????<arealevel></arealevel>//区域等级?
              33. ????<parentid></parentid>//父级区域id?
              34. ????</area>?
              35. ????//…..?
              36. ????</areas>?
              37. ?????*/??
              38. private?String?list2xml(List<AreaModel>?list)? ????????Document?document?=?DocumentHelper.createDocument();??
              39. //添加以根节点??
              40. ????????Element?root?=?document.addElement("areas");??
              41. for?(AreaModel?areaModel?:?list)?{??
              42. ????????????Element?area?=?root.addElement("area");??
              43. ????????????area.addElement("areaid").setText(areaModel.getAreaid());??
              44. ????????????area.addElement("areaname").setText(areaModel.getAreaname());??
              45. ????????????area.addElement("arealevel").setText(areaModel.getArealevel());??
              46. ????????????area.addElement("parentid").setText(areaModel.getParentid());??
              47. return?document.asXML();??
              48. 5.1.5.3??? 发布服务

                copy

                  class?AreaServer?{??
                1. ????????Endpoint.publish("http://127.0.0.1:12345/area",153); background-color:inherit; font-weight:bold">new?AreaInterfaceImpl());??
                2. }??

                5.1.5.5??? 生成客户端调用代码

                5.1.5.6??? 客户端

                copy
                1. class?AreaClient?{??
                2. ????????AreaInterfaceImplService?service?=?new?AreaInterfaceImplService();??
                3. //获得porttype??
                4. ????????AreaInterfaceImpl?portType?=?service.getAreaInterfaceImplPort();??
                5. //调用服务端方法??
                6. ????????String?result?=?portType.queryArea(getQueryXml("1.2.",0); background-color:inherit">10));??
                7. ????????System.out.println(result);??
                8. ??????
                9. static?String?getQueryXml(String?parentid,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> ????????String?xml?=?"<?xml?version="1.1"??encoding="utf-8"?>n"?+??
                10. ????????????????"<queryarea>n"?+??
                11. ????????????????"<parentid>"+parentid+"</parentid>n"?+??
                12. ????????????????"<start>"+start+"</start>n"?+??
                13. ????????????????"<end>"+end+"</end>n"?+??
                14. ????????????????"</queryarea>";??
                15. return?xml;??
                16. } ?

                (编辑:李大同)

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

    推荐文章
      热点阅读