MutipartFile使用过程中遇到的坑
MutipartFile是spring里面定义的接口,它封装了用户在上传图片时所包含的所有信息,但是有些时候我们要将file转换成MutipartFile,才能在保持原有代码逻辑的情况下方便代码的调整,但是file不能直接转换成MutipartFile,现在就要教大家如何将file转换成MutipartFile。
接口地址:
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/mock/web/MockMultipartFile.html
使用postman测图片上传接口注意事项
1.1 在headers 请求头中不需要传入参数
1.2 body中选择form-data类型
后台代码请求示例
1. controller层中代码如下,非常简单, 多张图片上传的话直接List<MultipartFile>
直接传入一个list就好了。
@RequestMapping(value = {"uploadLicensePhoto"})
@ResponseBody
public ResponseMessage uploadLicensePhoto(@RequestParam("file") List<MultipartFile> multipartFiles, HttpServletRequest request, HttpServletResponse response) {String businessLicensePath = null;String filePath = null;if (multipartFiles == null) {return ResponseMessage.normalFailedBack(CommonConstants.RESULT_ERROR);}try {businessLicensePath = outOrgBusinessLicensePath(multipartFiles, filePath);} catch (Exception e) {logger.info("注册异常,异常信息:{}" + e);}return ResponseMessage.sucsessBack(businessLicensePath);
}
2. 这里我写了一个方法 为了方便业务层调用outOrgBusinessLicensePath
3. 保存到磁盘中方法
public String imageUploadPath(String path) {File dir = new File(path);//确保路径切实有效if (!dir.exists()) {dir.mkdirs();}return path;}
4. 压缩文件。由于上传上来的照片比较大 可以做一层压缩处理
public String store(MultipartFile mf, String path, boolean realitive) {path += File.separator + IdGen.uuid() + mf.getOriginalFilename().substring(mf.getOriginalFilename().lastIndexOf("."));File file = new File(path);try {CommonsMultipartFile cf = (CommonsMultipartFile) mf;DiskFileItem fi = (DiskFileItem) cf.getFileItem();fi.getStoreLocation();// mf.transferTo(file); 文件压缩至200k左右存放磁盘Thumbnails.of( fi.getStoreLocation()).size(2000, 3000).toFile(file);} catch (IllegalStateException | IOException e) {logger.error("IllegalStateException异常,异常信息:{}" + e);}return path;}
图片上传并回显
1.获取图片存放的路径,
public ResponseMessage getLicensePhoto(HttpServletRequest request, HttpServletResponse response) {try {//图片存放路径String licensePicture = request.getParameter("licensePicture");if (StringUtils.isNotEmpty(licensePicture)) {//获取照片地址String[] urls = licensePicture.split(",");if (urls != null && !"".equals(urls)) {for (String url : urls) {//读取图片baseUploadService.imageRead(url, response);}}}
2. 将图片以IO流形式传输response(得到向客户端输出二进制数据的对象 response.getOutputStream())
public String imageRead(String path, HttpServletResponse response) {response.setCharacterEncoding("UTF-8");response.reset();// 设置返回的文件类型 这一步很重要,如果不设置预览正常,但是前天FileReader.src操作后就有问题。response.setContentType("image/jpeg;charset=UTF-8");response.setHeader("Content-Disposition", "inline; filename=\"" + path + "\"");FileInputStream is;try {is = new FileInputStream(path);// 得到文件大小int i = is.available();byte data[] = new byte[i];// 读数据is.read(data);is.close();// 得到向客户端输出二进制数据的对象OutputStream toClient = response.getOutputStream();// 输出数据toClient.write(data);toClient.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();logger.info("获取图片异常,异常信息:{}" + e);}return null;
}
介绍了图片上传以及回显的方法,中间遇到的坑在哪里呢?
1坑:win系统下和liunx系统下路径地址是有区别的
Win系统支持双// 但是liunx系统是不支持的,所以拼接/的时候要注意
可以使用File.separator来解决/的问题
2.坑:图片上传绝对路径和相对路径的问题
2.1图片直接存放到tomcat服务器下,照片是可以直接回显的
2.2图片读到磁盘中则需要以流的形式传给前端显示
3.坑: ?传参的时候一定要注意特殊字符
十六进制值 1. + URL 中+号表示空格%2B
2. 空格URL中的空格可以用+号或者编码%20
3. / 分隔目录和子目录%2F
4. ? 分隔实际的URL 和参数%3F
5. % 指定特殊字符%25
6. # 表示书签%23
7. & URL 中指定的参数间的分隔符%26
8. = URL 中指定参数的值%3D
特殊字符的含义
URL编码
符号 | 解释 | 转义 |
# | 用来标志特定的文档位置 | %23 |
% | 对特殊字符进行编码 | %25 |
& | 分隔不同的变量值对 | %26 |
+ | 在变量值中表示空格 | %2B |
/ | 表示目录路径 | %2F |
\ | 表示目录路径 | %5C |
= | 用来连接键和值 | %3D |
? | 表示查询字符串的开始 | %3F |
空格 | 空格 | %20 |
. | 句号 | %2E |
: | 冒号 | %3A |