JAVA servlet文件上传
一、文件上传
1.单文件上传
(保存在服务器目录下,没有保存在项目目录下)
Upload.java
package cn.webrx.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
/**
* @author netXiaobao
* @version 1.0
* @date 2020/11/27 20:12
*/
@WebServlet("/upload")
@MultipartConfig
public class Upload extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
// req.setCharacterEncoding("utf-8");
Part p = req.getPart("ff");
//p.write("d:/"+p.getSubmittedFileName());
String fn=req.getServletContext().getRealPath("/upload")+"/"+p.getSubmittedFileName();
System.out.println(fn);
p.write(fn);
}
}
index.jsp
<%--
Created by IntelliJ IDEA.
User: 86182
Date: 2020/11/30
Time: 9:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>单文件上传</h3>
<form action="/upload" enctype="multipart/form-data" method="post">
文件:<input type="file" name="ff"><br>
<input type="submit" value="上传文件">
</form>
</body>
</html>
2.如果上传的文件表单页面是静态页面,有乱码解决方式
Servlet 编写代码
Web.xml 配置
<jsp-config>
<jsp-property-group>
<url-pattern>*.html</url-pattern>
<page-encoding>utf-8</page-encoding>
</jsp-property-group>
</jsp-config>
3.文件上传判断是表单还是文件
判断代码:
输出结果:
index.html:
<h3>单文件上传</h3>
<form action="/upload2" enctype="multipart/form-data" method="post">
<input type="file" name="ff"><br>
<input type="text" name="text"><br>
<input type="submit" value="提交">
</form>
Upload.java:
package cn.webrx.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author netXiaobao
* @version 1.0
* @date 2020/11/30 9:39
*/
@WebServlet("/upload2")
@MultipartConfig
public class Upload2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out=resp.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html lang=\"en\">");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>netXiaobao</title>");
out.println("</head>");
out.println("<body>");
out.println("<h3>"+req.getParameter("text")+"</h3>");
//接文件
Part p=req.getPart("ff");
out.println(String.format("<h3>Part.getSubmittedFileName = %s</h3>",p.getSubmittedFileName()));
out.println(String.format("<h3>Part.getName = %s</h3>",p.getName()));
out.println(String.format("<h3>Part.getSize = %s</h3>",p.getSize()));
out.println(String.format("<h3>Part.getContentType = %s</h3>",p.getContentType()));
//上传到指定的目录下
//p.write(req.getServletContext().getRealPath("/upload/user.jpg"));
//接表单
Part f=req.getPart("text");
out.println(String.format("<h3>Part.getSubmittedFileName = %s</h3>",f.getSubmittedFileName()));
out.println(String.format("<h3>Part.getName = %s</h3>",f.getName()));
out.println(String.format("<h3>Part.getSize = %s</h3>",f.getSize()));
out.println(String.format("<h3>Part.getContentType = %s</h3>",f.getContentType()));
out.println("</body>");
out.println("</html>");
}
}
4.多文件上传
注:多文件上传是以图片为示例,所以后面代码增加了一个添加文字的功能,重要的是遍历接收
Upload.java
index.html
index.html:
<h3>多文件上传</h3>
<form action="/uploads" enctype="multipart/form-data" method="post">
<input type="file" name="ff" multiple><br>
<input type="text" name="text"><br>
<input type="file" name="ff2"><br>
<input type="file" name="ff3"><br>
<input type="file" name="ff4"><br>
<input type="submit" value="提交">
</form>
Upload.java:
package cn.webrx.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.CallableStatement;
import java.util.Collection;
/**
* @author netXiaobao
* @version 1.0
* @date 2020/11/30 9:39
*/
@WebServlet("/uploads")
@MultipartConfig
public class Uploads extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html lang=\"en\">");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>netXiaobao</title>");
out.println("</head>");
out.println("<body>");
//批量接值
Collection<Part> ps = req.getParts();
for (Part p : ps) {
String fn = p.getSubmittedFileName();
if (fn == null || "".equals(fn)) continue;
fn=req.getServletContext().getRealPath("/uploads/"+fn);
BufferedImage i=ImageIO.read(p.getInputStream());
out.println(String.format("<p>文件名:%s;%d字节;宽度:%d px;高度:%d px</p>",p.getSubmittedFileName(),p.getSize(),i.getWidth(),i.getHeight()));
Graphics2D g=i.createGraphics();
g.setColor(Color.RED);zhu
g.drawString(" hello world",50,50);
g.dispose();
String f=p.getContentType();
ImageIO.write(i,f.substring(f.lastIndexOf("/")+1).toLowerCase(),new FileOutputStream(fn));
// p.write(fn);
}
out.println("</body>");
out.println("</html>");
}
}
注:多文件上传是以图片为示例,所以后面代码增加了一个添加文字的功能,重要的是遍历接收
5.servlet上传控制格式、大小、多种重命名(4种)
index.html:
<h3>多文件上传</h3>
<form action="/uploads" enctype="multipart/form-data" method="post">
<input type="file" name="ff" multiple><br>
<input type="text" name="text"><br>
<input type="file" name="ff2"><br>
<input type="file" name="ff3"><br>
<input type="file" name="ff4"><br>
<input type="submit" value="提交">
</form>
Uploads.java:
package cn.webrx.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.sql.CallableStatement;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author netXiaobao
* @version 1.0
* @date 2020/11/30 9:39
*/
@WebServlet("/uploads")
@MultipartConfig
public class Uploads extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html lang=\"en\">");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>netXiaobao</title>");
out.println("</head>");
out.println("<body>");
//批量接值
Collection<Part> ps = req.getParts();
//设置初始值(路径、文件大小、文件格式)
String pp = "/uploads/user/";//路径
long maxSize = 1024 * 1024 * 20;//文件大小设置20MB
//文件格式设置
Set<String> set = new HashSet<String>();
set.add(".jpg");
set.add(".gif");
set.add(".png");
set.add(".rar");
// 上传的目录,相对路径,自动建立目录
String path = req.getServletContext().getRealPath(pp);
File file = new File(path);
if (!file.exists()) file.mkdirs();//判断目录是否存在,不存在就建立
for (Part p : ps) {
String fn = p.getSubmittedFileName();//取得文件名
if (fn == null || "".equals(fn)) continue;
//控制文件大小
long size = p.getSize();
if (size > maxSize) {//判断文件大小要是大于设定值,就继续判断
continue;
}
//控制文件格式
//p.getContentType();
String fileName = p.getSubmittedFileName();//获取文件名
//截取文件扩展名从最后一个.开始截取(包含.)
String ext = fileName.toLowerCase().substring(fileName.lastIndexOf("."));
//截取文件的基本名
String baseName=fileName.substring(0,fileName.lastIndexOf("."));
if (!set.contains(ext)) {//判断是否包含set集合中的字符串,不包含就继续判断
continue;
}
//控制文件的命名:1.原名;2.uuid;3.日期;4.原名+编号
/*1. p.write(path + "/" + fn);*/
/*2. String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();//uuid中的"-"符号删去
p.write(path + "/" + uuid + ext);*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssS");
p.write(path + "/" + sdf.format(new Date()) + "_" + String.format("%05d", new Random().nextInt(99999)) + ext);
/*4. int fileIndex = 0;
File ds = new File(path + "/" + fileName);
while (ds.exists()) {
++fileIndex;
fileName = baseName+ "(" + fileIndex + ")" + ext;
ds = new File(path + "/" + fileName);
}
p.write(path + "/" + fileName);*/
/* 图像左上角加水印
fn = path + "/" + fn;(上传目录:原名)
BufferedImage i = ImageIO.read(p.getInputStream());
out.println(String.format("<p>文件名:%s;%d字节;宽度:%d px;高度:%d px</p>", p.getSubmittedFileName(), p.getSize(), i.getWidth(), i.getHeight()));
Graphics2D g = i.createGraphics();
g.setColor(Color.RED);
g.drawString(" hello world", 50, 50);
g.dispose();
String f = p.getContentType();
ImageIO.write(i, f.substring(f.lastIndexOf("/") + 1).toLowerCase(), new FileOutputStream(fn))
*/
}
out.println("</body>");
out.println("</html>");
}
}
多种重命名效果图:
2.uuid:
3.日期
4.原名+编号
二、文件下载
文件下载分为两种:
1.普通下载
2.安全下载
1.普通下载:
普通下载代码:download.jsp
<%--
Created by IntelliJ IDEA.
User: 86182
Date: 2020/12/3
Time: 13:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>普通下载</h3>
<a href="/rar/源代码.rar">下载源代码</a>
<a href="/photo/flowers.jpg" download="tee.jpg">下载图片</a>
<!-- 下载后是jsp输出的静态内容 -->
<a href="/download/download.jsp" download>下载download.jsp文件</a>
</body>
</html>
普通下载图片必须增加download,否则单击后是直接显示图片,没有下载功能;第三个下载为什么打红星呢?
普通下载,下载后文件打开显示的是jsp输出的静态内容
普通下载的缺点:容易发生安全问题,产生盗链
那么如何防止盗链的情况发生和保证下载安全呢?需要使用servlet进行安全设置。
2.安全下载
如果要下载的内容,放到系统目录下 WEB-INF必须使用安全下载
下载人不知道文件在服务器位置,也不知道原来的名称,下载时候还可以动态修改名称,判断是不是登录,统计下载次数
download.jsp:
<h3>安全下载</h3>
<!-- 如果要下载的内容,放到系统目录下 WEB-INF必须使用安全下载
下载人不知道文件在服务器位置,也不知道原来的名称,下载时候还可以动态修改名称,判断是不是登录,统计下载次数
-->
<a href="/donw.do?type=girl" download>图片下载.jpg</a>
Down.java:
package cn.webrx.servlet;
import javax.servlet.ServletException;
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;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author netXiaobao
* @version 1.0
* @date 2020/12/3 16:55
*/
@WebServlet("/donw.do")
public class Down extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path=req.getServletContext().getRealPath("/WEB-INF/down/美女.jpg");
File file=new File(path);
FileInputStream fis=new FileInputStream(file);
byte[] buf=fis.readAllBytes();
fis.close();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String downname= sdf.format(new Date())+path.toLowerCase().substring(path.indexOf("."));
// 清空response
resp.reset();
// 设置response的Header
resp.addHeader("Content-Disposition", "attachment;filename=" + downname);
resp.addHeader("Content-Length", String.format("%d", file.length()));
resp.setContentType("application/octet-stream");
OutputStream os = resp.getOutputStream();
os.write(buf);
os.flush();
os.close();
}
}
安全下载不会在浏览器中显示真实的路径,可以在java代码中进行判断用户登录与否等安全措施