岁月悠悠,衰微只及肌肤;热忱抛却,颓唐必致灵魂
1. SSM配置
这里的重点在于文件的映射,很多人不理解。
在实际开发中,我们会把图片,视频文件等资源统一放到服务器的某个文件夹下便于管理。
不放在项目中的文件夹下,是因为如果每次项目重新打包部署,就会清空之前部署好的文件夹下的文件,非常不利于开发。
Q:那么映射是什么意思呢?
我们在实际存放文件的文件夹中,和我们访问的路径做一个映射。
例如:<mvc:resources location=“D:/bbb/” mapping="/aaa/**"/>
在D盘的 bbb文件夹中,我们放一个图片名为photo.jpg
这时,我们在访问 http://localhost:8080/aaa/photo.jpg 的时候,就可以访问到服务器上D盘bbb文件夹中的 photo.jpg 文件。
/aaa/**代表我们访问aaa下所有的文件都回去D盘的bbb文件夹中去寻找。
location为真实物理路径,mapping为虚拟映射路径。
<!-- 静态资源访问(不拦截此目录下的东西的访问) -->
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/img/" mapping="/img/**" />
<mvc:resources location="/fonts/" mapping="/fonts/**" />
<mvc:resources location="/WEB-INF/pages/error/" mapping="/WEB-INF/pages/error/**"/>
<mvc:resources location="/upload/" mapping="/upload/**"/>
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
2. 前端代码
为了代码简洁,我去掉了不必要的class样式。这里假设我传了三个属性,name,age和我们的file文件。
-
action:请求路径
-
method:请求方法为post请求
-
(重点)enctype:multipart/form-data 代表这份form表单不仅仅有文本数据,又有文件(img,video,MP3)等二进制数据,加了它才可以将文件传递给后台。
<form action="/uploadFile" method="post" enctype="multipart/form-data">
<input type="text" name="name">
<input type="text" name="age">
...
<input type="file" name="myfile"/>
</form>
3. 后端代码
@RequestMapping(value = "/uploadFile")
public void uploadFile(HttpSession session,
String name,
int age,
MultipartFile myfile) throws IllegalStateException, IOException{
// 1.文件名称
String oldFileName = myfile.getOriginalFilename(); //获取上传文件的原名
// 2.存储图片的物理路径
String file_path = session.getServletContext().getRealPath("upload");
// 3.上传图片
if(myfile!=null && oldFileName!=null && oldFileName.length()>0){
// 4.新的图片名称
String newFileName = UUID.randomUUID() + oldFileName.substring(oldFileName.lastIndexOf("."));
// 5.新图片
File newFile = new File(file_path+"/"+newFileName);
// 6.将内存中的数据写入磁盘
myfile.transferTo(newFile);
// 7.将文件名字保存到数据库,前端读取的时候会用到。或者可以把图片名称直接传给前端做一个图片的回显,这里大家自己操作。
}else{
log.info("File Error!")
}
}
这里假设我们传入一个png图片,名字叫 123.png
- 文件名称:123.png
- 存储图片的物理路径:为了方便起见,我把图片存放到了tomcat的target中。你也可以把路径改为 D:/xx/upload/,这里是我们接收文件的真实路径。
- 上传图片:这里对文件做了下判断,如果文件不为空,则执行下面的操作。
- 新图片名称:为了避免多人上传重复的文件名称,我把图片的名字做了处理,避免后面的人把前面的人的文件覆盖掉。保证名称的唯一性。
- 新图片:new一个文件
- 写入磁盘:上一步我们已经在真实路径new出了一个File,我们用transferTo方法,把前端传来的文件写进去。这一步结束后,我们的文件就在真实路径创建成功了!你可以去文件夹下查看文件有没有写入成功。
前端读取文件:
假设我们在数据库中请求到的图片路径通过Model的方式传给了前端。
<c:forEach var="item" items="${data}">
<img src="../upload/${data.imgUrl}" />
</c:forEach>
那么这时,我们就可以直接访问文件的虚拟地址,来访问到真实路径中的文件。
因为我这里直接放到了war包中,所以地址如上就可以访问到target中的文件。