servlet+jsp实现的文件上传与下载
java文件上传与下载
通过微表单元苏设置Method = "post"
enctype = "multipart/form-data"属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet
中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。
表单ENCTYPE属性
application/x-www-form-urlencoded :这是默认的编码方式,它只处理表单域里的value属性值。采用
这种编码方式的表单会将表单域的值处理成URL编码方式
multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域
指定文件的内容也封装到请求参数里
text/plain:这种方式主要适用于直接通过表单发送邮件的方式
文件下载
需要通过HttpServletResponse.setContentType方法设置Content-Type头字段的值,
为浏览器无法使用某种方式或激活某个程序来处理的MIME类型
需要通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为
“attachment;filename=文件名”;
读取下载文件,调用HttpServletResponse.getOutputStream方法返回的ServletOutputStream
对象来向客户端写入附件文件内容
文件上传实现步骤
获取request当中的流信息,保存到临时文件
从临时文件当中得到上传的文件名,及文件内容起止位置
上传
下载文件
通过微表单元苏设置Method = "post"
enctype = "multipart/form-data"属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet
中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。
表单ENCTYPE属性
application/x-www-form-urlencoded :这是默认的编码方式,它只处理表单域里的value属性值。采用
这种编码方式的表单会将表单域的值处理成URL编码方式
multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域
指定文件的内容也封装到请求参数里
text/plain:这种方式主要适用于直接通过表单发送邮件的方式
文件下载
需要通过HttpServletResponse.setContentType方法设置Content-Type头字段的值,
为浏览器无法使用某种方式或激活某个程序来处理的MIME类型
需要通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为
“attachment;filename=文件名”;
读取下载文件,调用HttpServletResponse.getOutputStream方法返回的ServletOutputStream
对象来向客户端写入附件文件内容
文件上传实现步骤
获取request当中的流信息,保存到临时文件
从临时文件当中得到上传的文件名,及文件内容起止位置
根据文件起止位置,读取上传文件内容,保存到本地
Jsp页面
<form action="uploadServlet.do" method="post"
enctype="multipart/form-data">
<input id="myfile" name="myfile" type="file"
/> <input type="submit" value="提交" />${result}
</form>
下载:
<a href="downloadServlet.do?filename=test1.txt">test1.txt</a>
${errorResult}
上传
public class UploadServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req,resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//从request当中获取流信息
InputStream fileSource = req.getInputStream();
String tempFileName = "E:/tempFile";
//tempFile指向临时文件
File tempFile = new File(tempFileName);
//outputStram文件输出流指向这个临时文件
FileOutputStream outputStream = new FileOutputStream(tempFile);
byte b[] = new byte[1024];
int n;
while(( n = fileSource.read(b)) != -1){
outputStream.write(b, 0, n);
}
//关闭输出流、输入流
outputStream.close();
fileSource.close();
//获取上传文件的名称
RandomAccessFile randomFile = new RandomAccessFile(tempFile,"r");
// l = new String(l.getBytes("8859_1"),"gbk");
String str2 = randomFile.readLine();
//编码转换
str2 = new String(str2.getBytes("8859_1"),"utf-8");
System.out.println(str2);
String str = randomFile.readLine();
str = new String(str.getBytes("8859_1"),"utf-8");
System.out.println(str);
int beginIndex = str.lastIndexOf("=") + 2;
int endIndex = str.lastIndexOf("\"");
String filename = str.substring(beginIndex, endIndex);
System.out.println("filename:" + filename);
//重新定位文件指针到文件头
randomFile.seek(0);
long startPosition = 0;
int i = 1;
//获取文件内容 开始位置
while(( n = randomFile.readByte()) != -1 && i <=4){
if(n == '\n'){
startPosition = randomFile.getFilePointer();
i ++;
}
}
startPosition = randomFile.getFilePointer() -1;
//获取文件内容 结束位置
randomFile.seek(randomFile.length());
long endPosition = randomFile.getFilePointer();
int j = 1;
while(endPosition >=0 && j<=2){
endPosition--;
randomFile.seek(endPosition);
if(randomFile.readByte() == '\n'){
j++;
}
}
endPosition = endPosition -1;
//设置保存上传文件的路径
//路径可以自行设置
String realPath = "E:\\myeclipse workplace\\css+js";
// String realPath = getServletContext().getRealPath("/") + "images";
File fileupload = new File(realPath);
System.out.println(realPath);
if(!fileupload.exists()){
fileupload.mkdir();
}
File saveFile = new File(realPath,filename);
RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,"rw");
//从临时文件当中读取文件内容(根据起止位置获取)
randomFile.seek(startPosition);
while(startPosition < endPosition){
randomAccessFile.write(randomFile.readByte());
startPosition = randomFile.getFilePointer();
}
//关闭输入输出流、删除临时文件
randomAccessFile.close();
randomFile.close();
tempFile.delete();
req.setAttribute("result", "上传成功!");
RequestDispatcher dispatcher = req.getRequestDispatcher("test.jsp");
dispatcher.forward(req, resp);
}
}
下载文件
public class DownLoadServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// req.setCharacterEncoding("utf-8");
// resp.setCharacterEncoding("utf-8");
// resp.setContentType("text/html;charset=utf-8");
// req.setCharacterEncoding("utf-8");
// resp.setContentType("text/html;charset=UTF-8");
// resp.setContentType("text/plain");
//进行编码的转换,因为不能识别中文
resp.setHeader("content-type","text/html;charset=UTF-8");
String path = getServletContext().getRealPath("/") + "images/";
String fileName = req.getParameter("filename");
String filename = null;
filename = new String(fileName.getBytes("8859_1"),"utf-8");
// filename = new String(filename.getBytes("8859_1"),"uft-8");
System.out.println("路径:" + path + "文件名:" + filename);
File file = new File(path + filename);
if (file.exists()) {
//由于下载的时候与浏览器的编码不符,浏览器不能识别中文编码,这里要进行转换
String value = new String(filename.getBytes("utf-8"),"ISO-8859-1");
resp.setContentType("application/x-msdownload");
resp.setHeader("Content-Disposition", "attachment;filename=\""
+ value + "\"");
InputStream inputStream = new FileInputStream(file);
ServletOutputStream outputStream = resp.getOutputStream();
byte b[] = new byte[1024];
int n;
while ((n = inputStream.read(b)) != -1) {
outputStream.write(b, 0, n);
}
outputStream.close();
inputStream.close();
} else {
req.setAttribute("errorResult", "文件不存在下载失败!!");
resp.sendRedirect("luntan.jsp");
}
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理