Spring Boot (3) 文件上传

Spring Boot (3) 文件上传

Scroll Down

文件上传

单文件上传

upload.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>单文件上传</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadFile" value="请选择文件"/>
    <input type="submit" value="上传"/>
</form>
</body>
</html>

FileUploadController.java

/**
 * 文件上传接口
 *
 * @Auther: MaWenyi
 * @Date: 2019/6/24
 * @Description: com.iscolt.multipart.web.controller
 * @version: 1.0
 */
@RestController
public class FileUploadController {

    // 格式化日期
    SimpleDateFormat simpleFormatter = new SimpleDateFormat("yyyy/MM/dd");

    @PostMapping("upload")
    public String upload(MultipartFile uploadFile, HttpServletRequest request) {
        String realPath = request.getServletContext().getRealPath("/uploadFile/");
        //String realPath = "src/main/resources/" + IMG_PATH_PREFIX + "/";
        System.out.println(realPath);
        String format = simpleFormatter.format(new Date());
        File folder = new File(realPath + format);
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }
        String oldName = uploadFile.getOriginalFilename();
        String newName = UUID.randomUUID().toString()
                + oldName.substring(oldName.lastIndexOf("."), oldName.length());
        try {
            uploadFile.transferTo(new File(folder, newName));
            String filePath = request.getScheme()
                    + "://"
                    + request.getServerName()
                    + ":"
                    + request.getServerPort()
                    + "/uploadFile/"
                    + format
                    + "/"
                    + newName;
            return "<a href='" + filePath + "'>"+ filePath +"</a>";
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "上传失败!";
    }
}

细节配置

# 是否开启文件上传支持
spring.servlet.multipart.enabled=true
# 写入磁盘阈值, 默认为0
spring.servlet.multipart.file-size-threshold=0
# 临时保存位置
spring.servlet.multipart.location=E:\\temp
# 上传时单文件的总大小, 默认为1MB
spring.servlet.multipart.max-file-size=1MB
# 上传时多文件的总大小, 默认为10MB
spring.servlet.multipart.max-request-size=10MB
# 文件是否延迟解析, 默认为false
spring.servlet.multipart.resolve-lazily=false

多文件上传

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>单/多 文件上传</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadFile" value="请选择文件"/>
    <input type="submit" value="单上传"/>
</form>
<form action="/uploads" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadFiles" value="请选择文件" multiple/>
    <input type="submit" value="多上传"/>
</form>
</body>
</html>
/**
 * 多文件上传
 *
 * @param uploadFiles
 * @param request
 * @return
 */
@PostMapping("uploads")
public String upload(MultipartFile[] uploadFiles, HttpServletRequest request) {
	String realPath = request.getServletContext().getRealPath("/uploadFile/");
	//String realPath = "src/main/resources/" + IMG_PATH_PREFIX + "/";
	System.out.println(realPath);
	String format = simpleFormatter.format(new Date());
	File folder = new File(realPath + format);
	if (!folder.isDirectory()) {
		folder.mkdirs();
	}
	String filePath = "";
	if (uploadFiles.length > 0) {
		for (int i=0; i<uploadFiles.length; i++){
			String oldName = uploadFiles[i].getOriginalFilename();
			String newName = UUID.randomUUID().toString()
					+ oldName.substring(oldName.lastIndexOf("."), oldName.length());
			try {
				uploadFiles[i].transferTo(new File(folder, newName));
				filePath = request.getScheme()
						+ "://"
						+ request.getServerName()
						+ ":"
						+ request.getServerPort()
						+ "/uploadFile/"
						+ format
						+ "/"
						+ newName
						+ "<br>"
						+ filePath;
				System.out.println(filePath);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return filePath;
	}
	return "上传失败!";
}

@ControllerAdvice

@ ControllerAdvice 主要用来处理全局数据, 一般搭配@ExceptionHandler、@ModelAttribute 以及@InitBinder 使用.

全局异常处理

/**
 * 全局异常处理
 *
 * @Auther: MaWenyi
 * @Date: 2019/6/25
 * @Description: com.iscolt.multipart
 * @version: 1.0
 */
@RestControllerAdvice
public class CustomExeptionHandler {

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ModelAndView uploadException(MaxUploadSizeExceededException e) throws IOException {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "上传文件大小超过限制");
        mv.setViewName("error");
        return mv;
    }
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>异常显示</title>
</head>
<body>
<div th:text="${msg}"></div>
</body>
</html>

添加全局数据

@ControllerAdvice 是一个全局数据处理组件, 因此也可以在@ControllerAdvice中配置全局数据, 使用@ModelAttribute注解进行配置.

/**
 * 添加全局数据
 *
 * @Auther: MaWenyi
 * @Date: 2019/6/25
 * @Description: com.iscolt.multipart.config
 * @version: 1.0
 */
@ControllerAdvice
public class GlobalConfig {

    @ModelAttribute(value = "info")
    public Map<String, String> userInfo() {
        HashMap<String, String> map = new HashMap<>();
        map.put("username", "idler");
        map.put("gender", "男");
        return map;
    }
}

Controller 示例代码如下:

/**
 * 验证全局数据
 *
 * @Auther: MaWenyi
 * @Date: 2019/6/25
 * @Description: com.iscolt.multipart.web.controller
 * @version: 1.0
 */
@Controller
public class HelloController {

    /**
     * 拿全局变量
     *
     * @param model
     */
    @GetMapping("/hello")
    @ResponseBody
    public void hello(Model model) {
        Map<String, Object> map = model.asMap();
        Set<String> keySet = map.keySet();
        // 遍历
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            Object value =map.get(key);
            System.out.println(key + ">>>" + value);
        }
    }

    /**
     * 拿全局变量, 简单版
     *
     * @param model
     */
    @GetMapping("/helloEasy")
    @ResponseBody
    public void helloEasy(Model model) {
        Map<String, Object> map = model.asMap();
        System.out.println(map.get("info"));
    }

}

自定义错误页面

参考旧址

简单配置

resources下新建 error,新建404.html500.html4xx.html, 5xx.html

错误信息:

timestampstatuserrormessagepath
某时间404Not...信息/xxx

页面中 $ 获取即可, 例如${status}

复杂配置

自定义Error数据

继承DefaultErrorAttributes, 重写getErrorAttributes()

自定义Error视图

实现ErrorViewResolver接口, 重写resolveErrorView(), 返回ModelAndView

完全自定义

继承BasicErrorController 来实现自己的ErrorController

支付宝 微信