前日学习《数据库开发这点事》时,研究hwcall源码时,学到了关于文件上传的一些知识,现总结如下:
文件上传是我们经常遇到的一个问题,form表单有个enctype属性,此属性一般取默认值,即enctype=”application/x-www-form-urlencoded”,则表单只处理表单域中的value值。如要上传文件,则设置enctype=”multipart/form-data”,表单将会以二进制流的方式来处理表单数据,并把文件域所指定文件的内容也封装到请求参数里。
下面来做几个小实验,看下面的几种情况(注意:如无说明,均为firefox下的测试):
一、当enctype=”application/x-www-form-urlencoded”时
upload.html:
<form action="uploadFileByGetParameter.jsp" method="post" enctype="application/x-www-form-urlencoded"/>
上传文件:<input type="file" name="uploadfile"/><br>
所属人:<input type="text" name="author"/><br>
<input type="submit" value="上传"/>
</form>
1、 通过HttpServletRequest的getParameter得到上传数据。
uploadFileByGetParameter.jsp:
<body>
<%
String file = request.getParameter("uploadfile");
String author = request.getParameter("author");
%>
file:<%=file %><br>
author:<%=author %><br>
</body>
操作如图:
è
2、 通过二进制流来得到上传数据:
将form的 action属性改为: uploadFileByBinaryStream.jsp
uploadFileByBinaryStream.jsp:
<body>
<%
InputStream is = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String buffer = null;
While((buffer = br.readLine()) != null){
out.println(buffer);
}
%>
</body>
点上传后得到结果:
说明:当使用IE时,会得到的是中文字符及特殊符号的转换编码,firefox已自动帮我们转换, 如F:/中”:”è%3A 而“/” è%5C,同时,firefox帮我们直接取得了文件名,而不是完整路径。如IE下得到的结果为:。
结论:当enctyp=”application/x-www-form-urlencoded”时,无法得到文件的内容,从而无法实现上传。
二、当enctype=”multipart/form-data”时
upload.html:
***************************源代码:******************************
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="uploadFileBySmartUpload.jsp" method="post" enctype="multipart/form-data"/>
上传文件:<input type="file" name="uploadfile"/><br>
所属人:<input type="text" name="author"/><br>
<input type="submit" value="上传"/>
</form>
</body>
</html>
*******************************************************************
1、 通过HttpServletRequest的getParameter得到上传数据。
*****************uploadFile.jsp源代码**************************
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>uploadFile</title>
</head>
<body>
<%
String file = request.getParameter("uploadfile");
String author = request.getParameter("author");
%>
file:<%=file %><br>
author:<%=author %><br>
</body>
</html>
****************************************************************
结果:
说明,不能直接使用request.getParameter得到上传的数据
2、 通过二进制流来得到上传数据:
*************************源代码*******************************
uploadFileByBinaryStream.jsp:
<body>
<%
InputStream is = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String buffer = null;
While((buffer = br.readLine()) != null){
out.println(buffer);
}
%>
</body>
**************************************************************
得到结果:
从这可以看出,通过二进制流的方式,我们可以得到文件中的内容,因此,要实现上传
我们只需要去解析这个文件的格式内容,然后写到硬盘上即可实现上传。
在hwcall的设计中,实现了一个文件上传组件,如图:
我们可以利用这些,实现文件上传。已在源代码中添加一个例子的完整注释,有兴趣的可以去研究一下这些代码,没兴趣的,只需要参照范例,学会如何使用即可。以下是一个范例:
fupload.html :
uploadFileBySmartUpload.jsp
*************************源代码**********************************
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@ page import="com.jspsmart.upload.*,java.io.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>uploadFile</title>
</head>
<body>
<%
SmartUpload mySmartUpload = new SmartUpload();
mySmartUpload.initialize(pageContext);
mySmartUpload.setMaxFileSize(500 * 1024*1024);
mySmartUpload.upload(); //此方法执行完,file将被添加到files(Files类的对象)中
String sCPath=mySmartUpload.getRequest().getParameter("CurrentPath");
//使用files,主要是为了说明可以实现多个文件的上传
com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(0);
if (!myFile.isMissing()) {
String message = request.getRealPath("/")+ myFile.getFileName();
System.out.println(message);
myFile.saveAs(message, mySmartUpload.SAVE_PHYSICAL); //保存myFile
out.println("上传文件:"+message + " 成功");
}
%>
</body>
</html>
*****************************************************************
操作如下:
点上传后:
上述这个范例只是最基本的使用,想知道更详细的使用方法,请参看hwcall的设计。在《数据库开发这点事》中已附带完整源代码。
图片上不来。以上内容均在群 86912012华东华中,87316904华南西南,87316239华北东北西北 共享,详情http://code.google.com/p/howwe