SSM+Layui的文件上传
文件上传,例如图片的文件上传,不会将图片等文件存入数据库,将文件存入数据库读取过程是一个很耗费时间的工作,所以我们存的都是文件路径,所以文件上传后会把源文件下载到一个另一个位置,数据库存入文件下载的位置,理解基本流程后就开始做一下文件上传进行测试。
准备工作
首先下载在layui官网下载好对应的layui版本放在web文件下,再者是ssm的基本配置。
在资源文件夹下建立file.properties一个存储文件上传后下载的路径的文件,这里file.properties文件内容是path=E:/upload/。这样准备工作做好了就可以进行详细的操作了。
详细步骤
做一个前端页面upload.jsp,(注意这里的js和css路径用自己项目的路径)内容如下,这里的前端全是Layui:
<html>
<head>
<title>文件上传</title>
<link rel="stylesheet" href="layui-v2.5.6/layui/css/layui.css" media="all">
</head>
<body style="padding: 20px">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
<legend>常规使用:普通图片上传</legend>
</fieldset>
<div class="layui-upload">
<button type="button" class="layui-btn" id="test1">上传图片</button>
<div class="layui-upload-list">
<img class="layui-upload-img" width="60" height="60" id="demo1">
<p id="demoText"></p>
</div>
</div>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
<legend>选完文件后不自动上传</legend>
</fieldset>
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-normal" id="test8">选择文件</button>
<button type="button" class="layui-btn" id="test9">开始上传</button></br>
<img src="" alt="" id="myimages">
</div>
<script src="layui-v2.5.6/layui/layui.js"></script>
<script type="text/javascript">
layui.use(['jquery','form','layer','element','upload'], function() {
var form = layui.form;
var $ = layui.jquery;
var layer = layui.layer;
var upload=layui.upload;
//渲染文件上传
//普通图片上传
var uploadInst = upload.render({
elem: '#test1'
,accept:'images'
,acceptMime:'images/*'
,auto:true //是否自动上传
,field:'mf' //表单的name
,url: '/layui/file/uploadFile.action' //改成您自己的上传接口
,before: function(obj){
//预读本地文件示例,不支持ie8
obj.preview(function(index, file, result){
$('#demo1').attr('src', result); //图片链接(base64)
});
}
,done: function(res){
//如果上传失败
if(res.code > 0){
return layer.msg('上传失败');
}
//上传成功
}
,error: function(){
//演示失败状态,并实现重传
var demoText = $('#demoText');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
demoText.find('.demo-reload').on('click', function(){
uploadInst.upload();
});
}
});
//不自动上传
upload.render({
elem:'#test8',
url:'/layui/file/uploadFile.action',
field:'mf'
,accept:'images'
,acceptMime:'images/*'
,auto:false ,//是否自动上传
bindAction:'#test9'
,done:function(res){
if(res.code > 0){
return layer.msg('上传失败');
}else{
//上传成功
layer.msg("上传成功")
alert(res.data.src)
$('#myimages').attr('src',res.data.src)
}
}
,error: function(){
layer.msg("服务器异常")
}
})
})
</script>
</body>
</html>
再多加一些springmvc.xml的配置,一个是支持文件上传,一个是静态文件的放行:
<!-- 配置springmvc对文件上传的支持 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置文件名的编码 -->
<property name="defaultEncoding" value="utf-8"></property>
<!-- 配置最上传文件的支持 20M -->
<property name="maxUploadSize" value="20971520"></property>
<!-- 设置文件上传的临时目录 -->
<property name="uploadTempDir" value="upload/temp" />
</bean>
<!-- 配置静态文件放行 -->
<mvc:default-servlet-handler />
前端和配置完成后,我们再写一个FileController的控制器类用来响应jsp的数据请求。
@Controller
@RequestMapping("file")
public class FileController {
/**
* 添加
*
* @throws IOException
* @throws IllegalStateException
*/
@RequestMapping("uploadFile")
//这个注解返回的是json数据
@ResponseBody
public Map<String,Object> uploadFile(MultipartFile mf) throws IOException {
// 文件上传的父目录
String parentPath = AppFileUtils.PATH;
// 得到当前日期作为文件夹名称,这用随机数的类给下载的文件夹取新名字
String dirName = RandomUtils.getCurrentDateForString();
// 构造文件夹对象
File dirFile = new File(parentPath, dirName);
if (!dirFile.exists()) {
dirFile.mkdirs();// 创建文件夹
}
// 得到文件原名
String oldName = mf.getOriginalFilename();
// 根据文件原名得到新名,这用随机数的类给下载的文件取新名字
String newName = RandomUtils.createFileNameUseTime(oldName);
File dest = new File(dirFile, newName);
//把文件下载好了
mf.transferTo(dest);
//这里开始封装前端layui界面需要的json数据,详细layui的json数据格式可以再layui的文件上传的官方文档中查看
Map<String,Object> map=new HashMap<>();
map.put("code",0);
map.put("msg","");
Map<String,Object> data=new HashMap<>();
data.put("src", "file/downloadFile.action?path="+dirName+"/"+newName);
map.put("data",data);
return map;
}
/**
* 不下载只显示
*/
@RequestMapping("downloadShowFile")
public ResponseEntity<Object> downloadShowFile(String path, HttpServletResponse response) {
//这里做一个区分如果第三个参数为"",只是在浏览器显示
return AppFileUtils.downloadFile(response, path, "");
}
/**
* 下载图片
* @param path
* @param response
* @return
*/
@RequestMapping("downloadFile")
public ResponseEntity<Object> downloadFile(String path, HttpServletResponse response) {
//这里做一个区分如果第三个参数不为"",在浏览器下载
String oldName="";
return AppFileUtils.downloadFile(response, path, oldName);
}
}
这里先写上面代码缺少的AppFileUtils类显示图片到网页,稍后奉上给文件取名的随机函数的类:
public class AppFileUtils {
/**
* 得到文件上传的路径
*/
public static String PATH="E:/upload/";
static {
//取到文件夹下的file.properties,也就是准备工作的file.properties文件,他是问见下载的路径
InputStream stream = AppFileUtils.class.getClassLoader().getResourceAsStream("file.properties");
//这个东西可厉害了,可以将file.properties文件下的内容path=E:/upload/封装成了键值对path:E:/upload/
Properties properties=new Properties();
try {
properties.load(stream);
//现在路径就是E:/upload/了
PATH=properties.getProperty("path");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 文件下载
* @param response
* @param path
* @param oldName
* @return
*/
public static ResponseEntity<Object> downloadFile(HttpServletResponse response, String path, String oldName) {
//4,使用绝对路径+相对路径去找到文件对象
File file=new File(AppFileUtils.PATH,path);
//5,判断文件是否存在
if(file.exists()) {
try {
try {
//如果名字有中文 要处理编码
oldName=URLEncoder.encode(oldName, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
//把file转成一个bytes
byte [] bytes=FileUtils.readFileToByteArray(file);
HttpHeaders header=new HttpHeaders();
//封装响应内容类型(APPLICATION_OCTET_STREAM 响应的内容不限定)
header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//设置下载的文件的名称
header.setContentDispositionFormData("attachment", oldName);
//创建ResponseEntity对象
ResponseEntity<Object> entity=
new ResponseEntity<Object>(bytes, header, HttpStatus.CREATED);
return entity;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}else {
PrintWriter out;
try {
out = response.getWriter();
out.write("文件不存在");
out.flush();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
最后的最后,是RandomUtils类,给文件取名字的。
public class RandomUtils {
private static SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd");
private static SimpleDateFormat sdf2=new SimpleDateFormat("yyyyMMddHHmmssSSS");
private static Random random=new Random();
/**
* 得到当前日期,这个是FileController中给文件夹取名字的
*/
public static String getCurrentDateForString() {
return sdf1.format(new Date());
}
/**
* 生成文件名使用时间+4位随机数
* @param suffix 文件名称,这个是FileController中给文件取名字的
*/
public static String createFileNameUseTime(String fileName) {
String fileSuffix=fileName.substring(fileName.lastIndexOf("."),fileName.length());
String time=sdf2.format(new Date());
Integer num=random.nextInt(9000)+1000;
return time+num+fileSuffix;
}
/**
}
总结
以上就是文件上传的基本操作了。