- 浏览: 8595 次
- 性别:
- 来自: 成都
最新评论
一、写这篇记录的原因:
最近看了一些关于关于socket模拟文件服务器的文章或者视频,客户端通过浏览器访问,服务端通过socket去实现,学习之下了解到就是向socket发送制定格式的内容【http协议】,然后服务端进行解析,返回相关的数据,于是就想肯定要可以使用socket模拟调用webservice【webservice就是http协议+soap报文通过tcp协议来传输】,当然了使用httpclient去模拟发送get/post请求最方便,不过也是自己对http协议深入理解【原来的理解就知道http协议是什么样的,但是具体发送的啥内容也模糊】
二、直接贴代码:
1.调用部分
2.Response对象定义
3.核心处理部分[调用+解析]
三、测试结果:
OK 200 HTTP/1.1
Server-->Microsoft-IIS/6.0
Cache-Control-->private, max-age=0
X-AspNet-Version-->2.0.50727
Content-Length-->838
Date-->Tue, 12 Dec 2017 15
X-Powered-By-->ASP.NET
Content-Type-->text/xml; charset=utf-8
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getSupportCityResponse xmlns="http://WebXml.com.cn/"><getSupportCityResult><string>合肥 (58321)</string><string>巢湖 (58326)</string><string>蚌埠 (58221)</string><string>安庆 (58424)</string><string>六安 (58311)</string><string>滁州 (58236)</string><string>马鞍山 (58336)</string><string>阜阳 (58203)</string><string>宣城 (58433)</string><string>铜陵 (58429)</string><string>淮北 (58116)</string><string>芜湖 (58334)</string><string>宿州 (58122)</string><string>淮南 (58224)</string><string>池州 (58427)</string></getSupportCityResult></getSupportCityResponse></soap:Body></soap:Envelope>
四、遇见问题
错误内容很明细,就是只能打印出消息头,消息体不能打印,然后过段时间连接重置,报错,当时还怀疑服务器没有返回,使用抓包工具后,发现数据是返回的,然后这个问题就困惑了好几天
关键问题:
read()会返回-1呢?答案是:当TCP通信连接的一方关闭了套接字时。【readLine底层应该也是这个类似方法】
再次分析改过后的代码,客户端用到了read()返回-1这个条件,而服务端也用到了,只有二者有一方关闭了Socket,另一方的read()方法才会返回-1,而在客户端打印输出前,二者都没有关闭Socket,因此,二者的read()方法都不会返回-1,程序便阻塞在此处,都不往下执行,这便造成了死锁。
基本上确定了:webservice服务端并没有关闭输出的socket输入流,由于我们只是客户端,我们就无法控制了,处理的方式就是:
将inputStream流中读取完后【context-length:然后读取这个长度】,之后直接跳出再次读环节就可以了,具体就见代码了,有点小麻烦!!
五、此只是本人深入一点学习http协议吧,如果要模拟http请求建议httpclient,代码有问题,也欢迎大家指正!谢谢!!!
最近看了一些关于关于socket模拟文件服务器的文章或者视频,客户端通过浏览器访问,服务端通过socket去实现,学习之下了解到就是向socket发送制定格式的内容【http协议】,然后服务端进行解析,返回相关的数据,于是就想肯定要可以使用socket模拟调用webservice【webservice就是http协议+soap报文通过tcp协议来传输】,当然了使用httpclient去模拟发送get/post请求最方便,不过也是自己对http协议深入理解【原来的理解就知道http协议是什么样的,但是具体发送的啥内容也模糊】
二、直接贴代码:
1.调用部分
package com.pjf.netbase; import com.pjf.netentity.Response; import com.pjf.netservice.ClientService; public class WebServiceClient { public final static int BYTELEN = 1024;// 经测试64个字节以上没有问题 public static void main(String[] args) throws Exception { // BufferedReader br=new BufferedReader(new InputStreamReader(new // FileInputStream("1.txt"))); // String str=""; // while((str=br.readLine())!=null){ // System.out.println(str); // // } // long startTime = System.currentTimeMillis(); System.out.println(); // Socket socket = new Socket("www.webxml.com.cn", 80); // PrintWriter pw = new PrintWriter(socket.getOutputStream()); String req = /* * "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + */ "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n" + "<soap:Body>\r\n" + "<getSupportCity xmlns=\"http://WebXml.com.cn/\">\r\n" + "<byProvinceName>安徽</byProvinceName>\r\n" + "</getSupportCity>\r\n" + "</soap:Body>\r\n" + "</soap:Envelope>\r\n"; String head = "POST /WebServices/WeatherWebService.asmx HTTP/1.1\r\n" + "Host: www.webxml.com.cn\r\n" + "Content-Type: text/xml; charset=utf-8\r\n" + "Content-Length:" + req.getBytes().length + "\r\n" + "SOAPAction: \"http://WebXml.com.cn/getSupportCity\"\r\n\r\n"; Response res = ClientService.callWebService(head, req, "www.webxml.com.cn", 80); if (res.getStatus().equals("999")) { System.out.println("连接异常,请检查连接"); } else { System.out.println(res.toString()); } // System.out.println(head + str); // pw.println(head + str); // pw.flush(); // // 接受客户端的响应 // byte[] b = new byte[BYTELEN]; // byte[] context = null; // byte[] headbyte = null; // InputStream is = socket.getInputStream(); // int len = 0; // // int start_position = 0; // int end_position = 0; // int contlen = 0; // boolean isContinue = true; // while ((len = is.read(b)) != -1) { // System.out.println("每次读取的长度:" + len); // // 解析内容 // if (isContinue) { // // 针对头部信息,防止制定的字节一个byte[len]你不够,此处进行字节数组拼接 // if (headbyte == null) { // headbyte = new byte[len]; // System.arraycopy(b, 0, headbyte, 0, len); // // } else { // byte[] tmp = new byte[headbyte.length + len]; // System.arraycopy(headbyte, 0, tmp, 0, headbyte.length); // System.arraycopy(b, 0, tmp, headbyte.length, len); // headbyte = tmp; // b = tmp; // // } // // for (int i = start_position; i < b.length; i++) { // if (b[i] == '\r') { // end_position = i; // String data = new String(b, start_position, end_position - // start_position); // if (data.contains("Content-Length")) { // // System.out.println("----contlen"+data); // contlen = Integer.parseInt(data.split(" ")[1]); // } // // System.out.println("每次读取输出的内容:" + data); // start_position = i + 2; // i = i + 1; // if (data.equals("")) { // isContinue = false; // System.out.println("内容准备读取,跳出循环准备全部去读"); // break; // } // // } // // } // } // // 如果头结点已经读取完毕,则进行保留内存的内容结点 // if (isContinue == false) { // // if (context == null) { // context = new byte[b.length - start_position]; // if (b.length - start_position > 0) { // System.arraycopy(b, start_position, context, 0, b.length - // start_position); // } // // 需要判断是否立即结束 ----针对于一次读完的情况,加入此判断,否则可能存在问题 // if (len < BYTELEN) { // break; // } // } // // } else if (len < BYTELEN) {//bug就出现在这 // // byte[] tmp = new byte[context.length + len]; // // System.arraycopy(context, 0, tmp, 0, context.length); // // System.arraycopy(b, 0, tmp, context.length, len); // // context = tmp; // // break; // // } // else { // byte[] tmp = new byte[context.length + len]; // System.arraycopy(context, 0, tmp, 0, context.length); // System.arraycopy(b, 0, tmp, context.length, len); // context = tmp; // System.out.println((context.length) + "-------------" + contlen); // if (context.length == contlen) {// 表示数据读取完毕 // break; // } // } // // } // // } // long endTime = System.currentTimeMillis(); // System.out.println("使用时间:" + (endTime - startTime)); // System.out.println(new String(context)); // System.out.println("处理完毕"); // pw.close(); // socket.close(); } }
2.Response对象定义
package com.pjf.netentity; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * * @author pengjf 作为调用webservice的返回对象封装 * */ public class Response { private String status;// 状态 private String statusNum; private String version; public Response() { status = "-999"; } public String getStatusNum() { return statusNum; } public void setStatusNum(String statusNum) { this.statusNum = statusNum; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } private Map<String, String> headMap = new HashMap<String, String>();// 头节点 private String resultSoapXml = "";// 解析内容 public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public Map<String, String> getHeadMap() { return headMap; } public void setHeadMap(Map<String, String> headMap) { this.headMap = headMap; } public String getResultSoapXml() { return resultSoapXml; } public void setResultSoapXml(String resultSoapXml) { this.resultSoapXml = resultSoapXml; } @Override public String toString() { String result = ""; Iterator iter = headMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); result += entry.getKey() + "-->" + entry.getValue() + "\r\n"; } return status + " " + statusNum + " " + version + "\r\n" + result + "\r\n" + resultSoapXml; } }
3.核心处理部分[调用+解析]
package com.pjf.netservice; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import com.pjf.netentity.Response; public class ClientService { public static int BYTELEN = 1024; public static Response callWebService(String head, String request, String host, int port) throws UnknownHostException, IOException { Socket socket = new Socket(host, port); PrintWriter pw = new PrintWriter(socket.getOutputStream()); pw.println(head + request); pw.flush(); Response res = praseInputStrem(socket); pw.close(); pw = null; return res; } public static Response praseInputStrem(Socket socket) { Response res = new Response(); try { long startTime = System.currentTimeMillis(); // 接受客户端的响应 byte[] b = new byte[BYTELEN]; byte[] context = null; byte[] headbyte = null; InputStream is = socket.getInputStream(); int len = 0; int start_position = 0; int end_position = 0; int contlen = 0; boolean isContinue = true; boolean isFirstLine = true; while ((len = is.read(b)) != -1) { System.out.println("每次读取的长度:" + len); // 解析内容 if (isContinue) { // 针对头部信息,防止制定的字节一个byte[len]你不够,此处进行字节数组拼接 if (headbyte == null) { headbyte = new byte[len]; System.arraycopy(b, 0, headbyte, 0, len); } else { byte[] tmp = new byte[headbyte.length + len]; System.arraycopy(headbyte, 0, tmp, 0, headbyte.length); System.arraycopy(b, 0, tmp, headbyte.length, len); headbyte = tmp; b = tmp; } for (int i = start_position; i < b.length; i++) { if (b[i] == '\r') { end_position = i; String data = new String(b, start_position, end_position - start_position); if (isFirstLine) { isFirstLine = false; System.out.println(data); String[] firstLineData = data.trim().split(" "); if (firstLineData.length != 3) { res.setStatus("999"); return res; } else { res.setStatus(firstLineData[2]); res.setStatusNum(firstLineData[1]); res.setVersion(firstLineData[0]); } } // String data = new String(b, start_position, // end_position - start_position); if (data.contains("Content-Length")) { // System.out.println("----contlen"+data); contlen = Integer.parseInt(data.split(" ")[1]); } if (data.contains(":")) { String[] headsplit = data.split(":"); res.getHeadMap().put(headsplit[0].trim(), headsplit[1].trim()); } System.out.println("每次读取输出的内容:" + data); start_position = i + 2; i = i + 1; if (data.equals("")) { isContinue = false; System.out.println("内容准备读取,跳出循环准备全部去读"); break; } } } } // 如果头结点已经读取完毕,则进行保留内存的内容结点 if (isContinue == false) { if (context == null) { context = new byte[b.length - start_position]; if (b.length - start_position > 0) { System.arraycopy(b, start_position, context, 0, b.length - start_position); } // 需要判断是否立即结束 ----针对于一次读完的情况,加入此判断,否则可能存在问题 if (len < BYTELEN) { break; } } else { byte[] tmp = new byte[context.length + len]; System.arraycopy(context, 0, tmp, 0, context.length); System.arraycopy(b, 0, tmp, context.length, len); context = tmp; System.out.println((context.length) + "-------------" + contlen); if (context.length == contlen) {// 表示数据读取完毕 break; } } } } long endTime = System.currentTimeMillis(); System.out.println("使用时间:" + (endTime - startTime)); res.setResultSoapXml(new String(context)); socket.shutdownInput(); socket.shutdownOutput(); is.close(); is = null; socket = null; System.out.println("处理完毕"); } catch (IOException e) { System.out.println(e); } return res; } }
三、测试结果:
OK 200 HTTP/1.1
Server-->Microsoft-IIS/6.0
Cache-Control-->private, max-age=0
X-AspNet-Version-->2.0.50727
Content-Length-->838
Date-->Tue, 12 Dec 2017 15
X-Powered-By-->ASP.NET
Content-Type-->text/xml; charset=utf-8
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getSupportCityResponse xmlns="http://WebXml.com.cn/"><getSupportCityResult><string>合肥 (58321)</string><string>巢湖 (58326)</string><string>蚌埠 (58221)</string><string>安庆 (58424)</string><string>六安 (58311)</string><string>滁州 (58236)</string><string>马鞍山 (58336)</string><string>阜阳 (58203)</string><string>宣城 (58433)</string><string>铜陵 (58429)</string><string>淮北 (58116)</string><string>芜湖 (58334)</string><string>宿州 (58122)</string><string>淮南 (58224)</string><string>池州 (58427)</string></getSupportCityResult></getSupportCityResponse></soap:Body></soap:Envelope>
四、遇见问题
错误内容很明细,就是只能打印出消息头,消息体不能打印,然后过段时间连接重置,报错,当时还怀疑服务器没有返回,使用抓包工具后,发现数据是返回的,然后这个问题就困惑了好几天
关键问题:
read()会返回-1呢?答案是:当TCP通信连接的一方关闭了套接字时。【readLine底层应该也是这个类似方法】
再次分析改过后的代码,客户端用到了read()返回-1这个条件,而服务端也用到了,只有二者有一方关闭了Socket,另一方的read()方法才会返回-1,而在客户端打印输出前,二者都没有关闭Socket,因此,二者的read()方法都不会返回-1,程序便阻塞在此处,都不往下执行,这便造成了死锁。
基本上确定了:webservice服务端并没有关闭输出的socket输入流,由于我们只是客户端,我们就无法控制了,处理的方式就是:
将inputStream流中读取完后【context-length:然后读取这个长度】,之后直接跳出再次读环节就可以了,具体就见代码了,有点小麻烦!!
五、此只是本人深入一点学习http协议吧,如果要模拟http请求建议httpclient,代码有问题,也欢迎大家指正!谢谢!!!
相关推荐
java调用webservicejava调用webservice.zipjava调用webservice.zipjava调用webservice.zipjava调用webservice.zipjava调用webservice.zipjava调用webservice.zipjava调用webservice.zipjava调用webservice.zipjava...
利用socket thread dom4j log4j axis2 soap PBE加解密等相关技术实现的socket协议调用webservice服务。 由于银行后台核心系统普遍采用的是UNIX下C/C++的开发平台,如果需要调Web Service往往需要借助一些第三方的库...
"Java 使用 XFire 调用 webService 接口" 在本文中,我们将学习如何使用 XFire 框架在 Java 中调用 webService 接口。XFIRE 是一个基于 Java 的开源框架,用于简化 Web 服务的开发和集成。下面,我们将通过一个简单...
总结,Java Android调用Webservice涉及到网络请求、数据传输、解析和安全等多个环节,开发者需要了解HTTP协议,选择合适的Web服务类型,以及掌握相应的数据解析技术。通过合理利用第三方库和遵循最佳实践,可以提高...
Java Axis调用WebService服务端是Java开发者在进行分布式系统交互时常见的一种技术实践。Axis是Apache软件基金会开发的一个开源项目,它提供了一种方便、高效的方式,使得Java应用程序能够作为客户端来消费或作为...
调用WebService,最简单的办法当然是直接添加WEB引用,然后自动产生代理类,但是在调用JAVA的WebService时并没有这么简单,特别是对于SoapHeader的处理,通过C#添加Web引用方式访问JavaWebService的方法,除了string...
本话题主要探讨如何使用Java调用由C++实现的Web服务(Webservice)。在给出的描述中,提到了通过WSDL(Web Services Description Language)文件来实现这一目标。以下是关于这个主题的详细知识点: 1. **Web服务...
JAX-WS提供了创建和消费SOAP WebService的API,包括`javax.jws.WebService`注解用于声明服务端点,以及`javax.xml.ws.Service`类用于客户端调用。本工具类可能利用了JAX-WS的一些核心功能来简化服务调用。 4. **...
本文将深入探讨如何使用Axis2来动态地调用Web Service,并通过分析`WebServiceInvoker.java`这个文件来理解其实现原理。 1. **Java动态调用Web Service**: 在Java中,动态调用Web Service主要涉及到JAX-WS(Java ...
在探讨Java调用带有JSON参数的WebService之前,我们首先需要了解几个关键的技术概念:Java、JSON以及WebService。 Java是一种广泛使用的编程语言,它具有面向对象、跨平台、多线程以及健壮性等特点。Java在企业级...
Java 调用 ODI webservice 实现数据同步 Java 调用 ODI webservice 是实现数据同步的一种常见方式。ODI(Oracle Data Integrator)是一种数据集成平台,提供了webservice接口,允许用户通过webservice调用ODI方案...
JAVA调用WEBSERVICE接口
这篇博客“Java使用XFire调用WebService接口”显然是讨论如何利用XFire这个开源框架来与Web服务交互。 XFire是Apache CXF项目的前身,它提供了一种简单的方式来创建和消费SOAP Web服务。XFire的强项在于其轻量级和...
JAVA 调用 SAP SOAP webservice 详解 在本文中,我们将详细介绍如何使用 JAVA 调用 SAP SOAP webservice,包括配置 SAP 登录信息、创建 java 项目、添加 web 服务客户端、生成 JAVA 类、调用接口等步骤。 配置 SAP...
总的来说,使用Apache Axis调用HTTPS Web Service涉及到了Java的网络编程、SSL/TLS协议以及Web Service的原理。通过理解这些知识点,开发者可以构建安全、可靠的Web Service客户端应用。在实践中,务必关注安全性,...
Java Axis 直接调用webservice 接口工具类, 无需根据wsdl编译客户端,需要axis相关包,测试使用axis 1.4, 附demo引入axis包后直接可以测试;
java调用webservice接口案例,精简,service调用webservice接口案例;不用生成一堆代码,逻辑清晰
本方法是用axis1.4技术,实现java客户端调用webservice。已经可实现过可行的,如果不行可加我QQ号302633进行详细解析。
总结,调用Java中的Web服务并解析XML涉及到了Web服务的基础概念、Java的Web服务客户端创建、XML解析技术以及实际的调用与响应处理。熟练掌握这些知识点,能够帮助开发者有效地集成和利用各种Web服务资源。
Java调用WebService工程是将Java应用程序与通过WebService接口提供的服务进行交互的过程。WebService是一种基于XML标准的、平台和语言无关的通信方式,它允许不同系统间的应用能够共享数据和服务。在Java中,我们...