1.直接通过form表单方式上传
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" th:src="@{http://code.jquery.com/jquery-2.1.4.min.js}"></script>
</head>
<body>
<form action="/upload7" method="post" enctype="multipart/form-data">
<input type = "file" name = "myFile">
<input type = "file" name = "myFile">
<input type = "file" name = "myFile">
<input type="submit" value="Upload! "/>
</form>
<!--单文件上传-->
<form id= "uploadForm">
<p >指定文件名: <input type="text" name="filename" value= ""/></p >
<p >上传文件: <input type="file" name="myFile"/></p>
<input type="button" value="上传" onclick="doUpload()" />
</form>
</body>
form class="layui-form" action="#" id="uploadForm">
<div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-block">
<input type="text" id="config_name" placeholder="请输入配置名称" autocomplete="off"
class="layui-input">
</div>
</div>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">描述</label>
<div class="layui-input-block">
<textarea id="config_desc" placeholder="请输入配置描述" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文件</label>
<div class="layui-input-block">
<input type="file" name="file">
<p class="help-block">请选择配置文件</p>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" id="save_config_file">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
<script>
function doUpload() {
var formData = new FormData($("#uploadForm")[0]);
var file = document.getElementsByName("file").values();
debugger;
$.ajax({
url: '/uploads',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
alert(returndata);
},
error: function (returndata) {
alert(returndata);
}
});
}
$("#save_config_file").click(function () {
var name = $("#config_name").val();
var desc = $("#config_desc").val();
var userId = $("#userId").val();
var formData = new FormData($("#uploadForm")[0]);
formData.append("name",name);
formData.append("desc",desc);
formData.append("userId",userId);
$.ajax({
url: '/uploads',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
layui.use('layer', function () {
var layer = layui.layer;
layer.msg(returndata.returnMsg, {
icon: 1
});
});
setTimeout(() => {
closeLayui();
}, 300);
},
error: function (returndata) {
console.log("====================Error==========================");
}
});
});
</script>
</html>
1.1采用IO流方式接收
@ResponseBody
@RequestMapping("/uploads")
public JSON upload(@RequestParam(value = "myFile",required = false)MultipartFile upfile,HttpServletRequest request) throws IOException {
Map<String,Object> ret = new HashMap<>();
String filePath = "D:/upload/";
String fileName = upfile.getName();
Long fileSize = upfile.getSize();
String fileType = upfile.getContentType();
//String fileNameType = fileName.substring(fileName.lastIndexOf("."+1));
String savePath = filePath + upfile.getOriginalFilename();
//第一种,采用流方式
// InputStream inputStream = upfile.getInputStream();
InputStream inputStream = request.getInputStream();
byte[] bytes = new byte[1024];
FileOutputStream fileOutputStream = new FileOutputStream(savePath);
int size = 0;
while((size = inputStream.read(bytes)) != -1){
fileOutputStream.write(bytes,0,size);
fileOutputStream.flush();
}
if(!(new File(savePath).getParentFile().exists())){
new File(savePath).getParentFile().mkdirs();
}
if(StringUtils.isEmpty(savePath)){
ret.put("state","上传失败");
ret.put("url",savePath);
JSON aa = (JSON) JSON.toJSON(ret);
return aa;
}
else{
ret.put("state","SUCCESS");
ret.put("url",savePath);
JSON aa = (JSON) JSON.toJSON(ret);
return aa;
}
}
1.2采用multipartFile的transferTo方法
@ResponseBody
@RequestMapping("/uploads")
public JSON upload(@RequestParam(value = "myFile",required = false)MultipartFile upfile,HttpServletRequest request) throws IOException {
Map<String,Object> ret = new HashMap<>();
String filePath = "D:/upload/";
String fileName = upfile.getName();
Long fileSize = upfile.getSize();
String fileType = upfile.getContentType();
//String fileNameType = fileName.substring(fileName.lastIndexOf("."+1));
String savePath = filePath + upfile.getOriginalFilename();
File file = new File(savePath);
upfile.transferTo(file);
if(StringUtils.isEmpty(savePath)){
ret.put("state","上传失败");
ret.put("url",savePath);
JSON aa = (JSON) JSON.toJSON(ret);
return aa;
}
else{
ret.put("state","SUCCESS");
ret.put("url",savePath);
JSON aa = (JSON) JSON.toJSON(ret);
return aa;
}
}
1.3从request请求中获取multipartFile实例
@RequestMapping(value = "/upload3")
public String doSecond(HttpServletRequest request, HttpSession session) throws IllegalStateException, IOException {
MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;//request强制转换注意
MultipartFile file = mRequest.getFile("myFile");
if (!file.isEmpty()) {
String fileName = file.getOriginalFilename();
if (!(StringUtils.isEmpty(fileName))) {// 因为最后一个添加的控件没有上传相应的内容
String uuid = UUID.randomUUID().toString();
String fileType = fileName.substring(fileName
.lastIndexOf("."));
// 使用字符替换图片名称,防止乱码
String tempName = uuid.substring(1, 10) + fileType;
/*uploadFilePath = fileRootHelper.getOrigImage() + tempName;
File uploadfile = new File(basepath
+ uploadFilePath);// 上传地址*/
String path = "e://";
File file2 = new File(path, tempName);
//File mir = new File(basepath + fileRootHelper.getOrigImage());// 文件路径
/*if (!mir.exists()) {
mir.mkdirs();
}*/
file.transferTo(file2);// 开始上传
}
}
return "test2";
}
1.4从request请求中获取多个multipartFile实例
@RequestMapping(value = "/upload9")
public String doEight(HttpServletRequest request, HttpSession session,Model model) throws IllegalStateException, IOException {
List<MultipartFile> list_files=((MultipartHttpServletRequest)request).getFiles("myfile");
if(list_files.isEmpty()){
model.addAttribute("result_multifile", "文件为空");
return "index";
}
InputStream inputStream = null;
OutputStream outputStream = null;
String path = "d:/upload/";
for (MultipartFile file : list_files) {
try {
inputStream = file.getInputStream();
String fileName = file.getOriginalFilename();
File targetFile = new File(path + fileName);
if(!targetFile.getParentFile().exists()){
targetFile.getParentFile().mkdir();
}
outputStream = new FileOutputStream(targetFile);
FileCopyUtils.copy(inputStream, outputStream);
model.addAttribute("result_multifile", "上传成功");
} catch (IOException e) {
e.printStackTrace();
model.addAttribute("result_multifile", "上传失败");
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "test2";
}
1.5文件名重复的多文件上传
@RequestMapping(value = "/upload5")
public String doFourth(HttpServletRequest request, HttpSession session) throws IllegalStateException, IOException {
List<MultipartFile> files = new ArrayList<MultipartFile>();
try {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
if (request instanceof MultipartHttpServletRequest) {
// 将request变成多部分request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator<String> iter = multiRequest.getFileNames();
// 检查form中是否有enctype="multipart/form-data"
if (multipartResolver.isMultipart(request) && iter.hasNext()) {
// 获取multiRequest 中所有的文件名
while (iter.hasNext()) {
// 一次遍历所有文件
// MultipartFile file =
// multiRequest.getFile(iter.next().toString());
// if (file != null) {
// files.add(file);
// }
// 适配名字重复的文件
List<MultipartFile> fileRows = multiRequest
.getFiles(iter.next().toString());
if (fileRows != null && fileRows.size() != 0) {
for (MultipartFile file : fileRows) {
if (file != null && !file.isEmpty()) {
String name = file.getOriginalFilename();
File file2 = new File("e://"+name);
file.transferTo(file2);
files.add(file);
}
}
}
}
}
}
} catch (Exception ex) {
log.error("解析MultipartRequest错误", ex);
}
return files.toString();
}
1.6IO流或者文件资源访问器拷贝
//第六种 使用IO流进行文件上传
@RequestMapping(value = "/upload7")
public String doSixth(@RequestParam("myFile") MultipartFile file, HttpSession session, Model model) throws IllegalStateException, IOException {
//判断文件是否为空
if(file.isEmpty()){
model.addAttribute("result_singlefile", "文件为空");
return "test2";
}
//创建输入输出流
InputStream inputStream = null;
OutputStream outputStream = null;
try {
//指定上传的位置为 d:/upload/
String path = "e:/upload/";
//获取文件的输入流
inputStream = file.getInputStream();
//获取上传时的文件名
String fileName = file.getOriginalFilename();
//注意是路径+文件名
File targetFile = new File(path + fileName);
//如果之前的 String path = "d:/upload/" 没有在最后加 / ,那就要在 path 后面 + "/"
//判断文件父目录是否存在
if(!targetFile.getParentFile().exists()){
//不存在就创建一个
targetFile.getParentFile().mkdir();
}
//获取文件的输出流
outputStream = new FileOutputStream(targetFile);
//1.普通输入输出流
/*byte[] bytes = new byte[1024];
int size = 0;
while((size = inputStream.read(bytes)) != -1){
outputStream.write(bytes,0,size);
}*/
//2.缓冲输入输出流
/*BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
byte[] bytes = new byte[1024];
int size = 0;
while((size = bufferedInputStream.read(bytes)) != -1){
bufferedOutputStream.write(bytes,0,size);
}*/
//3.使用资源访问器FileCopyUtils的copy方法拷贝文件
FileCopyUtils.copy(inputStream, outputStream);
/*参数是通过源码
public static int copy(InputStream in, OutputStream out) throws IOException {
......
}
而得知的*/
//告诉页面上传成功了
model.addAttribute("result_singlefile", "上传成功");
} catch (IOException e) {
e.printStackTrace();
//出现异常,则告诉页面失败
model.addAttribute("result_singlefile", "上传失败");
} finally {
//无论成功与否,都有关闭输入输出流
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "test2";
}
1.7从源码层面进行修改
使用Fileupload方法进行文件上传,我用的是Springboot,默认有了MultipartFile解析了,所以需要先在配置文件中关掉
@RequestMapping(value = "/upload6")
public String doFifth(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//得到上传文件的保存目录。 将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
// String realPath = this.getServletContext().getRealPath("/upload");// /WEB-INF/files
String realPath = "e://upload/";
System.out.println("文件存放位置:"+realPath);
//设置临时目录。 上传文件大于缓冲区则先放于临时目录中
String tempPath = "E:\\tempPath";
System.out.println("临时文件存放位置:"+tempPath);
//判断存放上传文件的目录是否存在(不存在则创建)
File f = new File(realPath);
if(!f.exists()&&!f.isDirectory()){
System.out.println("目录或文件不存在! 创建目标目录。");
f.mkdir();
}
//判断临时目录是否存在(不存在则创建)
File f1 = new File(tempPath);
if(!f1.isDirectory()){
System.out.println("临时文件目录不存在! 创建临时文件目录");
f1.mkdir();
}
/**
* 使用Apache文件上传组件处理文件上传步骤:
*
* */
//1、设置环境:创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置上传文件的临时目录
factory.setRepository(f1);
//2、核心操作类:创建一个文件上传解析器。
ServletFileUpload upload = new ServletFileUpload(factory);
//解决上传"文件名"的中文乱码
upload.setHeaderEncoding("UTF-8");
//3、判断enctype:判断提交上来的数据是否是上传表单的数据
if(!ServletFileUpload.isMultipartContent(req)){
System.out.println("不是上传文件,终止");
//按照传统方式获取数据
return "";
}
//==获取输入项==
// //限制单个上传文件大小(5M)
// upload.setFileSizeMax(1024*1024*4);
// //限制总上传文件大小(10M)
// upload.setSizeMax(1024*1024*6);
//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> items =upload.parseRequest(req);
for(FileItem item:items){
//如果fileitem中封装的是普通输入项的数据(输出名、值)
if(item.isFormField()){
String filedName = item.getFieldName();//普通输入项数据的名
//解决普通输入项的数据的中文乱码问题
String filedValue = item.getString("UTF-8");//普通输入项的值
System.out.println("普通字段:"+filedName+"=="+filedValue);
}else{
//如果fileitem中封装的是上传文件,得到上传的文件名称,
String fileName = item.getName();//上传文件的名
//多个文件上传输入框有空 的 异常处理
if(fileName==null||"".equals(fileName.trim())){ //去空格是否为空
continue;// 为空,跳过当次循环, 第一个没输入则跳过可以继续输入第二个
}
//注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
//处理上传文件的文件名的路径,截取字符串只保留文件名部分。//截取留最后一个"\"之后,+1截取向右移一位("\a.txt"-->"a.txt")
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
//拼接上传路径。存放路径+上传的文件名
String filePath = realPath+"\\"+fileName;
//构建输入输出流
InputStream in = item.getInputStream(); //获取item中的上传文件的输入流
OutputStream out = new FileOutputStream(filePath); //创建一个文件输出流
//创建一个缓冲区
byte b[] = new byte[1024];
//判断输入流中的数据是否已经读完的标识
int len = -1;
//循环将输入流读入到缓冲区当中,(len=in.read(buffer))!=-1就表示in里面还有数据
while((len=in.read(b))!=-1){ //没数据了返回-1
//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath+"\\"+filename)当中
out.write(b, 0, len);
}
//关闭流
out.close();
in.close();
//删除临时文件
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
item.delete();//删除处理文件上传时生成的临时文件
System.out.println("文件上传成功");
}
}
} catch (FileUploadException e) {
//e.printStackTrace();
throw new RuntimeException("服务器繁忙,文件上传失败");
}
return "test2";
}