java web 实现简单下载功能
项目结构
├── src\
│ ├── a.txt
│ └── com\
│ └── demo\
│ └── web\
│ ├── Cookie\
│ ├── download\
│ ├── homework\
│ ├── servlet\
│ ├── servletcontext\
│ └── utils\
└── web\├── WEB-INF\│ ├── b.txt│ └── lib\│ └── javax.servlet.jar├── c.txt├── download.html├── htmls\│ └── location2.html├── img\│ ├── 1.avi│ ├── 2.jpg│ └── 九尾.jpg├── index.jsp├── location.html└── register.html
/**
工具类
*/
import sun.misc.BASE64Encoder;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;public class DownLoadUtils {public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {if (agent.contains("MSIE")) {// IE浏览器filename = URLEncoder.encode(filename, "utf-8");filename = filename.replace("+", " ");} else if (agent.contains("Firefox")) {// 火狐浏览器BASE64Encoder base64Encoder = new BASE64Encoder();filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";} else {// 其它浏览器filename = URLEncoder.encode(filename, "utf-8");}return filename;}
}/**
下载文件servlet实现
*/import com.demo.web.utils.DownLoadUtils;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// request.setCharacterEncoding("UTF-8");//1、获取文件名称String filename = request.getParameter("filename");System.out.println(filename);//2、使用字节输入流读取数据到内存//2.1 获取文件在服务器端的真实路径ServletContext servletContext = this.getServletContext();String realPath = servletContext.getRealPath("/img/" + filename);//2.2 读取文件到内存File file = new File(realPath);FileInputStream fis = new FileInputStream(file);//3、指定response响应头信息//3.1 指定响应头类型:content-typeString mimeType = servletContext.getMimeType(realPath);//image/jpegresponse.setHeader("content-type", mimeType);//处理文件名中文乱码问题//1、获取客户端使用的浏览器类型String agent = request.getHeader("user-agent");//2、调用工具类,返回一个文件名称filename = DownLoadUtils.getFileName(agent, filename);//3.2 指定响应头的打开方式response.setHeader("content-disposition", "attachment;filename=" + filename);//4、将数据写出到response输出流ServletOutputStream sos = response.getOutputStream();byte[] buff = new byte[1024 * 8];//缓冲区int len = 0;while ((len = fis.read(buff)) != -1) {sos.write(buff,0,len);}fis.close();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
前端
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>下载文件</title>
</head>
<body><a href="/img/2.jpg">图片1</a><a href="/img/九尾.jpg">图片2</a><hr><a href="/downloadServlet?filename=九尾.jpg">下载图片1</a><a href="/downloadServlet?filename=2.jpg">下载图片2</a></body>
</html>
工具类
import java.io.File;
import java.io.IOException;/*** File类的使用*/
public class FileTest {/*** 创建文件** @param filename 文件名*/public File createFile(String filename) throws IOException {//1、创建file对象File file = new File(filename);//判断文件是否存在if (!file.exists()) {//2、调用方法创建文件file.createNewFile();}return file;}/*** 创建目录** @param pathname*/public void createDir(String pathname) {File file = new File(pathname);if (!file.exists()) {//1、第一种方式:创建目录,只能创一级目录
// file.mkdir();//1、第二种方式:创建目录,可以创建多级目录file.mkdirs();}}/*** 删除文件** @param filename 文件名*/public void delFile(String filename) {File file = new File(filename);if (file.exists()) {file.delete();System.out.println("删除成功!");} else {System.out.println(file.getName() + "不存在!");}}/*** 遍历文件的路径* @param filename 文件名*/public void outFilePath(String filename) {File file = new File(filename);String path = file.getAbsolutePath();String path1 = file.getPath();System.out.println(path);System.out.println(path1);}/*** 遍历目录中所有的文件和目录** @param filename 文件名*/public void listDir(String filename) {File file = new File(filename);//判断是否是目录if (file.isDirectory()) {//遍历目录File[] files = file.listFiles();
// System.out.println("文件的个数" + files.length);//跳出的条件if (null == files || files.length == 0) {return;} else {for (File file1 : files) {if (file1.isDirectory()) {System.out.println("目录是----" + file1.getName());//递归算法listDir(file1.getAbsolutePath());} else {System.out.println("文件是---" + file1.getName());}}}} else {System.out.println("文件是---" + file.getName());}}/*** 给指定的文件重命名** @param filename 文件名*/public void renameFile(String filename) {File file = new File(filename);file.renameTo(new File("g://a//aa.txt"));}public static void main(String[] args) {FileTest ft = new FileTest();ft.renameFile("g://a//a.txt");
// ft.listDir("g://apache-tomcat-8.0.36");
// ft.outFilePath("g://a//b//b.txt");
// try {
// ft.createFile("g://a.txt");
// } catch (IOException e) {
// e.printStackTrace();
// }
// ft.createDir("g://a//b");
// ft.delFile("g://a.txt");}
}import java.io.*;/*** java中的I/O流*/
public class IODemo {public static void main(String[] args) throws IOException {IODemo demo = new IODemo();demo.copyFile("g://a//aa.txt","g://a//b//aa.txt");
// demo.writeFile("g://a//a.txt");
// demo.readFile("g://a//aa.txt");}/**** 读操作* @param filename 文件名*/public void readFile(String filename) throws IOException {/*** 第一种方式*/
// File file = new File(filename);
// //1、创建一个字节读流的对象
// FileInputStream fis = new FileInputStream(file);
// int len = 0;//读取的字节数
// //2、读文件: 文件如果读到末尾返回为-1
// while ((len = fis.read()) != -1) {
// System.out.print((char)len);
// }
// //关闭流
// fis.close();/*** 第二种方式*/File file = new File(filename);FileInputStream fis = new FileInputStream(file);//定义一个缓冲区byte[] buff = new byte[1024 * 8];int len = 0;//读取的字节数while ((len = fis.read(buff)) != -1) {System.out.write(buff, 0, len);}//关闭流fis.close();}//写操作public void writeFile(String filename) throws IOException {//1、创建一个字节输出流对象:追加内容,需要传入第二个参数FileOutputStream fos = new FileOutputStream(new File(filename), true);//2、写文件String str = "--这是追加的内容!";fos.write(str.getBytes());
// fos.write(100);//强制从缓冲区中把数据写入到文件中fos.flush();//关闭流fos.close();}//拷贝文件:边读边写的过程public void copyFile(String srcFile, String deFile) throws IOException {//1、创建字节输入流对象File file = new File(srcFile);FileInputStream fis = new FileInputStream(file);//2、创建字节输出流对象File file1 = new File(deFile);FileOutputStream fos = new FileOutputStream(file1);//3、使用输入流读取文件到内存byte[] buff = new byte[1024 * 8];int len = 0;//读取的字节数while ((len = fis.read(buff)) != -1) {//4、边读边写fos.write(buff,0,len);fos.flush();}//5、反向关闭流fos.close();fis.close();}}