分享
 
 
 

将文件通过http的post方法上传到服务器

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

这实际上是模仿浏览器的post行为,问题的提出是本人在做一个企业内部网络的项目的时候,该企业网络与Internet是通过一台HP-UNIX的服务器连接的,项目需要经常从互联网传送一些文本文件到内部网络的一台Web服务器,我们只能够通过那台HP-UNIX的主机进去,当时内网的Web服务器用的是DotNet框架,很容易的写好了文件上传的Web界面。这就麻烦了,我不能够用浏览器直接访问该文件上传页面,所以就只好用Java写了个模仿浏览器上传文件的程序。

环境:

内网Web服务器:Windows2000+DotNet Framework1.0

外网主机:HP-UNIX(具体什么版本号忘记了)、jdk1.4

首先、我们解决容易的问题,我们知道asp.net的文件上传功能封装得非常完美。很轻松我们就写好了如下上传页面(命名为TestFileManager.aspx):

<%@ Page Language="c#" CodePage="936" %>

<%@ import Namespace="System" %>

<%@ import Namespace="System.IO" %>

<script runat="server">

void Page_Load(Object sender, EventArgs e) {

}

void Button1_Click(Object sender, EventArgs e) {

//判断选取对话框选取的文件长度是否为0

Label1.Text="Clicked";

//因为我的项目中用的只是xml文件,所以有此判断

if (uploadfile1.PostedFile.ContentLength != 0 && uploadfile1.PostedFile.FileName.ToLower().EndsWith(".xml")) {

try{

string strFileName = uploadfile1.PostedFile.FileName;

string[] strTemp = strFileName.Split(new char[]{'\\'});

strFileName = "C:\\"+strTemp[strTemp.Length-1];

uploadfile1.PostedFile.SaveAs(strFileName);

Label1.Text="测试文件" + strFileName + "上传成功! ";

}

catch (Exception exp)

{

Label1.Text = exp.StackTrace;

}

}

}

</script>

<html>

<head>

<title>逻辑层测试管理</title>

</head>

<body>

<form method="post" enctype="multipart/form-data" runat="server">

<p>

<input id="uploadfile1" type="file" size="49" runat="server" />

<asp:Button id="Button1" onclick="Button1_Click" runat="server" Text="上传"></asp:Button>

</p>

<p>

<asp:Label id="Label1" runat="server" Width="459px"></asp:Label>

</p>

<!-- Insert content here -->

</form>

</body>

</html>

这个上传页面应该没什么好说的了,我们看看它将产生的html页面内容:

<html>

<head>

<title>逻辑层测试管理</title>

</head>

<body>

<form name="_ctl0" method="post" action="TestFileManager.aspx" id="_ctl0" enctype="multipart/form-data">

<input type="hidden" name="__VIEWSTATE" value="dDwyNTIzNjA5NDU7Oz7rsE3eBYzQHDVtl+aTn96MvQW6PQ==" />

<p>

<input name="uploadfile1" id="uploadfile1" type="file" size="49" />

<input type="submit" name="Button1" value="?" id="Button1" />

</p>

<p>

<span id="Label1" style="width:459px;"></span>

</p>

<!-- Insert content here -->

</form>

</body>

</html>

上面有一段<input type="hidden" name="__VIEWSTATE" value="dDwyNTIzNjA5NDU7Oz7rsE3eBYzQHDVtl+aTn96MvQW6PQ==" />这是它产生的相当于Session的一个值,这个值将对我们的上传程序产生比较大的影响。

