- 浏览: 77304 次
- 性别:
- 来自: 新加坡
最新评论
-
lzzy_alex:
"any problem in computer s ...
JVM原理学习笔记(二) —— 虚拟机规范 -
lonpo:
lonpo 写道是encodeURIComponent()方法 ...
收集了一些URI特殊字符的编码,有一些想法 -
lonpo:
你可以使用javascript的encodeURICompon ...
收集了一些URI特殊字符的编码,有一些想法 -
jeff312:
如果没有被墙,scala官网上的资料已经很多。我对scala也 ...
Scala种种信息--google地毯式搜索的收获 -
桥下一粒砂:
兄台,我对Scala也很感兴趣,不知道你有没什么学习资源分享一 ...
Scala种种信息--google地毯式搜索的收获
js框架很多,JQuery算是其中比较有趣的,AJAX功能用起来也挺方便,我手头的应用,视图层的交互和XML解析全靠它了。缺点不是没有,jq的AJAX请求函数只支持接收XML/HTML/JSON/JSONP格式的服务器数据。在普通情况下,我们往往只是用AJAX呼叫服务器获取相关文本、数值或XML这种结构化的文档,这些返回数据,说到底都是基于文本的,以至于给我们制造了一个错觉,即AJAX/XMLHttpRequest只能用于基于文本的内容/数据交互。在疯狂Google了一天后的结果,也证实了我的判断令人尴尬地准确着。
在网上问十个人,九个会告诉你XMLHttpRequest只能交互文本,实际上完全不是这样,不知道是不是因为太多的人一上手就开始用框架而不是研究HttpRequest对象的特性,但关于ResponseBody的使用几乎没有人谈及,这就有点遗憾了。首先,我找到下面一篇文章,较为详细地解释了HttpRequest对象的属性和方法:
http://blog.chinaunix.net/u2/61797/showart_1000687.html
里面的东西我就不照抄了,这里只请大家注意“属性:responseBody”这个属性的讲解。显然,只依靠JQuery的几个AJAX函数,是无法处理这种返回数据的,这种情况下,只能自己编写直接给予XMLHttpRequest的交互函数了。
根据这篇文章所述,responseBody实际上是个二进制结构,在IE8的Debugger里显示为“Array of Byte”。实际上这个数据结构是兼容于VB/C 中的Byte数组的,比如在VB里面我们会这样定义一个Byte数组:
Dim bytes(10) As Byte
但是js/vbs却是不支持这种数据结构的,ByteArray对于js来说只是内存中的一个特殊对象,其结构对js来说是完全透明的,脚本能够使用其内存地址来获取对其的引用,却不能操作这个透明物体。js所能做的,就是持有这个对象的地址引用,然后pass给其它可以处理该数据的组件或程序。
很多人可能一辈子都不会用到responseBody这个属性,所以有必要解释一下我为什么那么需要它。我的项目里需要实现一个机制,用servlet提供一个TIF文件流,然后客户端js应该能接收这个二进制流的数据,并将之传给一个图像浏览组件。这个流程的核心问题就是:图像浏览组件(ActiveX)只能接受ByteArray的二进制数据,故必须要想尽一切办法得到ByteArray对象。
在本人还未意识到responseBody之前,曾天真地认为:1)ByteArray是一个js能识别的Array对象;2)HttpRequest只能传输文本数据。在这种自以为是的思想指导下,我提出了第一个解决方案:
1) 在服务端Servlet取得文件流后将之byte by byte读出,然后组装成一个JSON格式的字符串,如: "[72, 43, 43, 0, 38 ...]"的形式;
2) 通过PrintWriter.print()方法把这个JSON字符串发送到客户端js的回调函数,并由该回调函数把JSON字符串转换成js数组;
3) 由于该js数组中的所有元素都是byte数据(范围在0~255内的整数),直接将该js数组作为ByteArray参数传入图像浏览组件,并显示图片。
然而,由于没有清楚认识到ByteArray的数据性质,上述的方案无疑是失败的,图像组件直接因参数类型不匹配而报错。并且,由于所有的byte都被转换成文本后才传输的,该交互行为需要的实际的网络流量远远超过了原二进制文件的容量(*见备注的换算)。
在阅读了responseBody的相关信息后,我坚信ByteArray数据是能被它接收到的,问题是Servlet应该怎样写数据才能传给responseBody一个ByteArray。首先我想到的是用response.getOutputStream(),具体代码如下:
事实证明这个试验是不成功的,到达客户端的ByteArray数据量大得惊人,对于servlet的OutputStream没什么研究,一时摸不透原因。于是,我再试了下面的代码:
其中byteArray2CharArray()方法的实现我就不写了,总之它的功能就是把一个byteArray翻译成一个charArray,各个元素的整数绝对值保持不变(在JVM里,无论是byte还是char最后都将被表示成int,但char是非负的所以采用绝对值)。这里比较怪异,试验仍然不太成功,虽然客户端responseBody接收到了一个size正确的ByteArray,里面的数据却是不正确的,因为在Buffered的读取方式下,有的byte值居然是负数,这是相当怪异的也是不正确的。接下来,一个有点“笨”的方法,居然取得了成功:
最终,这个采用PrintWriter.write(int b)的方法获得了成功,客户端拿到了正确的ByteArray数据,图像文件也得以正确还原并显示。
虽然最后一个方法取得了成功,笔者心里还是有些不舒服,因为没有用到buffer,有多少个byte就得调用多少次write(int b)方法,通过查看JDK的源代码,该方法是强制同步的,获得锁释放锁等额外开销让人无法忘怀,这样写的话性能不可能很好,目前正考虑继承PrintWriter写一个类,还望这方面有心得的朋友能一起交流一下。至于byte[]的缓冲读取方式为何出现怪异数据我还耿耿于怀,苦于没有时间再去看JBoss的实现源码,只能请有研究的朋友不吝指教了。
*备注: 例如 121 这个整数,当其类型是byte的时候,只占1个字节,而字符串"121"则会占据6个字节,因为每一个字符char都会占据2个字节。在加上连接JSON数组需要用到","作分隔符也要占据2个字节,头尾一对方括号占4个字符暂且忽略不计。因此,假设一个ByteArray里面的数据全都是(byte)121,那么当其解析成字符串后,其大小应该是源数据的约8倍,对于一个基于网络的程序来说这种缺陷是不能容忍的。
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
脑子进水的傻子才去折腾用jsp输出byte array,更别提用response.reset()来折腾服务器
毋须讳言,我对Http二进制流真的一知半解,即使原来已经猜到动态静态获取都无区别,面对问题也不得不怀疑自己当初的判断。
还要加强学习啊。
这个是一个可行方案,之前在一个项目里面用了,浏览器可以直接打开二进制流,不然就直接提示下载。问题是,有一个小概率事件发生 就是IE会出现白屏,就是什么都不显示,渲染失败。
不知道现在IE会否有该善,三年前的项目用的还是IE6。(另外,公司原因没其他浏览器测试)
其实现在看来,用out.write(int b) 或 out.write(char[] bb) 的方式比较适合我现在的系统要求,因为原来是不得已得靠ActiveX下载图片文件后缓存在本地待用,这样一来无论是删除、下载、加载都必须让js拥有管理客户机本地文件的权限,相信不少客户都会对此抵触。现在把图片的二进制信息直接缓存在内存中,需要绘制的时候就拿出来让ActiveX渲染,又快又安全。
代码经过修正,是可以的,这是我自己的bug,让朋友费心了。
这个是一个可行方案,之前在一个项目里面用了,浏览器可以直接打开二进制流,不然就直接提示下载。问题是,有一个小概率事件发生 就是IE会出现白屏,就是什么都不显示,渲染失败。
不知道现在IE会否有该善,三年前的项目用的还是IE6。(另外,公司原因没其他浏览器测试)
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
如果不是组建的开发人员把后缀名定死了的话,那就可能是 response 头的 MIME 类型问题。就算是开发人员把后缀名定死了,楼主不妨这样:
http://host_name:8080/AppName/SomeServlet?fileId=30&foo=bar.tif
反正服务器端不处理 foo 参数,也许能骗过组件。
第一种方法你提到的数据量大的惊人,我基本上可以猜到什么原因了
你用的是ie看的吧,而且你没有告诉ie你数据流的格式是什么,ie当成图片来处理,你看到的实际上是经过ie转换后的bmp
你只需要在你的head上设置contenttype为image/tiff
建议你再额外设置content length
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
你的意见我正在考虑,在向ActiveX供应商寻求支持时,那边的回答就是只能拿实际文件而不能拿servlet二进制流。你这一说,我开始怀疑他们是否对此有过测试。谢谢提示。
供应商瞎扯蛋,tomcat静态文件也是通过servlet传送给客户端的, DefaultServlet
你可以尝试下跟踪应答头,看看你缺少了什么
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
你的意见我正在考虑,在向ActiveX供应商寻求支持时,那边的回答就是只能拿实际文件而不能拿servlet二进制流。你这一说,我开始怀疑他们是否对此有过测试。谢谢提示。
这恐怕跟服务器端的stream的类型和方式有关,我也试过用byte[]缓冲输出流(缓冲区byte[]得到数据后,把它编码成相应的char[]),诡异的是,浏览器端收到了正确的二进制数据,但IE却随后立即崩溃了。以IO流输出文件只怕与实际文件地址URL读取还是有区别的,区别在哪里还要请人指教。
有区别也是服务器端没设置好,查看一下响应头,就知道哪儿不同了。
多谢提示,我就去研究一下响应头。
你倒是提醒了我,其实JBoss的servlet实现就是Tomcat的实现,JBoss现在把Tomcat当成一个子集,专门处理web/servlet请求。
第二个方案的代码中我省略了byteArray2CharArray()方法的代码,实现上跟你的设想其实没多大差别,而这正是我在主帖里对方案二描述的故障的源头。实际上从byte到char的解码编码没那么简单,强制转换是行不通的,实际上,b会先被转换成有符号int,然后才会转成char,这样一来就麻烦了,因为char是无符号的,当中间int数据是负数的时候,char的结果就会出错。比较正确简洁的代码如下:
当然,即使通过转换使得char数组得到了正确的二进制数据,方案仍然行不通,因为IE虽然接到了正确的数据,却突然离奇崩溃了,正在考虑一些跟帖网友的建议,试一试resp.reset()之类的办法。
这恐怕跟服务器端的stream的类型和方式有关,我也试过用byte[]缓冲输出流(缓冲区byte[]得到数据后,把它编码成相应的char[]),诡异的是,浏览器端收到了正确的二进制数据,但IE却随后立即崩溃了。以IO流输出文件只怕与实际文件地址URL读取还是有区别的,区别在哪里还要请人指教。
有区别也是服务器端没设置好,查看一下响应头,就知道哪儿不同了。
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
在网上问十个人,九个会告诉你XMLHttpRequest只能交互文本,实际上完全不是这样,不知道是不是因为太多的人一上手就开始用框架而不是研究HttpRequest对象的特性,但关于ResponseBody的使用几乎没有人谈及,这就有点遗憾了。首先,我找到下面一篇文章,较为详细地解释了HttpRequest对象的属性和方法:
http://blog.chinaunix.net/u2/61797/showart_1000687.html
里面的东西我就不照抄了,这里只请大家注意“属性:responseBody”这个属性的讲解。显然,只依靠JQuery的几个AJAX函数,是无法处理这种返回数据的,这种情况下,只能自己编写直接给予XMLHttpRequest的交互函数了。
根据这篇文章所述,responseBody实际上是个二进制结构,在IE8的Debugger里显示为“Array of Byte”。实际上这个数据结构是兼容于VB/C 中的Byte数组的,比如在VB里面我们会这样定义一个Byte数组:
Dim bytes(10) As Byte
但是js/vbs却是不支持这种数据结构的,ByteArray对于js来说只是内存中的一个特殊对象,其结构对js来说是完全透明的,脚本能够使用其内存地址来获取对其的引用,却不能操作这个透明物体。js所能做的,就是持有这个对象的地址引用,然后pass给其它可以处理该数据的组件或程序。
很多人可能一辈子都不会用到responseBody这个属性,所以有必要解释一下我为什么那么需要它。我的项目里需要实现一个机制,用servlet提供一个TIF文件流,然后客户端js应该能接收这个二进制流的数据,并将之传给一个图像浏览组件。这个流程的核心问题就是:图像浏览组件(ActiveX)只能接受ByteArray的二进制数据,故必须要想尽一切办法得到ByteArray对象。
在本人还未意识到responseBody之前,曾天真地认为:1)ByteArray是一个js能识别的Array对象;2)HttpRequest只能传输文本数据。在这种自以为是的思想指导下,我提出了第一个解决方案:
1) 在服务端Servlet取得文件流后将之byte by byte读出,然后组装成一个JSON格式的字符串,如: "[72, 43, 43, 0, 38 ...]"的形式;
2) 通过PrintWriter.print()方法把这个JSON字符串发送到客户端js的回调函数,并由该回调函数把JSON字符串转换成js数组;
3) 由于该js数组中的所有元素都是byte数据(范围在0~255内的整数),直接将该js数组作为ByteArray参数传入图像浏览组件,并显示图片。
然而,由于没有清楚认识到ByteArray的数据性质,上述的方案无疑是失败的,图像组件直接因参数类型不匹配而报错。并且,由于所有的byte都被转换成文本后才传输的,该交互行为需要的实际的网络流量远远超过了原二进制文件的容量(*见备注的换算)。
在阅读了responseBody的相关信息后,我坚信ByteArray数据是能被它接收到的,问题是Servlet应该怎样写数据才能传给responseBody一个ByteArray。首先我想到的是用response.getOutputStream(),具体代码如下:
File file = new File("c:\\001.tif"); InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); OutputStream out = response.getOutputStream(); int b = 0; int len = 0; byte[] buf = new byte[1024]; while ((len = bis.read(buf)) != -1) { out.write(buf, 0, len); } out.flush(); out.close(); bis.close();
事实证明这个试验是不成功的,到达客户端的ByteArray数据量大得惊人,对于servlet的OutputStream没什么研究,一时摸不透原因。于是,我再试了下面的代码:
File file = new File("c:\\001.tif"); InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); PrintWriter out = resp.getWriter(); byte[] buf = new byte[1024]; int len = 0; try { while ((len = in.read(buf)) != -1) { char[] cbuf = byteArray2CharArray(buf); write(cbuf, 0, len); out.flush(); } } catch (IOException ex) { ex.printStackTrace(); }
其中byteArray2CharArray()方法的实现我就不写了,总之它的功能就是把一个byteArray翻译成一个charArray,各个元素的整数绝对值保持不变(在JVM里,无论是byte还是char最后都将被表示成int,但char是非负的所以采用绝对值)。这里比较怪异,试验仍然不太成功,虽然客户端responseBody接收到了一个size正确的ByteArray,里面的数据却是不正确的,因为在Buffered的读取方式下,有的byte值居然是负数,这是相当怪异的也是不正确的。接下来,一个有点“笨”的方法,居然取得了成功:
File file = new File("c:\\001.tif"); InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); PrintWriter out = resp.getWriter(); int b = 0; while ((b = bis.read()) != -1) { out.write(b); } out.flush(); out.close(); bis.close();
最终,这个采用PrintWriter.write(int b)的方法获得了成功,客户端拿到了正确的ByteArray数据,图像文件也得以正确还原并显示。
虽然最后一个方法取得了成功,笔者心里还是有些不舒服,因为没有用到buffer,有多少个byte就得调用多少次write(int b)方法,通过查看JDK的源代码,该方法是强制同步的,获得锁释放锁等额外开销让人无法忘怀,这样写的话性能不可能很好,目前正考虑继承PrintWriter写一个类,还望这方面有心得的朋友能一起交流一下。至于byte[]的缓冲读取方式为何出现怪异数据我还耿耿于怀,苦于没有时间再去看JBoss的实现源码,只能请有研究的朋友不吝指教了。
*备注: 例如 121 这个整数,当其类型是byte的时候,只占1个字节,而字符串"121"则会占据6个字节,因为每一个字符char都会占据2个字节。在加上连接JSON数组需要用到","作分隔符也要占据2个字节,头尾一对方括号占4个字符暂且忽略不计。因此,假设一个ByteArray里面的数据全都是(byte)121,那么当其解析成字符串后,其大小应该是源数据的约8倍,对于一个基于网络的程序来说这种缺陷是不能容忍的。
评论
29 楼
shewa5337
2010-07-09
把这个帖子顶顶。
碰到这样一个问题,怎么把responseBody取到的二进制数据在浏览器中显示出来
碰到这样一个问题,怎么把responseBody取到的二进制数据在浏览器中显示出来
28 楼
ninja9turtle
2010-07-07
myy 写道
jeff312 写道
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
脑子进水的傻子才去折腾用jsp输出byte array,更别提用response.reset()来折腾服务器
27 楼
jeff312
2009-11-23
linliangyi2007 写道
我承认我没有细看楼主的原文,但servlet输出动态图片和文件都是标准的HTTP二进制传输,感觉楼主不懂IO基础,弄的很是麻烦!!
说白了只要是流就能传二进制Byte信息,只要能有byte信息,对计算机而言就拥有了全部的信息获取手段!!
有说的不对的楼主可以拍砖。
说白了只要是流就能传二进制Byte信息,只要能有byte信息,对计算机而言就拥有了全部的信息获取手段!!
有说的不对的楼主可以拍砖。
毋须讳言,我对Http二进制流真的一知半解,即使原来已经猜到动态静态获取都无区别,面对问题也不得不怀疑自己当初的判断。
还要加强学习啊。
26 楼
jeff312
2009-11-23
mangoo1 写道
引用
如果不是组建的开发人员把后缀名定死了的话,那就可能是 response 头的 MIME 类型问题。就算是开发人员把后缀名定死了,楼主不妨这样:
http://host_name:8080/AppName/SomeServlet?fileId=30&foo=bar.tif
反正服务器端不处理 foo 参数,也许能骗过组件。
http://host_name:8080/AppName/SomeServlet?fileId=30&foo=bar.tif
反正服务器端不处理 foo 参数,也许能骗过组件。
这个是一个可行方案,之前在一个项目里面用了,浏览器可以直接打开二进制流,不然就直接提示下载。问题是,有一个小概率事件发生 就是IE会出现白屏,就是什么都不显示,渲染失败。
不知道现在IE会否有该善,三年前的项目用的还是IE6。(另外,公司原因没其他浏览器测试)
其实现在看来,用out.write(int b) 或 out.write(char[] bb) 的方式比较适合我现在的系统要求,因为原来是不得已得靠ActiveX下载图片文件后缓存在本地待用,这样一来无论是删除、下载、加载都必须让js拥有管理客户机本地文件的权限,相信不少客户都会对此抵触。现在把图片的二进制信息直接缓存在内存中,需要绘制的时候就拿出来让ActiveX渲染,又快又安全。
25 楼
jeff312
2009-11-23
ahuango 写道
既然用int 可以正确输出到client端,为什么不能用buffer writer 来输出呢
代码经过修正,是可以的,这是我自己的bug,让朋友费心了。
24 楼
mangoo1
2009-11-21
引用
如果不是组建的开发人员把后缀名定死了的话,那就可能是 response 头的 MIME 类型问题。就算是开发人员把后缀名定死了,楼主不妨这样:
http://host_name:8080/AppName/SomeServlet?fileId=30&foo=bar.tif
反正服务器端不处理 foo 参数,也许能骗过组件。
http://host_name:8080/AppName/SomeServlet?fileId=30&foo=bar.tif
反正服务器端不处理 foo 参数,也许能骗过组件。
这个是一个可行方案,之前在一个项目里面用了,浏览器可以直接打开二进制流,不然就直接提示下载。问题是,有一个小概率事件发生 就是IE会出现白屏,就是什么都不显示,渲染失败。
不知道现在IE会否有该善,三年前的项目用的还是IE6。(另外,公司原因没其他浏览器测试)
23 楼
linliangyi2007
2009-11-21
我承认我没有细看楼主的原文,但servlet输出动态图片和文件都是标准的HTTP二进制传输,感觉楼主不懂IO基础,弄的很是麻烦!!
说白了只要是流就能传二进制Byte信息,只要能有byte信息,对计算机而言就拥有了全部的信息获取手段!!
有说的不对的楼主可以拍砖。
说白了只要是流就能传二进制Byte信息,只要能有byte信息,对计算机而言就拥有了全部的信息获取手段!!
有说的不对的楼主可以拍砖。
22 楼
yiding_he
2009-11-20
jeff312 写道
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
如果不是组建的开发人员把后缀名定死了的话,那就可能是 response 头的 MIME 类型问题。就算是开发人员把后缀名定死了,楼主不妨这样:
http://host_name:8080/AppName/SomeServlet?fileId=30&foo=bar.tif
反正服务器端不处理 foo 参数,也许能骗过组件。
21 楼
nj_first
2009-11-20
我也觉得楼上的手的有道理
20 楼
oxromantic
2009-11-20
jeff312 写道
js框架很多,JQuery算是其中比较有趣的,AJAX功能用起来也挺方便,我手头的应用,视图层的交互和XML解析全靠它了。缺点不是没有,jq的AJAX请求函数只支持接收XML/HTML/JSON/JSONP格式的服务器数据。在普通情况下,我们往往只是用AJAX呼叫服务器获取相关文本、数值或XML这种结构化的文档,这些返回数据,说到底都是基于文本的,以至于给我们制造了一个错觉,即AJAX/XMLHttpRequest只能用于基于文本的内容/数据交互。在疯狂Google了一天后的结果,也证实了我的判断令人尴尬地准确着。
在网上问十个人,九个会告诉你XMLHttpRequest只能交互文本,实际上完全不是这样,不知道是不是因为太多的人一上手就开始用框架而不是研究HttpRequest对象的特性,但关于ResponseBody的使用几乎没有人谈及,这就有点遗憾了。首先,我找到下面一篇文章,较为详细地解释了HttpRequest对象的属性和方法:
http://blog.chinaunix.net/u2/61797/showart_1000687.html
里面的东西我就不照抄了,这里只请大家注意“属性:responseBody”这个属性的讲解。显然,只依靠JQuery的几个AJAX函数,是无法处理这种返回数据的,这种情况下,只能自己编写直接给予XMLHttpRequest的交互函数了。
根据这篇文章所述,responseBody实际上是个二进制结构,在IE8的Debugger里显示为“Array of Byte”。实际上这个数据结构是兼容于VB/C 中的Byte数组的,比如在VB里面我们会这样定义一个Byte数组:
Dim bytes(10) As Byte
但是js/vbs却是不支持这种数据结构的,ByteArray对于js来说只是内存中的一个特殊对象,其结构对js来说是完全透明的,脚本能够使用其内存地址来获取对其的引用,却不能操作这个透明物体。js所能做的,就是持有这个对象的地址引用,然后pass给其它可以处理该数据的组件或程序。
很多人可能一辈子都不会用到responseBody这个属性,所以有必要解释一下我为什么那么需要它。我的项目里需要实现一个机制,用servlet提供一个TIF文件流,然后客户端js应该能接收这个二进制流的数据,并将之传给一个图像浏览组件。这个流程的核心问题就是:图像浏览组件(ActiveX)只能接受ByteArray的二进制数据,故必须要想尽一切办法得到ByteArray对象。
在本人还未意识到responseBody之前,曾天真地认为:1)ByteArray是一个js能识别的Array对象;2)HttpRequest只能传输文本数据。在这种自以为是的思想指导下,我提出了第一个解决方案:
1) 在服务端Servlet取得文件流后将之byte by byte读出,然后组装成一个JSON格式的字符串,如: "[72, 43, 43, 0, 38 ...]"的形式;
2) 通过PrintWriter.print()方法把这个JSON字符串发送到客户端js的回调函数,并由该回调函数把JSON字符串转换成js数组;
3) 由于该js数组中的所有元素都是byte数据(范围在0~255内的整数),直接将该js数组作为ByteArray参数传入图像浏览组件,并显示图片。
然而,由于没有清楚认识到ByteArray的数据性质,上述的方案无疑是失败的,图像组件直接因参数类型不匹配而报错。并且,由于所有的byte都被转换成文本后才传输的,该交互行为需要的实际的网络流量远远超过了原二进制文件的容量(*见备注的换算)。
在阅读了responseBody的相关信息后,我坚信ByteArray数据是能被它接收到的,问题是Servlet应该怎样写数据才能传给responseBody一个ByteArray。首先我想到的是用response.getOutputStream(),具体代码如下:
事实证明这个试验是不成功的,到达客户端的ByteArray数据量大得惊人,对于servlet的OutputStream没什么研究,一时摸不透原因。于是,我再试了下面的代码:
其中byteArray2CharArray()方法的实现我就不写了,总之它的功能就是把一个byteArray翻译成一个charArray,各个元素的整数绝对值保持不变(在JVM里,无论是byte还是char最后都将被表示成int,但char是非负的所以采用绝对值)。这里比较怪异,试验仍然不太成功,虽然客户端responseBody接收到了一个size正确的ByteArray,里面的数据却是不正确的,因为在Buffered的读取方式下,有的byte值居然是负数,这是相当怪异的也是不正确的。接下来,一个有点“笨”的方法,居然取得了成功:
最终,这个采用PrintWriter.write(int b)的方法获得了成功,客户端拿到了正确的ByteArray数据,图像文件也得以正确还原并显示。
虽然最后一个方法取得了成功,笔者心里还是有些不舒服,因为没有用到buffer,有多少个byte就得调用多少次write(int b)方法,通过查看JDK的源代码,该方法是强制同步的,获得锁释放锁等额外开销让人无法忘怀,这样写的话性能不可能很好,目前正考虑继承PrintWriter写一个类,还望这方面有心得的朋友能一起交流一下。至于byte[]的缓冲读取方式为何出现怪异数据我还耿耿于怀,苦于没有时间再去看JBoss的实现源码,只能请有研究的朋友不吝指教了。
*备注: 例如 121 这个整数,当其类型是byte的时候,只占1个字节,而字符串"121"则会占据6个字节,因为每一个字符char都会占据2个字节。在加上连接JSON数组需要用到","作分隔符也要占据2个字节,头尾一对方括号占4个字符暂且忽略不计。因此,假设一个ByteArray里面的数据全都是(byte)121,那么当其解析成字符串后,其大小应该是源数据的约8倍,对于一个基于网络的程序来说这种缺陷是不能容忍的。
在网上问十个人,九个会告诉你XMLHttpRequest只能交互文本,实际上完全不是这样,不知道是不是因为太多的人一上手就开始用框架而不是研究HttpRequest对象的特性,但关于ResponseBody的使用几乎没有人谈及,这就有点遗憾了。首先,我找到下面一篇文章,较为详细地解释了HttpRequest对象的属性和方法:
http://blog.chinaunix.net/u2/61797/showart_1000687.html
里面的东西我就不照抄了,这里只请大家注意“属性:responseBody”这个属性的讲解。显然,只依靠JQuery的几个AJAX函数,是无法处理这种返回数据的,这种情况下,只能自己编写直接给予XMLHttpRequest的交互函数了。
根据这篇文章所述,responseBody实际上是个二进制结构,在IE8的Debugger里显示为“Array of Byte”。实际上这个数据结构是兼容于VB/C 中的Byte数组的,比如在VB里面我们会这样定义一个Byte数组:
Dim bytes(10) As Byte
但是js/vbs却是不支持这种数据结构的,ByteArray对于js来说只是内存中的一个特殊对象,其结构对js来说是完全透明的,脚本能够使用其内存地址来获取对其的引用,却不能操作这个透明物体。js所能做的,就是持有这个对象的地址引用,然后pass给其它可以处理该数据的组件或程序。
很多人可能一辈子都不会用到responseBody这个属性,所以有必要解释一下我为什么那么需要它。我的项目里需要实现一个机制,用servlet提供一个TIF文件流,然后客户端js应该能接收这个二进制流的数据,并将之传给一个图像浏览组件。这个流程的核心问题就是:图像浏览组件(ActiveX)只能接受ByteArray的二进制数据,故必须要想尽一切办法得到ByteArray对象。
在本人还未意识到responseBody之前,曾天真地认为:1)ByteArray是一个js能识别的Array对象;2)HttpRequest只能传输文本数据。在这种自以为是的思想指导下,我提出了第一个解决方案:
1) 在服务端Servlet取得文件流后将之byte by byte读出,然后组装成一个JSON格式的字符串,如: "[72, 43, 43, 0, 38 ...]"的形式;
2) 通过PrintWriter.print()方法把这个JSON字符串发送到客户端js的回调函数,并由该回调函数把JSON字符串转换成js数组;
3) 由于该js数组中的所有元素都是byte数据(范围在0~255内的整数),直接将该js数组作为ByteArray参数传入图像浏览组件,并显示图片。
然而,由于没有清楚认识到ByteArray的数据性质,上述的方案无疑是失败的,图像组件直接因参数类型不匹配而报错。并且,由于所有的byte都被转换成文本后才传输的,该交互行为需要的实际的网络流量远远超过了原二进制文件的容量(*见备注的换算)。
在阅读了responseBody的相关信息后,我坚信ByteArray数据是能被它接收到的,问题是Servlet应该怎样写数据才能传给responseBody一个ByteArray。首先我想到的是用response.getOutputStream(),具体代码如下:
File file = new File("c:\\001.tif"); InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); OutputStream out = response.getOutputStream(); int b = 0; int len = 0; byte[] buf = new byte[1024]; while ((len = bis.read(buf)) != -1) { out.write(buf, 0, len); } out.flush(); out.close(); bis.close();
事实证明这个试验是不成功的,到达客户端的ByteArray数据量大得惊人,对于servlet的OutputStream没什么研究,一时摸不透原因。于是,我再试了下面的代码:
File file = new File("c:\\001.tif"); InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); PrintWriter out = resp.getWriter(); byte[] buf = new byte[1024]; int len = 0; try { while ((len = in.read(buf)) != -1) { char[] cbuf = byteArray2CharArray(buf); write(cbuf, 0, len); out.flush(); } } catch (IOException ex) { ex.printStackTrace(); }
其中byteArray2CharArray()方法的实现我就不写了,总之它的功能就是把一个byteArray翻译成一个charArray,各个元素的整数绝对值保持不变(在JVM里,无论是byte还是char最后都将被表示成int,但char是非负的所以采用绝对值)。这里比较怪异,试验仍然不太成功,虽然客户端responseBody接收到了一个size正确的ByteArray,里面的数据却是不正确的,因为在Buffered的读取方式下,有的byte值居然是负数,这是相当怪异的也是不正确的。接下来,一个有点“笨”的方法,居然取得了成功:
File file = new File("c:\\001.tif"); InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); PrintWriter out = resp.getWriter(); int b = 0; while ((b = bis.read()) != -1) { out.write(b); } out.flush(); out.close(); bis.close();
最终,这个采用PrintWriter.write(int b)的方法获得了成功,客户端拿到了正确的ByteArray数据,图像文件也得以正确还原并显示。
虽然最后一个方法取得了成功,笔者心里还是有些不舒服,因为没有用到buffer,有多少个byte就得调用多少次write(int b)方法,通过查看JDK的源代码,该方法是强制同步的,获得锁释放锁等额外开销让人无法忘怀,这样写的话性能不可能很好,目前正考虑继承PrintWriter写一个类,还望这方面有心得的朋友能一起交流一下。至于byte[]的缓冲读取方式为何出现怪异数据我还耿耿于怀,苦于没有时间再去看JBoss的实现源码,只能请有研究的朋友不吝指教了。
*备注: 例如 121 这个整数,当其类型是byte的时候,只占1个字节,而字符串"121"则会占据6个字节,因为每一个字符char都会占据2个字节。在加上连接JSON数组需要用到","作分隔符也要占据2个字节,头尾一对方括号占4个字符暂且忽略不计。因此,假设一个ByteArray里面的数据全都是(byte)121,那么当其解析成字符串后,其大小应该是源数据的约8倍,对于一个基于网络的程序来说这种缺陷是不能容忍的。
第一种方法你提到的数据量大的惊人,我基本上可以猜到什么原因了
你用的是ie看的吧,而且你没有告诉ie你数据流的格式是什么,ie当成图片来处理,你看到的实际上是经过ie转换后的bmp
你只需要在你的head上设置contenttype为image/tiff
建议你再额外设置content length
19 楼
oxromantic
2009-11-20
jeff312 写道
myy 写道
jeff312 写道
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
你的意见我正在考虑,在向ActiveX供应商寻求支持时,那边的回答就是只能拿实际文件而不能拿servlet二进制流。你这一说,我开始怀疑他们是否对此有过测试。谢谢提示。
供应商瞎扯蛋,tomcat静态文件也是通过servlet传送给客户端的, DefaultServlet
你可以尝试下跟踪应答头,看看你缺少了什么
18 楼
ahuango
2009-11-20
既然用int 可以正确输出到client端,为什么不能用buffer writer 来输出呢
17 楼
jeff312
2009-11-20
myy 写道
jeff312 写道
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
你的意见我正在考虑,在向ActiveX供应商寻求支持时,那边的回答就是只能拿实际文件而不能拿servlet二进制流。你这一说,我开始怀疑他们是否对此有过测试。谢谢提示。
16 楼
jeff312
2009-11-20
weiqingfei 写道
jeff312 写道
karlmax 写道
既然http://host_name:8080/AppName/images/001.tif可以用,那么http://host_name:8080/AppName/SomeServlet?fileId=30就没有理由不成。可以尝试一下URL rewriting,如果不成看一下SomeServlet的respons header是否正确设置了content type等。
这恐怕跟服务器端的stream的类型和方式有关,我也试过用byte[]缓冲输出流(缓冲区byte[]得到数据后,把它编码成相应的char[]),诡异的是,浏览器端收到了正确的二进制数据,但IE却随后立即崩溃了。以IO流输出文件只怕与实际文件地址URL读取还是有区别的,区别在哪里还要请人指教。
有区别也是服务器端没设置好,查看一下响应头,就知道哪儿不同了。
多谢提示,我就去研究一下响应头。
15 楼
jeff312
2009-11-20
lzyzizi 写道
刚才去看了下TOMCAT 4的源码,发现PrinterWriter其实也就是包装了OutputStreamWriter,而OutputStreamWriter(这个类代理了sun.nio.cs.StreamEncoder)包装了getOutputStream(返回ServletOutputStream),而ServletOutputStream应该是来自socket.getOutputStream()。在tomcat里,他们的提交最后都交给RequestBase.write方法。不过我不清楚JBOSS怎么实现的。。。
也就是说PrintWriter相对于ServletOutputStream多了一层OutputStreamWriter
虽然想不明白那3种状况是为什么,但对于楼主的问题还是挺好奇的。
不过对于楼主的第二种方案,不知道楼主有没有试过直接将byte cast成 char
char c = (char)b;然后把char数组传到客户端去呢?
也就是说PrintWriter相对于ServletOutputStream多了一层OutputStreamWriter
虽然想不明白那3种状况是为什么,但对于楼主的问题还是挺好奇的。
不过对于楼主的第二种方案,不知道楼主有没有试过直接将byte cast成 char
char c = (char)b;然后把char数组传到客户端去呢?
你倒是提醒了我,其实JBoss的servlet实现就是Tomcat的实现,JBoss现在把Tomcat当成一个子集,专门处理web/servlet请求。
第二个方案的代码中我省略了byteArray2CharArray()方法的代码,实现上跟你的设想其实没多大差别,而这正是我在主帖里对方案二描述的故障的源头。实际上从byte到char的解码编码没那么简单,强制转换是行不通的,实际上,b会先被转换成有符号int,然后才会转成char,这样一来就麻烦了,因为char是无符号的,当中间int数据是负数的时候,char的结果就会出错。比较正确简洁的代码如下:
charArray = new String(byteArray).toCharArray();
当然,即使通过转换使得char数组得到了正确的二进制数据,方案仍然行不通,因为IE虽然接到了正确的数据,却突然离奇崩溃了,正在考虑一些跟帖网友的建议,试一试resp.reset()之类的办法。
14 楼
weiqingfei
2009-11-19
jeff312 写道
karlmax 写道
既然http://host_name:8080/AppName/images/001.tif可以用,那么http://host_name:8080/AppName/SomeServlet?fileId=30就没有理由不成。可以尝试一下URL rewriting,如果不成看一下SomeServlet的respons header是否正确设置了content type等。
这恐怕跟服务器端的stream的类型和方式有关,我也试过用byte[]缓冲输出流(缓冲区byte[]得到数据后,把它编码成相应的char[]),诡异的是,浏览器端收到了正确的二进制数据,但IE却随后立即崩溃了。以IO流输出文件只怕与实际文件地址URL读取还是有区别的,区别在哪里还要请人指教。
有区别也是服务器端没设置好,查看一下响应头,就知道哪儿不同了。
13 楼
myy
2009-11-19
jeff312 写道
2. URL直接给图像组件。这个实际上原来开发包里就有这个功能,但是它只能下载实际存在的图像文件,比如这样的URL: http://host_name:8080/AppName/images/001.tif ,如果是 http://host_name:8080/AppName/SomeServlet?fileId=30 这样的URL,它是不起作用的。但是我不清楚是ActiveX的http请求都有这个限制还是说仅仅是我手头这个开发包的功能缺陷?
请指教。
不可能静态URL可以而动态不行,客户端应该只认数据格式,不会管你后台是如何生成的(否则生成图形验证码的程序如何实现?),应该是你写的“SomeServlet”有问题!
不一定Servlet,用jsp也可以直接输出byte array的,但要注意,在输出之前,要:
response.reset();
out.clear();
12 楼
penciltim
2009-11-19
有些浏览器不支持的,输出的可能是一堆乱码
加个resp.setContentType好点。
加个resp.setContentType好点。
11 楼
lzyzizi
2009-11-19
刚才去看了下TOMCAT 4的源码,发现PrinterWriter其实也就是包装了OutputStreamWriter,而OutputStreamWriter(这个类代理了sun.nio.cs.StreamEncoder)包装了getOutputStream(返回ServletOutputStream),而ServletOutputStream应该是来自socket.getOutputStream()。在tomcat里,他们的提交最后都交给RequestBase.write方法。不过我不清楚JBOSS怎么实现的。。。
也就是说PrintWriter相对于ServletOutputStream多了一层OutputStreamWriter
虽然想不明白那3种状况是为什么,但对于楼主的问题还是挺好奇的。
不过对于楼主的第二种方案,不知道楼主有没有试过直接将byte cast成 char
char c = (char)b;然后把char数组传到客户端去呢?
也就是说PrintWriter相对于ServletOutputStream多了一层OutputStreamWriter
虽然想不明白那3种状况是为什么,但对于楼主的问题还是挺好奇的。
不过对于楼主的第二种方案,不知道楼主有没有试过直接将byte cast成 char
char c = (char)b;然后把char数组传到客户端去呢?
10 楼
whaosoft
2009-11-19
responseBody 这个属性确实不太常用
发表评论
-
发挥抽象事务的威力——深入Spring事务管理
2012-05-07 03:07 0事务管理(Transaction Management ... -
可能是世界上最简单的web server的java实现 (源码)
2011-11-24 15:34 2111J2EE 写了好些年,各种we ... -
Linux 下运行tomcat的 “BASEDIR” 错误
2011-06-22 15:44 4548昨天需要将公司的Hudson从Windows2008服务器移植 ... -
系统缓存的透明化设计
2011-06-17 18:45 0下面是我在研究了一下本公司产品的缓存设计后所做的一些归 ... -
Scala 学习感想(持续更新)
2011-04-06 11:09 1626有一点写一点,不成章法,没有顺序。 Traits 的意义:j ... -
如何国际化GWT-EXT 的MessageBox
2011-04-04 12:32 2918这是工作中偶然碰到的 ... -
更新常量后,请重新编译你的class
2009-12-29 12:39 1204一些朋友可能喜欢这样做,程序中使用的各种常量用一个类来 ... -
更新常量后,请重新编译你的class
2009-12-29 12:38 1715一些朋友可能喜欢这样做,程序中使用的各种常量用一个类来 ... -
JVM原理学习笔记(二) —— 虚拟机规范
2009-10-20 13:14 1661最近在阅读 《Inside the JVM》 这本书, ... -
Web小经验:使用Servlet实现文件下载的时候,避免浏览器自动打开文件
2009-10-19 12:31 5111遇到这个问题的人很多,大致情形如下: 1. 客户端向servl ... -
JVM原理学习笔记(一)
2009-10-19 01:41 1545最近在阅读 《Inside the JVM》 这本书, ... -
为什么是Hibernate —— 我的菜鸟系统设计回顾 (1)
2009-10-16 19:12 0如果不出意外,这将只是该系列文章的第一篇,希望我能有足 ... -
关于用 ThreadLocal 管理 Connection 的一些总结
2009-10-01 14:26 6200随着Hibernate3的流 ... -
收集了一些URI特殊字符的编码,有一些想法
2009-09-15 19:28 4328先把资料列一下, 字符 URL编码值 ... -
部署EJB一定要仔细观察应用服务器的控制台消息
2009-07-13 23:48 1352EJB 的部署一向是个头疼的问题,在部署行为和默认设置 ... -
从C++语法角度理解Java线程锁
2009-07-01 11:46 1831做WEB应用不可能不接触 ... -
微型项目,EJB还是Hibernate?
2009-06-17 17:38 1002本人前一段收到任务,负责独立设计开发一个微型系统作为现有 DM ... -
使用 Local 与 LocalHome 访问 EJB 组件 -- 解惑篇
2008-11-19 15:33 3593这个年代还在写EJB ...
相关推荐
HttpRequest对象使用Ajax技术的详细步骤
HttpRequest是网络编程中一个重要的概念,它主要用于发送HTTP请求到服务器获取或提交数据。在本文中,我们将深入探讨HttpRequest的工作原理、主要功能以及如何在实际应用中使用它,特别是通过ASIHttpRequst这个库来...
本文将详细介绍HttpRequest对象的使用方法,包括路径参数、QueryDict对象、请求体的处理和请求头信息的获取。 首先,HttpRequest对象提供了路径参数的获取方法。路径参数是在URL路径中定义的参数,可以通过在URL...
主要介绍了Java中使用HttpRequest获取用户真实IP地址,使用本文方法可以避免Apache、Squid、nginx等反向代理软件导致的非真实IP地址,需要的朋友可以参考下
#### 二、路径获取方法详解 ##### 1. `getRealPath` - **描述**:用于获取服务器上的实际物理路径。 - **示例**: - `request.getSession().getServletContext().getRealPath("/")` - `this.getServletContext()...
GET方法简单、直观,适合获取少量无副作用的数据,而POST方法更适合需要发送大量数据或者需要改变服务器状态的操作,比如用户注册、商品购买等。 在实际开发中,我们还需要处理响应。如示例代码所示,通过`httpReq....
4. **处理响应**:当请求成功返回时,可以解析响应的二进制数据,将其保存为图片文件或直接显示在QML的`Image`组件上。如果需要自定义标记或覆盖物,可以通过在URL中添加额外的参数实现。 在实际应用中,可能还需要...
- BinaryRead:读取输入流的二进制数据。 - SaveAs:将请求保存到磁盘。 - MapPath:将虚拟路径转换为物理路径。 接下来是Response对象,它是System.Web.HttpResponse类的实例,负责将服务器的响应发送回客户端...
Cocos2d-x提供了一些图像处理类,如Image和Texture2D,可以帮助我们将二进制数据转换成可以使用的图像资源。 ```cpp auto response = static_cast*>(sender); if (response && response->isSucceed()) { auto& ...
ASP.NET中的`HttpRequest`对象提供了`UserHostAddress`属性,可以获取到客户端的IP地址。然后,我们可以使用`System.Net.Dns`类的`GetHostEntry()`方法,传入客户端的IP地址,从而得到一个`IPHostEntry`对象,这个...
首先,我们需要理解VB中的WebClient类或HttpRequest对象是获取网页数据的关键工具。WebClient类提供了一个简单的方法来下载Web资源,而HttpRequest对象则允许我们发送HTTP请求并接收响应。 1. **使用WebClient类...
在C#中,可以通过设置HttpRequest对象的Url属性,然后使用GetResponse()方法发送请求并获取响应。 3. **POST请求**:POST请求常用于向服务器提交数据,如表单数据或文件。在C#中,可以通过HttpWebRequest对象的...
总结,HTTPrequest是Web开发的基础,GET和POST是其核心方法,用于获取和提交数据。理解并熟练运用这些概念对于任何Web开发者都至关重要。无论你是创建动态网页、API接口,还是进行数据交互,都需要掌握HTTP请求的...
接着,我们使用ResponseText来获取抓取的数据,并将其存储在变量中。最后,我们使用MsgBox来显示抓取的数据。 应用于股票价格数据 在本文中,我们将应用抓取的HTML数据来实现股票价格数据的自动更新。首先,我们将...
然后,根据`ImageContentType`创建一个`MemoryStream`,将二进制数据写入`MemoryStream`,再用`HttpPostedFile`的`WriteTo`方法将`MemoryStream`的内容写回HTTP响应,这样浏览器就能显示图片了。 6. **安全性与性能...
C#的wpf客户端使用HttpWebRequest模拟网页表单提交数据到Java的web服务端,Java服务端使用commons-fileupload.jar,Spring接受数据。 ********************************** *该程序可以同时提交表单数据和上传文件* ...
在描述中,提到"HttpRequest程序idea2017测试通过,通过HTTP Request获取数据",这暗示了该项目使用HttpRequest类实现了HTTP的GET和POST方法,能够在Java环境中发送HTTP请求,获取服务器响应的数据。Idea2017是...
【HttpRequest-Reptile-master】项目是一个基于Java的爬虫应用,使用了HttpRequest库来实现对网页数据的抓取。这个项目在IDEA2017集成开发环境中已经成功测试运行,意味着它兼容Java 8及以上版本。让我们深入探讨...