【SpringMVC】上传并显示图片
Spring配置文件上传功能
基于Servelt的配置
在继承了AbstractAnnotationConfigDispatcherServletInitializer的类中重写customizeRegistration方法。
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
// F:/tmp/是用于临时存储上传文件的地方
registration.setMultipartConfig(new MultipartConfigElement("F:/tmp/"));
}
这里只是一个比较简单的例子,实际上MultipartConfigElement的构造器还能指定上传文件的最大值,最大的请求值,文件的最小值。
单图片上传
上传文件需要在表单添加enctype="multipart/form-data"
,一个基础的单文件上传页面
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="imageFile"/>
<button type="submit">提交</button>
</form>
FileUploadController
@Controller
public class FileUploadController {
@PostMapping("/upload")
public String uploadFile(@RequestParam("imageFile") MultipartFile imageFile, HttpSession session) throws IOException {
String fileName = imageFile.getOriginalFilename();
if (!imageFile.isEmpty()) {
String filePathPrefix = session.getServletContext().getRealPath("./");
imageFile.transferTo(new File(filePathPrefix, "/static/uploads/" + fileName));
session.setAttribute("imagepath", "/static/uploads/" + fileName);
return "redirect:/showimage";
}
return "upload";
}
@RequestMapping(value = "/upload", method = RequestMethod.GET)
public String getUploadForm() {
return "upload";
}
}
@PostMapping
是@RequestMapping(..., method=RquestMethod.POST)
的缩写,表示处理的是post方法。@RequestParam
注解用于绑定提交的参数,括号里的imageFile和表单中是一样的,这里的参数类型为MultipartFile,表示上传的是一个文件,在处理的时候相比byte流会比较方便。上面代码还有很多问题比如没有判断重名文件,没有检查文件后缀,文件大小等问题,需要完善。
MultipartFile
- getBytes() 获取byte[]数组
- getContentType() 获取文件类型
- getOriginalFilename() 获取上传文件的名字
- getSize() 获取文件大小
- isEmpty() 文件是否为空
- transferTo() 把文件转存到指定的位置
注意点
这里提到的是在使用__Intellij Idea__开发时遇到的问题:
-
如何获取部署到本地服务器上之后的项目路径?:
String filePathPrefix = session.getServletContext().getRealPath("./");
在我的电脑上是
"F:/tomcat/webapps/ROOT"
,intellij在部署时会将target文件夹下的文件放在这个位置 -
imageFile.transferTo(new File(filePathPrefix, "/static/uploads/" + fileName));
将文件转存到
F:/tomcat/webapps/ROOT/static/uploads/
文件夹下。但实际操作的时候会发现出现找不到路径的错误,而我已经在src/main/webapp下建立了static/uploads文件夹。经过在网上查资料,原来是需要自己手动在target文件夹下新建static/uploads文件夹,不然打包的时候服务器下不会有相应的文件夹。
图片显示
在FileUploadController中可以看到,在session中设置了imagepath属性,值为/static/uploads/filename
,并重定向到/showimage
ImageShowController
@Controller
public class ImageShowController {
@RequestMapping("/showimage")
public String showImage(HttpServletRequest request, Model model, HttpSession session) {
String imagePath = (String) session.getAttribute("imagepath");
model.addAttribute("imagepath", imagePath);
return "uploaded";
}
}
uploaded.jsp
<body>
<img src="${imagepath}" alt="">
</body>
前端做的比较简单,只需要src的值设置正确的路径就行了
困惑
看到网上很多blog说springmvc在获取静态资源时需要添加
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
或者
<mvc:resources location="/static/ mapping="/static/**"/>
这里两个星号是因为如果/static/下还有文件夹,只使用/static/*,不会匹配该文件夹里的内容
但实际操作的时候一个都没添加也没出现问题,不知道是不是我用的是Spring 5的关系…