JSP上传文件至服务器【1】

这几天一直在试使用JSP向服务器上传文件,在网上也找了很多前辈的代码,直接拷过去大部分都不能有,总是希望拷过去后直接看效果,结果忙了很久,尝试前辈的各种代码都不行。最终决定沉下气来专攻一端代码一行一行地看,最终经过几天的不懈努力实现了功能。以后还得写程序静下心来不能心浮气躁。

下边是一个简单的实例,源代码是在这里,但在我的电脑上确实可以运行,但存在bug,如下图。(注意!我说的是在我的电脑上,在前辈的电脑上不一定,这里没有把别人的bug亮出来昭告天下的意思,只是为了方便说明程序存在的问题,不好意思了撒~)




下边我先为前辈的代码加上注释:

<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>
<%@ page import="javax.servlet.*"%>
<%@ page import="javax.servlet.http.*"%>
<html><head><title>upFile</title></head>
<body bgcolor="#ffffff">
<%
//定义上载文件的最大字节
int MAX_SIZE = 102400 * 102400;
// 创建根路径的保存变量
String rootPath;
//声明文件读入类
DataInputStream in = null;
FileOutputStream fileOut = null;
//取得客户端的网络地址即IP
String remoteAddr = request.getRemoteAddr();
//获得服务器的名字
String serverName = request.getServerName();
//取得互联网程序的绝对地址,request.getRealPath(serverName)表示获取当前运行的文件在服务器所在的目录名
String realPath = request.getRealPath(serverName);
//截取realPath的第一次字符到最后一个\之前的字符并赋值给realPath
realPath = realPath.substring(0,realPath.lastIndexOf("\\"));
//创建文件的保存目录,也就是说在当前运行的文件的目录下建立了一个upload目录,将会用于存储上传文件
rootPath = realPath + "\\upload\\";
//取得客户端上传的数据类型并将返回值赋给contentType变量
String contentType = request.getContentType();
try{
//如果contentType中存在"multipart/form-data"这个字符串,也就是说上传了二进制数据
if(contentType.indexOf("multipart/form-data") >= 0){
//那么使用request对象的getInputStream()来返回这些数据,并将其赋给in
in = new DataInputStream(request.getInputStream());
//下边是返回表单二进制的长度并存储在formDataLength中
int formDataLength = request.getContentLength();
//如果字节数过大则提示文件过大
if(formDataLength > MAX_SIZE){
out.println("<P>上传的文件字节数不可以超过" + MAX_SIZE + "</p>");
return;
}
//根据上传的字节数简历byte类型数组将用于存储上传的二进制数据
byte dataBytes[] = new byte[formDataLength];
int byteRead = 0;
int totalBytesRead = 0;
//上传的数据保存在byte数组,使用到了read方法,返回值为本次已读的量
while(totalBytesRead < formDataLength){
byteRead = in.read(dataBytes,totalBytesRead,formDataLength);
totalBytesRead += byteRead;
}
//根据byte数组创建字符串,也就是将byte数组中的信息转化为字符串形式
String file = new String(dataBytes);
System.out.println(file);
//out.println(file);
//下边的三行代码用于获取上传文件的文件名,主要是对file字符串的截取,可以在控制台将file输出就能根据代码看懂如果获得文件名
String saveFile = file.substring(file.indexOf("filename=\"") + 10);
saveFile = saveFile.substring(0,saveFile.indexOf("\n"));
saveFile = saveFile.substring(saveFile.lastIndexOf("\\") + 1,saveFile.indexOf("\""));
//下边是获取contentType也就是 request.getContentType()的最后一个等号的位置,等号后边是一段区分上传图片和其他数据的字符串,并且这段字符串不可能在图片数据中存在
int lastIndex = contentType.lastIndexOf("=");
//取得数据的分隔字符串:将分隔数据和上传图片的分隔字符串赋给boundary
String boundary = contentType.substring(lastIndex + 1,contentType.length());
//创建保存路径的文件名,路径+文件名
String fileName = rootPath + saveFile;
//out.print(fileName);
//pos可以就像一个指针,最终指向图片数据开始的位置
int pos;
pos = file.indexOf("filename=\"");
pos = file.indexOf("\n",pos) + 1;
pos = file.indexOf("\n",pos) + 1;
pos = file.indexOf("\n",pos) + 1;
//从图片数据开始的位置查找分隔字符串,找到的便是图片数据末的分隔字符串的位置
//至于要减去4,可能是因为在file字符串末尾的分隔字符串前还有两个-和一个\r\n,各占1个字节,所以将指针回调4个字节
int boundaryLocation = file.indexOf(boundary,pos) - 4;
//out.println(boundaryLocation);
//取得文件数据的开始的位置,startPos也类似指针指向的确实byte类型时,pos的指向
int startPos = ((file.substring(0,pos)).getBytes()).length;
//out.println(startPos);
//同理获取数据的结束的位置
int endPos = ((file.substring(0,boundaryLocation)).getBytes()).length;
//out.println(endPos);
//检查上载文件是否存在
File checkFile = new File(fileName);
if(checkFile.exists()){
out.println("<p>" + saveFile + "文件已经存在.</p>");
}
//检查上载文件的目录是否存在
File fileDir = new File(rootPath);
if(!fileDir.exists()){
fileDir.mkdirs();
}
//创建文件的写出类
fileOut = new FileOutputStream(fileName);
//使用write方法写出dataBytes数组中特定位置的数据
fileOut.write(dataBytes,startPos,(endPos - startPos));
fileOut.close();
out.println(saveFile + "文件成功上载.</p>");
}else{
String content = request.getContentType();
out.println("<p>上传的数据类型不是multipart/form-data</p>");
}
}catch(Exception ex){
throw new ServletException(ex.getMessage());
}
%>
</body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值