使用ajax上传文件,不跳转页面,解决下载文件时中文乱码问题
该demo使用的bootstrap,vue.js显示文件列表。大家可根据自己的需求去取得上传和下载文件的核心代码运用到自己的demo中
直接附代码
后端代码
package com.blog.controller;
import com.blog.entity.UploadFile;
import com.blog.service.UploadFileService;
import com.blog.util.ResultUtil;
import com.google.gson.Gson;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* (UploadFile)表控制层
*
* @author fang
* @since 2020-07-28 16:34:48
*/
@Controller
@RequestMapping("uploadFile")
public class UploadFileController {
/**
* 创建日志记录器
*/
static Logger logger= Logger.getLogger(UploadFile.class);
/**
* 服务对象
*/
@Resource
private UploadFileService uploadFileService;
/**
* 上传资源
* @param uploadFileName 实例对象
* @param uploadFile 实例对象
* @param request 请求对象
* @return 数据接口
*/
@RequestMapping(value = "uploadFile.action")
@ResponseBody
public HashMap<String,Object> uploadFile(MultipartFile uploadFileName, UploadFile uploadFile, HttpServletRequest request) {
if (null==uploadFileName){
return ResultUtil.getResult("1","未知错误!");
}
uploadFile.setFileUploadTime(new Date());
//取得用户自定义文件名
String oldName=uploadFile.getFileName();
if (null==oldName||"".equals(oldName)){
oldName=uploadFileName.getOriginalFilename();
}
//创建上传文件地址
String dateString=new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String path=request.getServletContext().getRealPath("/upload");
File file=new File(path,dateString);
logger.info(new Gson().toJson(uploadFile));
if (!file.exists()){
boolean m=file.mkdirs();
if (!m){
logger.error("上传文件目录创建失败!");
return ResultUtil.getResult("1","未知错误!");
}
}
//开始上传文件
String originalFilename=uploadFileName.getOriginalFilename();
//文件重新命名
logger.debug(originalFilename);
String fileNewName=new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
+originalFilename.substring(originalFilename.lastIndexOf("."));
//格式化文件大小格式
DecimalFormat dfs=new DecimalFormat("#.##");
String fileSize=dfs.format(uploadFileName.getSize()/(1024*1024*1.0))+"MB";
//取得文件的url
String url=File.separator+"upload"+File.separator+dateString+File.separator+fileNewName;
//封装对象
uploadFile.setFileSize(fileSize);
uploadFile.setFileName(oldName);
uploadFile.setFileNewName(fileNewName);
uploadFile.setFileUrl(url);
try {
//开始进行文件上传
uploadFileName.transferTo(new File(path+File.separator+dateString,fileNewName));
} catch (IOException e) {
logger.error("上传文件错误:"+e.getMessage());
return ResultUtil.getResult("1","上传文件失败");
}
//将文件信息存入数据库
Boolean flag= uploadFileService.insert(uploadFile);
if (flag){
logger.info(new Gson().toJson(uploadFile));
return ResultUtil.getResult("0","上传成功");
}
logger.error("文件信息保存数据库失败");
return ResultUtil.getResult("1","上传文件失败");
}
/**
* 查询所有上传的文件
* @return 文件集合
*/
@RequestMapping(value = "findAllFile.action")
@ResponseBody
public HashMap<String,Object> findAllFile(){
//查询数据库
List<UploadFile> list=uploadFileService.queryAll(null);
if (null==list){
return ResultUtil.getResult("1","查询失败");
}
return ResultUtil.getResult("0","成功",list);
}
@RequestMapping("/download.action")
public void download(HttpServletRequest request, HttpServletResponse response, Integer fileId) {
UploadFile fileEntity = uploadFileService.queryById(fileId);
if (null==fileEntity){
return;
}
String path=request.getServletContext().getRealPath(fileEntity.getFileUrl());
logger.info(path);
File file = new File(path);
logger.info(file.exists());
String fileName = fileEntity.getFileName();
try {
fileName= URLEncoder.encode(fileName,"utf-8");
} catch (UnsupportedEncodingException e) {
logger.error("文件中文名处理失败:"+e.getMessage());
}
response.setCharacterEncoding("utf-8");
//设置响应类型,告诉浏览器打开方式
response.setContentType("multipart/form-data");
///response.setContentType("application/x-msdownload");
//设置消息头
response.setHeader("Content-Disposition","attachment;filename="+ fileName);
//取得输出流
OutputStream out=null;
try {
out=response.getOutputStream();
if (null==out){
return;
}
FileUtils.copyFile(file,out);
out.close();
} catch (IOException e) {
logger.error("空指针异常:"+e.getMessage());
}
}
}
前端代码
上传
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="static/js/jquery.min.js"></script>
<title>上传文件</title>
</head>
<body>
<div>
<form id="uploadForm" method="post" enctype="multipart/form-data" onsubmit="return false" >
<label>
请选择资源:<input id="e" type="file" title="请选择文件" name="uploadFileName"/>
</label>
<br>
<label>
资源名称:<input type="text" placeholder="带后缀名" name="fileNewName"/>
</label>
<br>
<label>
所需积分:<input type="number" name="downloadIntegral"/>
</label>
<br>
<label>
资源简述:
<textarea cols="30" style="resize: none" name="fileDescription" ></textarea>
</label>
<br>
<label>
<input type="button" value="提交" id="btnUpload" />
</label>
</form>
</div>
</body>
<script src="static/js/config.js"></script>
<script>
$(function () {
$("#btnUpload").bind("click",function () {
//取得form表单
var form=document.getElementById("uploadForm");
//创建FormData 对象 异步上传二进制文件
var formDate=new FormData(form);
$.ajax({
url:url+"/uploadFile/uploadFile.action",
type:"post",
data:formDate,
//默认情况下,processData 的值是 true,其代表以对象的形式上传的数据都会被转换为字符串的形式上传。而当上传文件的时候,则不需要把其转换为字符串,因此要改成false
processData:false,
// ajax 中 contentType 设置为 false 是为了避免 JQuery 对其操作,从而失去分界符,而使服务器不能正常解析文件。
contentType:false,
success:function(data){
if (data.code==="0"){
alert(data.msg);
}else{
alert(data.msg)
}
}
});
})
})
</script>
</html>
显示
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<base href="http://localhost/">
<head>
<meta charset="UTF-8">
<!--导入jquery-->
<script src="static/js/jquery.min.js"></script>
<!--导入bootstrap-->
<link rel="stylesheet" href="static/bootstrap3/css/bootstrap.min.css">
<script src="static/bootstrap3/js/bootstrap.min.js"></script>
<title>资源列表</title>
</head>
<body>
<div class="container" id="fileApp">
<div class="row clearfix">
<div class="col-md-12 column">
<a href="uploadFile.html">去上传</a>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover">
<thead>
<tr class="success">
<th>
序号
</th>
<th>
资源名称
</th>
<th>
上传时间
</th>
<th>
大小
</th>
<th>
所需积分
</th>
<th>
描述
</th>
<th>
操作
</th>
</tr>
</thead>
<tbody>
<tr v-for="(file,index) in fileList">
<td>
{{index+1}}
</td>
<td>
{{file.fileName}}
</td>
<td>
{{file.fileUploadTime}}
</td>
<td>
{{file.fileSize}}
</td>
<td>
{{file.downloadIntegral}}
</td>
<td>
{{file.fileDescription}}
</td>
<td>
<button type="button" v-on:click="download(file.fileId)" class="btn-info">下载</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
<script src="static/js/vue.min.js"></script>
<script src="static/js/config.js"></script>
<script src="fileShow.js"></script>
</html>
上传的js代码
var vue= new Vue({
el:"#fileApp",
created:function () {
findAllFile();
},
methods:{
download:function (fileId) {
window.location.href=url+"/uploadFile/download.action?fileId="+fileId
}
},
data:{
fileList:{}
}
});
function findAllFile() {
$.post("http://localhost/uploadFile/findAllFile.action",{},function (data) {
if (data.code==="0"){
vue.fileList=data.data
}
})
}