接着我们来写Java上传的程序,这里要说明一点,我没有用j2se的网络包,并不是现有的网络包不行,因为当时我正好在玩sun的BRAZIL PROJECT(http://www.sun.com/2000-0822/brazil/),感觉挺精巧的,所以就用上了brazil的网络功能。

import java.io.*;

import org.w3c.dom.*;

import org.xml.sax.*;

import javax.xml.parsers.*;

import sunlabs.brazil.util.*;

import sunlabs.brazil.util.http.*;

/**

* 该类实现上传xml测试文件到逻辑层

*

*/

public class TestFileManager {

/**

* 提取XML一个节点的属性值

* @node XML节点对象

* @strName 属性名称

* @return 节点的属性值

*/

private static String getNodeAttributeValue(Node node, String strName) {

NamedNodeMap nmap = node.getAttributes();

Node tmpnode = nmap.getNamedItem(strName);

String rtStr = "";

if ( tmpnode != null ) {

rtStr = tmpnode.getNodeValue().trim();

}

return rtStr;

}

public static void main(String[] args){

if ( args.length < 1 ) {

System.out.println("Usage: java TestFileManager xmlfilelist");

System.exit(0);

}

try {

HttpRequest request = new HttpRequest("http://192.9.200.108:80/OnlineService/TestFileManager.aspx");

request.setMethod("GET");

request.setRequestHeader("Cache-Control", "no-cache");

request.setRequestHeader("Connection", "Keep-Alive");

request.setRequestHeader("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

request.setRequestHeader("Accept-Encoding", "gzip, deflate");

request.setRequestHeader("Accept-Language", "en-au");

request.setRequestHeader("Referer", "http://rookie/OnlineService/TestFileManager.aspx");

request.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3215; .NET CLR 1.0.3705)");

request.connect();

String strCookie = request.getResponseHeader("Set-Cookie");

strCookie = strCookie.substring(0,strCookie.indexOf(";"));

DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();

DocumentBuilder parser =dbfactory.newDocumentBuilder();

String strTemp = request.getContent();

Document xmldoc = parser.parse(new InputSource(new StringReader(strTemp)));

NodeList nlist = xmldoc.getElementsByTagName("input");

Node node;

String strName = "";

String strValue = "";

for ( int i = 0; i < nlist.getLength(); i++) {

node = nlist.item(i);

strName = getNodeAttributeValue(node,"name");

if ( strName.equals("__VIEWSTATE") ) {

strValue = getNodeAttributeValue(node,"value");

break;

}

}

request.close();

request = null;

String strBoundary = null;

String strFileName = null;

BufferedInputStream bis = null;

byte[] data = null;

for ( int i=0; i<args.length;i++ ) {

try {

strBoundary = new String(""+(Math.random()+Math.random())).substring(2);

strFileName = args[i];

bis = new BufferedInputStream(new FileInputStream(strFileName));

data = new byte[bis.available()];

bis.read(data, 0, data.length);

bis.close();

System.out.println("上传文件 " + strFileName + "...");

request = new HttpRequest("http://192.9.200.108:80/OnlineService/TestFileManager.aspx");

request.setMethod("POST");

request.setRequestHeader("Cache-Control", "no-cache");

request.setRequestHeader("Connection", "Keep-Alive");

request.setRequestHeader("Content-Type", "multipart/form-data; boundary=---------------------------"+strBoundary);

request.setRequestHeader("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

request.setRequestHeader("Accept-Encoding", "gzip, deflate");

request.setRequestHeader("Accept-Language", "en-au");

request.setRequestHeader("Cookie", strCookie);

request.setRequestHeader("Host", "rookie");

request.setRequestHeader("Referer", "http://rookie/OnlineService/TestFileManager.aspx");

request.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3215; .NET CLR 1.0.3705)");

DataOutputStream dos = new DataOutputStream(request.getOutputStream());

dos.writeBytes("-----------------------------"+strBoundary);

dos.writeBytes("\r\nContent-Disposition: form-data; name=\"__VIEWSTATE\"");

dos.writeBytes("\r\n\r\n"+strValue);

dos.writeBytes("\r\n-----------------------------"+strBoundary);

dos.writeBytes("\r\nContent-Disposition: form-data; name=\"uploadfile1\"; filename=\"" + strFileName + "\"");

dos.writeBytes("\r\nContent-Type: text/xml");

dos.writeBytes("\r\n\r\n");

dos.writeBytes(new String(data));

dos.writeBytes("\r\n-----------------------------"+strBoundary);

dos.writeBytes("\r\nContent-Disposition: form-data; name=\"Button1\"");

dos.writeBytes("\r\n上传");

dos.writeBytes("\r\n-----------------------------"+strBoundary+"--");

dos.writeBytes("\r\n");

dos.close();

request.connect();

request.close();

request = null;

System.out.println("文件 " + strFileName + " 上传成功.");

} catch (FileNotFoundException e) {

System.out.println("文件 " + strFileName + " 未找到.");

} catch (Exception e) {

e.printStackTrace();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

下面我详细讲解main方法中的具体过程

首先创建一个到服务器http的请求

HttpRequest request = new HttpRequest("http://192.9.200.108:80/OnlineService/TestFileManager.aspx");

第一次使用的是GET方式

request.setMethod("GET");

紧接着进行一些请求的属性设置

request.setRequestHeader("Cache-Control", "no-cache");

这里保持连接,因为后面还要发送数据到服务器呢

request.setRequestHeader("Connection", "Keep-Alive");

下面是一些无关紧要的属性设置了。

request.setRequestHeader("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

request.setRequestHeader("Accept-Encoding", "gzip, deflate");

request.setRequestHeader("Accept-Language", "en-au");

request.setRequestHeader("Referer", "http://rookie/OnlineService/TestFileManager.aspx");

request.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3215; .NET CLR 1.0.3705)");

构造好了连接请求,然后连接

request.connect();

紧接着提取Cookie值,在后文的post中可以用到。

String strCookie = request.getResponseHeader("Set-Cookie");

strCookie = strCookie.substring(0,strCookie.indexOf(";"));

下面通过循环查找,提取__VIEWSTATE的值,这个值是不能捏造的,每个新的get取得的是不一样的。

for ( int i = 0; i < nlist.getLength(); i++) {

node = nlist.item(i);

strName = getNodeAttributeValue(node,"name");

if ( strName.equals("__VIEWSTATE") ) {

strValue = getNodeAttributeValue(node,"value");

break;

}

}

往服务器组织发送数据

DataOutputStream dos = new DataOutputStream(request.getOutputStream());

dos.writeBytes("-----------------------------"+strBoundary);//这是每个要被发送数据间的间隔

dos.writeBytes("\r\nContent-Disposition: form-data; name=\"__VIEWSTATE\"");

dos.writeBytes("\r\n\r\n"+strValue);

dos.writeBytes("\r\n-----------------------------"+strBoundary);

这里面是发送文件的部分

dos.writeBytes("\r\nContent-Disposition: form-data; name=\"uploadfile1\"; filename=\"" + strFileName + "\"");

dos.writeBytes("\r\nContent-Type: text/xml");

dos.writeBytes("\r\n\r\n");

dos.writeBytes(new String(data));

dos.writeBytes("\r\n-----------------------------"+strBoundary);

dos.writeBytes("\r\nContent-Disposition: form-data; name=\"Button1\"");

dos.writeBytes("\r\n上传");

dos.writeBytes("\r\n-----------------------------"+strBoundary+"--");

dos.writeBytes("\r\n");

dos.close();

最后发送,也就是执行连接的操作。最后把上面程序部署到HP-UNIX上面,就可以上传文件到我的逻辑层了。以上的过程用j2se的net包也可以实现的,改一改类和方法就是了。

本文叙述的是文本文件的上传方式,对于二进制的文件则需要对文件数据进行编码,一般使用base64的编码。基本步骤是相同的,只要在组织文件数据的时候对文件内容编码并指明编码方式就可以了。

文中不详处,请email:zlyperson@163.net

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有