文件上传和下载(一)--【jsp+servlet】

时间:2020-12-12 21:07:41

一、文件上传

在TCP/IP中,最早出现的文件上传机制是FTP。它是将文件由客户端发送到服务器的标准机制。

但是在jsp编程中不能使用FTP方法来上传文件,这是由jsp运行机制所决定的。

通过为表单元素设置method="post" enctype="multipart/form-data"属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而是实现文件的上传。


enctype属性有三种类型

文件上传和下载(一)--【jsp+servlet】


实例【jsp+servlet】

1、上传实现思路

(一)、环境搭建【配置web.xml创建UploadServlet】

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>com.wuhn.scxz.servlet.UploadServlet</servlet-class>
</servlet>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>com.wuhn.scxz.servlet.DownloadServlet</servlet-class>
</servlet>

<!-- 上传servlet -->
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/UploadServlet.do</url-pattern>
</servlet-mapping>
<!-- 下载servlet -->
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/DownloadServlet.do</url-pattern>

</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

(二)、前台页面配置【Form的method设置为post,enctype配置为multipart/form-data


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>">

<title>上传</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<link rel="stylesheet" type="text/css" href="<%=path%>/css/common.css">
<script type="text/javascript" src="<%=path%>/js/jquery-1.11.1.js"></script>
<script type="text/javascript">


/*//js 预览功能因为回去不到本地实际的路径,所以无法实现。因为浏览器考虑到安全性的问题,限制了获取真实的本机路径,只能这样C:\fakepath\img1-lg.jpg
function showPreview(obj){
var imgPath = obj.value;
console.log(imgPath);
document.getElementById("previewImg").innerHTML="<img src='"+imgPath+"'/>";
}
*/

</script>

</head>

<body>
<form action="<%=path%>/UploadServlet.do" method="post" enctype="multipart/form-data">
请选择图片:<input id="myfile" name="myfile" type="file"/>
<input type="submit" value="提交" />${result}
</form>


</body>
</html>



(三)、后台Servlet实现【保存上传文件】

实现的步骤:

1、获取request当中的流信息,保存到临时文件。

2、从临时文件中得到上传的文件名及文件内容起止位置。

3、根据文件起止位置,读取上传文件内容,保存到本地。

package com.wuhn.scxz.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @author wuhn
* @创建时间 2015-12-07
* @功能 上传文件
* **/
public class UploadServlet extends HttpServlet {

/**
* get方法
* **/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);//默认为post提交

}

/**
* post方法
* **/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("测试:已接收到请求");
//从request当中获取流信息
InputStream inputStream = request.getInputStream();

//tempFile指向临时文件
String tempFileName= "D:\\tempFile";
File tempFile = new File(tempFileName);

//fileOutputStream文件输出流指向这个临时文件
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
byte b[] = new byte[1024];
int n;
while ((n = inputStream.read(b)) != -1) {
fileOutputStream.write(b, 0, n);
}
//关闭输出流、输入流
fileOutputStream.close();
inputStream.close();


//关闭上传文件的名称
RandomAccessFile randomFile = new RandomAccessFile(tempFile,"r");
randomFile.readLine();
String str = randomFile.readLine();
String strSplit = str.split(";")[str.split(";").length-1];
int beginIndex = strSplit.indexOf("\"")+1;
int endIndex = strSplit.lastIndexOf("\"");
System.out.println(strSplit+" beginIndex:"+beginIndex+" endIndex:"+endIndex);
String filename = strSplit.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 = startPosition-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 = getServletContext().getRealPath("/")+"images/upload";//这是服务器上的地址
//System.out.println("保存上传文件的路径:"+realPath);
File fileUploadFile = new File(realPath);
if (!fileUploadFile.exists()) {
fileUploadFile.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();

//返回
request.setAttribute("result", "上传成功!");
RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");
dispatcher.forward(request, response);

}

}




二、文件下载

1、需要通过HttpServletResponse.setContentType方法设置Content-Type头字段的值,为浏览器无法使用某种方式或激活某哥程序来处理的MIME类型,例如,“application/octet-stream”或“application/x-msdownload”等。


2、需要通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为“attachment;filename=文件名”。


3、读取下载文件,调用HttpServletResponse.getOutputStream方法返回的ServletOutputStream对象来向客户端写入附件文件内容。


实现【jsp+servlet】

(一)、配置web.xml【配置wen.xml,创建DownloadServlet】


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>com.wuhn.scxz.servlet.UploadServlet</servlet-class>
</servlet>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>com.wuhn.scxz.servlet.DownloadServlet</servlet-class>
</servlet>

<!-- 上传servlet -->
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/UploadServlet.do</url-pattern>
</servlet-mapping>
<!-- 下载servlet -->
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/DownloadServlet.do</url-pattern>

</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>



(二)、前台页面开发【通过超链接的方式发起文件下载请求】


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>">

<title>下载</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<link rel="stylesheet" type="text/css" href="<%=path%>/css/common.css">
<script type="text/javascript" src="<%=path%>/js/jquery-1.11.1.js"></script>

</head>

<body>
下载:<a href="<%=path%>/DownloadServlet.do?filename=test.txt">test.txt</a>    ${errorResult}
</body>
</html>



(三)、后台Servlet【设置响应类型及响应头输出流写入文件内容】

package com.wuhn.scxz.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @author wuhn
* @创建时间 2015-12-07
* @功能 下载文件
* **/
public class DownloadServlet extends HttpServlet {
/**
*get方法
* **/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取文件下载路径
String path = getServletContext().getRealPath("/")+"images/upload";
String filename = request.getParameter("filename");
File file = new File(path + filename);
if(file.exists()){
//设置相应类型
response.setContentType("application/x-msdownload");//或者application/octet-stream
//设置头信息
response.setHeader("Content-Disposition", "attachment;filename=\""+filename+"\"");
InputStream inputStream = new FileInputStream(file);
ServletOutputStream outputStream = response.getOutputStream();
byte b[] = new byte[1024];
int n;
while ((n=inputStream.read(b)) != -1) {
outputStream.write(b, 0, n);
}
//关闭流、释放资源
outputStream.close();
inputStream.close();

}else{
request.setAttribute("errorResult", "文件不存在,下载失败!");
RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");
dispatcher.forward(request, response);
}
}

/**
* post方法
* **/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);//默认为get
}
}


三、项目代码【点击这里下载