文件上传
Posted lpl666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传相关的知识,希望对你有一定的参考价值。
需求
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>上传图片</title>
<script src="js/jquery-1.12.4.min.js"></script>
<style>
a {
text-decoration: none;
display: block;
width: 100px;
height: 25px;
border-radius: 25px;
background: darkcyan;
color:#fff;
text-align: center;
line-height: 25px;
}
a:active{
background: orange;
}
</style>
</head>
<body>
<form enctype="multipart/form-data">
<input type="file" name="avatar" id="avatar" style="display: none;">
</form>
<a href="javascript:" id="btn">上传图片</a>
<span></span><br>
<img src="img/default.jpg" style="width: 150px;" alt="">
<script>
$("#btn").click(function(){
// 检测用户是否选择完毕
$('#avatar').change(function(){
// 获取文件名
var fileName = $('#avatar').val().split("")[2];
$('span').html(fileName);
// 创建表单数据对象
var fm = new FormData($('form')[0]);
// 发送ajax请求上传图片到服务器
$.ajax({
url:'http://localhost/upload',
data:fm,
type: "post",
processData:false,
contentType:false,
success:function(v){
$('img').attr('src','http://localhost:52330/resources/images/' + v.url);
}
});
});
// 触发上传图片事件
$('#avatar').click();
});
</script>
</body
后端代码(Java版)
项目核心目录结构
Maven文件上传依赖项
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
工具类代码
BaseUtil.java
package util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BaseUtil {
private static String uploadDir=null;
static {
try {
// 获取上传文件目录的配置文件流
InputStream uploadBaseUrl_inputStream = BaseUtil.class.getClassLoader().getResourceAsStream("upload.properties");
// 创建Properties集合
Properties uploadBaseUrl_properties = new Properties();
uploadBaseUrl_properties.load(uploadBaseUrl_inputStream);
uploadDir=uploadBaseUrl_properties.get("baseUrl").toString();
} catch (IOException e) {
e.printStackTrace();
}
}
// 获取文件上传的目录
public static String getUploadBaseDir(){
return uploadDir;
}
}
FileUtil.java
package util;
import java.io.File;
import java.util.Random;
import java.util.UUID;
public class FileUtil {
private static Random random = new Random();
// 随机生成分散目录
public static String getDir(){
String dir = null;
String values = "abcdefg01234567890";
int i = random.nextInt(values.length());
String path = String.valueOf(values.charAt(i));
return path;
};
// 保证目录必须存在
public static String mustDir(String path){
File file = new File(path);
if(!file.exists()){
file.mkdirs();
}
return path;
};
// 生成唯一文件名
public static String FileName(String uploadName){
UUID uuid = UUID.randomUUID();
String uid = uuid.toString().replaceAll("-","");
String fileName = uid;
return fileName+"."+getExt(uploadName);
}
// 根据上传文件名获取扩展名
public static String getExt(String uploadName){
return uploadName.split(".")[1];
}
}
配置文件
upload.properties
baseUrl=C:/Users/Bruce/Desktop/H5/resources/images/
过滤器-跨域设置
CORSFilter.java
package web;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter("/*")
public class CORSFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
String origin = request.getHeader("Origin");
// 解决跨域的数据问题
response.setHeader("Access-Control-Allow-Origin",origin);
// 解决跨域的cookie问题
response.setHeader("Access-Control-Allow-Credentials","true");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
Servlet处理程序
UploadServlet.java
package web;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import util.BaseUtil;
import util.FileUtil;
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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
// 【post】
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 上传文件并获取参数集合
Map<String, String[]> paramsMap = getParamsMap(request);
// 获取文件名称
String value = paramsMap.get("avatar")[0];
// 创建map对象
Map<String,String> obj = new HashMap<>();
obj.put("url",value);
// jackson
ObjectMapper mapper = new ObjectMapper();
// 设置响应头
response.setContentType("application/json;charset=utf-8");
// 响应并返回json
mapper.writeValue(response.getOutputStream(),obj);
}
// 【上传文件并获取参数集合】
public Map<String,String[]> getParamsMap(HttpServletRequest request){
Map<String,String[]> map = new HashMap<>();
try {
// 1. 创建文件磁盘工厂对象
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 2. 创建上传解析对象,帮助解析request对象中的inputStream
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
// 3. 解析完成,返回List集合
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
// 4. 遍历集合
for (FileItem fileItem : fileItems) {
// 4.1 获取表单项名字
String fieldName = fileItem.getFieldName();
// 4.2 检测是否是普通表单项
if (fileItem.isFormField()) {
// 4.2.1 获取普通项的值
String value = fileItem.getString("utf-8");
if(map.containsKey(fieldName)){
String[]oldArr = map.get(fieldName);
String[]newArr = new String[]{value};
String[]result=new String[oldArr.length + newArr.length];
System.arraycopy(oldArr,0,result,0,oldArr.length);
System.arraycopy(newArr,0,result,oldArr.length,newArr.length);
map.put(fieldName,result);
}
else {
map.put(fieldName,new String[]{value});
}
}
// 4.3 操作文件流
else {
// 获取文件名
String fileName = fileItem.getName();
// 获取要上传的目录
String baseDir = BaseUtil.getUploadBaseDir();
// 获取分散目录
String smallDir=FileUtil.getDir();
// 完整目录
String path = baseDir + smallDir;
// 该目录必须存在
FileUtil.mustDir(path);
// 定义唯一文件名
String fileNameId = FileUtil.FileName(fileName);
// 4.3.1 获取文件流输入流
InputStream inputStream = fileItem.getInputStream();
// 4.3.2 创建输出流
FileOutputStream os = new FileOutputStream(path
+"/"+fileNameId);
byte[] bs = new byte[1024];
int len = 0;
// 读取文件流输入流中内容
while ((len = inputStream.read(bs)) != -1) {
os.write(bs, 0, len);
}
inputStream.close();
os.close();
// 删除临时文件
fileItem.delete();
map.put(fieldName,new String[]{smallDir + "/" + fileNameId});
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return map;
}
// 【get】
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
上传多个文件
前端代码
<form action="upload2Servlet" enctype="multipart/form-data" method="post">
<p>
<span>姓名:</span>
<input type="text" name="username">
</p>
<p>
<span>爱好:</span>
<input type="checkbox" name="hobby" value="跑步"> 跑步
<input type="checkbox" name="hobby" value="跳绳"> 跳绳
<input type="checkbox" name="hobby" value="拳击"> 拳击
</p>
<p>
<span>相册:</span>
<input type="file" name="avatar" multiple>
</p>
<input type="submit">
</form>
后端处理程序
Upload2Servlet.java
package web;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import util.BaseUtil;
import util.FileUtil;
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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
@WebServlet("/upload2Servlet")
public class Upload2Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 上传文件,并获取相关参数
Map<String, String[]> paramsMap = getParamsMap(request);
Set<Map.Entry<String, String[]>> entries = paramsMap.entrySet();
// 循环遍历查看参数信息
for (Map.Entry<String, String[]> entry : entries) {
System.out.println(entry.getKey()+"---"+ Arrays.toString(entry.getValue()));
}
// 输出结果
// avatar---[0/d777d06d4a214b068cb0633012924375.jpg, e/f06da8b44d6c4848ad2dbdf216b80508.jpg, d/f0dcb11671af46309ae2d45bee8b88ae.jpg, 6/32bdd21eb2fb491cb5fc9acd7bcc24cf.jpg]
// username---[Bruce]
// hobby---[跑步, 跳绳, 拳击]
}
// 【上传文件并获取参数集合】
public Map<String,String[]> getParamsMap(HttpServletRequest request){
Map<String,String[]> map = new HashMap<>();
try {
// 1. 创建文件磁盘工厂对象
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 2. 创建上传解析对象,帮助解析request对象中的inputStream
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
// 3. 解析完成,返回List集合
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
// 4. 遍历集合
for (FileItem fileItem : fileItems) {
// 4.1 获取表单项名字
String fieldName = fileItem.getFieldName();
// 4.2 检测是否是普通表单项
if (fileItem.isFormField()) {
// 4.2.1 获取普通项的值
String value = fileItem.getString("utf-8");
if(map.containsKey(fieldName)){
String[]oldArr = map.get(fieldName);
String[]newArr = new String[]{value};
String[]result=new String[oldArr.length + newArr.length];
System.arraycopy(oldArr,0,result,0,oldArr.length);
System.arraycopy(newArr,0,result,oldArr.length,newArr.length);
map.put(fieldName,result);
}
else {
map.put(fieldName,new String[]{value});
}
}
// 4.3 操作文件流
else {
// 获取文件名
String fileName = fileItem.getName();
// 获取要上传的目录
String baseDir = BaseUtil.getUploadBaseDir();
// 获取分散目录
String smallDir= FileUtil.getDir();
// 完整目录
String path = baseDir + smallDir;
// 该目录必须存在
FileUtil.mustDir(path);
// 定义唯一文件名
String fileNameId = FileUtil.FileName(fileName);
// 4.3.1 获取文件流输入流
InputStream inputStream = fileItem.getInputStream();
// 4.3.2 创建输出流
FileOutputStream os = new FileOutputStream(path
+"/"+fileNameId);
byte[] bs = new byte[1024];
int len = 0;
// 读取文件流输入流中内容
while ((len = inputStream.read(bs)) != -1) {
os.write(bs, 0, len);
}
inputStream.close();
os.close();
// 删除临时文件
fileItem.delete();
// 检测是否已经存在
if(map.containsKey(fieldName)){
String[]oldArr = map.get(fieldName);
String[]newArr = new String[]{smallDir + "/" + fileNameId};
String[]result=new String[oldArr.length + newArr.length];
System.arraycopy(oldArr,0,result,0,oldArr.length);
System.arraycopy(newArr,0,result,oldArr.length,newArr.length);
map.put(fieldName,result);
}
else{
map.put(fieldName,new String[]{smallDir + "/" + fileNameId});
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return map;
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
以上是关于文件上传的主要内容,如果未能解决你的问题,请参考以下文章
ajaxFileUpload上传带参数文件及JS验证文件大小