- 浏览: 207785 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (107)
- java网络通信(rmi,hessian,nio...) (4)
- java基础 (25)
- java压缩和解压缩 (1)
- 开发框架整合 (7)
- struts2.0 (3)
- 构建工具(ant,maven..) (1)
- web容器配置(tomcat,weblogic,nginx...) (3)
- hibernate (8)
- 业务(项目管理,项目设计相关) (5)
- 数据库(oracle,mysql..) (7)
- linux命令 (6)
- java网络通信(rmi (6)
- hessian (6)
- nio...) (6)
- 数据库(oracle (4)
- mysql..) (4)
- ibatis (2)
- 多线程 (1)
- Windows Install Clean Up 卸载JDK (1)
- IETEST (1)
- UML 类图 关系 (1)
- java基础 spring (2)
- NFS SFU (1)
- jmap mat jps (1)
- 架构 (1)
- 统一管理 (0)
- 项目管理 (1)
- 图片预加载 (1)
- 代码高亮 (1)
- 同步 (1)
- 权限管理 (0)
- ehcache ibatis (1)
- jd-gui proguard (1)
- portmon (1)
- procexp (1)
- mysql (1)
- NIO 内存映射文件 (1)
- web容器配置(tomcat (1)
- weblogic (1)
- nginx...) (1)
- WEB (1)
- html (1)
- javascript (1)
- iOS pods (1)
最新评论
-
vrbvillor:
我的QQ是245614005。如果您可以帮我的话,请发邮件或联 ...
mysql存储过程中使用动态SQL,并且返回值 -
vrbvillor:
大侠,请教一个问题。我想在mysql的function里边 ...
mysql存储过程中使用动态SQL,并且返回值 -
newslxw:
ppgunjack 写道关键要弄清楚,UAT用例是谁提供,谁评 ...
做到客户满意为止(项目成本控制相关主题) -
萧十一狼:
所有dao类都继承com.ibatis.sqlmap.clie ...
spring+ibatis整合方法 -
adss101:
一般项目就这块比较难控制,,弄不好就死在这了,,客户要求,对于 ...
做到客户满意为止(项目成本控制相关主题)
首先,实现自动上传文件方式有很多种,其中就有 SOCKET , RMI , HTTP 等,考虑到服务器本身是个网站服务器,使用 SOCKET 和 RMI 需要单独开发端口, HTTP 则可以直接融合到网站中,也没有特殊的要求,所以采用了 HTTP 方式。 HTTP 方式又有好几种,其中就有 hessian 和 HttpUrlConnection 。使用 hessian 的话, hessian 提供的流上传有缺陷,可能会导致内存溢出,因此只能是将文件以多个字节数组方式传输到服务器,然后程序再整合字节成完整文件,无疑增加了代码复杂度。所以最终选择了 HttpUrlConnection 。
通过 HttpUrlConnection 自动上传文件,服务端和用户通过网页上传文件到服务器的程序一模一样,只是客户端,我们用 HttpUrlConnection 来代替浏览器向服务器提交数据。因此我们首先要弄清楚浏览器发送数据的格式。
第1步,数据格式:
发送文件, method 是 POST ; multipart/form-data ;我们通过 firefox 的 firebug 查看具体上传
下面数据是 iteye 上上传一个空文件是的 firebug 提交的数据。
文件格式如下:
head
Content-Length 357 Content-Type multipart/form-data; boundary=---------------------------41184676334
body
-----------------------------41184676334 Content-Disposition: form-data; name="authenticity_token" vggMNy0klrhNiSh9bQkSYeN/c3tx11I/lS0T7YDpc9U= -----------------------------41184676334 Content-Disposition: form-data; name="attachment[uploaded_data]"; filename="test.zip" Content-Type: application/zip -----------------------------41184676334—
格式解析:
Content-Length 定义了发送数据的总字节数;
Content-Type 定义格式和数据分界符 boundary ,下面发送的数据将用这个 boundary 分隔每一个变量, boundary 中的 41184676334 是由浏览器随机生成,我们可以直接使用 。
发送 2 个变量,分别是 authenticity_token 和空文件 test.zip
变量开头是 “--”+boundary ,然后下一行 Content-Disposition 定义变量名称,下一行是 content-type 定义数据格式,这个不是必须的,发送文件数据时, content-type 需要指定,
这里指出了文件类型,我们可以用 application/octet-stream 告诉服务器发送的是流,再空两行(即 \r\n\r\n ),是变量的值或者文件的内容。然后下一行开始是另外一个变量。最后一个变量以 “—“+boundary+”—“ 结束。
第2步 HTTPS 处理
有时候网站采用的是 HTTPS 协议,因此我们需要相应的证书,我们考虑是让程序接受所有证书,就像浏览器上设置接受所有证书,不管签名与否。实际是我们也无需证书,服务器也是我们自己的,我当然相信自己编写的客户端当然也相信自己的服务端了。
要接受所有服务器上的证书,我们需要实现两个接口
javax.net.ssl.X509TrustManager 和 javax.net.ssl.HostnameVerifier
接口中的函数都以空函数覆盖即可。其中 javax.net.ssl.HostnameVerifier 的 verify 返回 true 即可。下面是我们连接服务器的函数
HttpURLConnection getHttpConnection(String urlString) throws Exception { URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); if ("https".equalsIgnoreCase(url.getProtocol())) { HttpsURLConnection httpsConn=(HttpsURLConnection) conn; TrustManager[] managers ={new MyX509TrustManager()}; SSLContext sslContext=SSLContext.getInstance("TLS"); sslContext.init(null, managers, new SecureRandom()); SSLSocketFactory ssf=sslContext.getSocketFactory(); httpsConn.setSSLSocketFactory(ssf); httpsConn.setHostnameVerifier(new MyHostnameVerifier()); return httpsConn; } else { return conn; } }
其中 MyX509TrustManager 和 MyHostnameVerifier 分别是
javax.net.ssl.X509TrustManager 和 javax.net.ssl.HostnameVerifier 的实现类。
第 3 步,发送数据
连接了服务器,就可以发送数据了。
首先定义连接的
header
和连接方式和
boundary
conn = getHttpConnection(urlString); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); String BOUNDARY = "---------------------------41184676334"; conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("Charsert", "UTF-8"); conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0"); //可以不指定 conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); conn.setRequestProperty("Content-Length", String.valueOf(contentLen)); //不清楚长度,可以不写 conn.setAllowUserInteraction(false); //无需用户交互,即弹出https等的对话框。 conn.setChunkedStreamingMode(blockSize); //告诉HttpUrlConnection,我们需要采用流方式上传数据,无需本地缓存数据。HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。 byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(); StringBuffer sb = new StringBuffer(); sb.append("--").append(BOUNDARY).append("\r\n"); sb.append("Content-Disposition: form-data; name=\"username\"\r\n\r\n"); sb.append(username); sb.append("\r\n--").append(BOUNDARY).append("\r\n"); sb.append("--").append(BOUNDARY).append("\r\n"); sb.append("Content-Disposition: form-data; name=\"password\"\r\n\r\n"); sb.append(password); sb.append("\r\n--").append(BOUNDARY).append("\r\n"); sb.append("--").append(BOUNDARY).append("\r\n"); sb.append("Content-Disposition: form-data; name=\"file\"; filename=\identify.zip\"\r\n"); sb.append("Content-Type: application/octet-stream\r\n\r\n"); byte[] data = sb.toString().getBytes(); long fLen = f.length(); long contentLen = data.length + fLen + end_data.length; os.write(data); //发送非文件数据 fis = new FileInputStream(f); //读取文件内容,发送数据,数据要一点点发送,不能一下全部读取发送,否则会内存溢出。 int rn; byte[] buf = new byte[blockSize]; while ((rn = fis.read(buf, 0, blockSize)) > 0) { os.write(buf, 0, rn); } os.write(end_data); os.flush(); os.close(); fis.close();
第 4 步,接受服务器处理结果
ByteArrayOutputStream bo = new ByteArrayOutputStream(); InputStream is = conn.getInputStream(); byte[] inbuf = new byte[blockSize/10]; while ((rn = is.read(inbuf, 0, blockSize/10)) > 0) { bo.write(inbuf); } is.close(); String ret = bo.toString(); bo.close();
发表评论
-
MappedByteBuffer小结
2012-07-28 17:27 1540java的内存映射文件有如下特点: 1,使用虚拟内存, ... -
jstat 详解
2012-07-28 12:56 891jstat 详解 jstat ... -
NIO的内存映射文件一些问题
2012-07-28 12:51 1154见 http://yipsilon.iteye.com/bl ... -
Permanent会被GC
2012-04-23 17:27 783http://fallenlord.blogbus.c ... -
JVM内存分析工具
2011-11-28 17:17 1204参考 jvm内存分解: ... -
JVM内存解析
2011-11-28 17:10 824参考: http://vanadiumlin.iteye.c ... -
基本类型的初始化值
2011-11-28 11:05 926各基本类型在没初始化时,默认如下值 boolean init ... -
多线程笔记
2011-11-28 10:47 8041、synchronized以线程为单位,不是以调用为单位,通 ... -
B/S系统打印
2011-11-10 17:00 1278B/S系统打印都很费劲,到目前我还没找到一个完善的方法,以下是 ... -
在文件中间插入数据
2011-11-10 15:55 1008目前没有什么好方法能直接在文件中间插入数据. 都是采用先将插 ... -
将JAR打包成EXE,并且生成安装文件
2011-11-10 15:21 2587桌面程序项目完成后,需要将项目打包成安装包在WINDOWS下运 ... -
卸载JDK导致applet不能显示
2011-11-09 17:59 827最近做测试,需要卸载JDK,卸载后发现JAVA UPDATE不 ... -
多线程下谨慎对待基类(抽象类)中的成员变量
2011-07-06 22:13 2341有这么个需求: 做开发 ... -
wait和notify使用方法
2011-07-05 13:47 1166原则是: 调用wait的对象必须是synchronized中的 ... -
SimpleDateFormat在多线程下不安全
2011-07-05 13:42 2040在工具类中有2个时间格式化和字符串转换成时间的函数,使用了类静 ... -
java计算两个日期间隔方法
2011-06-24 16:55 2748SimpleDateFormat formatter = ... -
jtable选中指定的行和选中事件监听
2011-06-16 18:49 11226选中行 table.getSelectionModel().s ... -
监听jtable单元格内容改变事件
2011-06-16 18:45 7495对话框监听jtable内容是否改变,改变后,在用户退出时提示是 ... -
自定义jtable单元格显示方式
2011-06-16 18:41 1521自定义jtable显示方式,需要继承DefaultTableC ... -
自定义jtable单元格编辑器
2011-06-16 18:35 3564jtable每行每列的单元格的编辑器都可以自定义, 方法如下: ...
相关推荐
用于模拟浏览器访问网页,抓取站点源文件。... * version 1.0.0_00,支持POST数据,支持SSL,支持上传文件。 * GET、POST方式无需设置自动判断。 * 代码经过优化和修理。 【API简介】
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
4.10 心爱小宝贝相片集——Gallery与衍生BaseAdapter容器 4.11 快速的搜索手机文件引擎——JavaI/O的应用 4.12 按钮也能随点击变换——ImageButton选择特效 4.13 具自动提示功能的菜单——AutoCompleteTextView与...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——...
11.3.4 文件上传 11.4 HttpClient 11.4.1 HttpGet请求 11.4.2 HttpPost请求 11.5 本章小结 第12章 数据解析 12.1 XML 12.1.1 DOM 12.1.2 SAX 12.1.3 PULL 12.2 JSON格式 12.2.1 基本类型 12.2.2 数组和集合 12.2.3 ...