zoukankan      html  css  js  c++  java
  • 32.再谈SpringBoot文件上传

    • Controller配置    

    以具体代码为通过时间为文件夹分类上传的文件

    /**
    * 
    * @Title: upload
    * @Description: 上传图片
    * @param file
    * @throws IOException    
    * @return String    
    * @throws
    */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public ResultBean<String> upload(@RequestParam(value = "file", required = false) MultipartFile file)
    throws IOException {
    
    
    byte[] bytes = file.getBytes();
    String originalFilename = file.getOriginalFilename();
    int indexOf = originalFilename.indexOf(".");
    String extend = originalFilename.substring(indexOf);
    String format = DateUtils.format(new Date(), DateUtils.YYYYMMDD);
    String nowFileName = DateUtils.format(new Date(), DateUtils.YYYYMMDDHHMMSS);
    String strPath = "upload/" + format;
    File path = new File(strPath);
    if (!path.exists()) {
    path.mkdirs();
    }
    // 这样默认上传文件就放在当前 项目路径下
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(strPath).append("/").append(nowFileName).append(extend);
    File name = new File(stringBuilder.toString());
    FileCopyUtils.copy(bytes, name);
    ResultBean<String> resultBean = new ResultBean<String>();
    resultBean.setData(stringBuilder.toString());
    return resultBean;
    }


             (上图为最后上传的效果)

    • application.properties
     ###########springboot文件上传
    #spring.http.multipart.location=upload
    #最大文件上传
    spring.http.multipart.max-file-size=1MB
    #最大请求
    spring.http.multipart.max-request-size=100MB
    • 上传出错捕获

    以下主要是,针对异步请求上传出错的捕获,捕获之后通过Redis发布与订阅者模式,将错误日志异步发送给订阅者,然后存储到elasticsearch中(以下代码中没有涉及)

    package org.niugang.exception;
    
    import java.io.IOException;
    import java.util.Date;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.tomcat.util.http.fileupload.FileUploadBase.FileSizeLimitExceededException;
    import org.niugang.bean.CustomErrorType;
    import org.niugang.constant.LogType;
    import org.niugang.utils.DateUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.security.access.AccessDeniedException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartException;
    import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
    import com.alibaba.fastjson.JSONObject;
    
    /**
     * 也可以使用aop监控  ControllerAop.java
     * @Description:异步调用统一处理异常类
     * @Project:boot-sis
     * @File:ControllerAdviceException.java
     * @Package:org.niugang.exception
     * @Date:2018年7月2日上午9:49:30
     * @author:niugang
     * @Copyright (c) 2018, 863263957@qq.com All Rights Reserved.
     *
     */
    @ControllerAdvice
    public class ControllerAdviceException extends ResponseEntityExceptionHandler {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    
    @ExceptionHandler({ Exception.class })
    @ResponseBody
    ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex, HttpServletResponse response)
    throws ServletException, IOException {
    HttpStatus status = getStatus(request);
    String message = "";
    // 如果异常
    if (ex instanceof AccessDeniedException) {
    String header = request.getHeader("x-requested-with");
    if (header != null && header.equals("XMLHttpRequest")) {
    // throw new RuntimeException("暂无权限");
    // 异步清楚不抛异常,才能继续往下走
    } else {
    request.getRequestDispatcher("/exception/403").forward(request, response);
    }
    
    
    }
    // 文件上传  文件上传出错代码捕获
    if (ex instanceof MultipartException) {
    MultipartException e = (MultipartException) ex;
    FileSizeLimitExceededException ee = (FileSizeLimitExceededException) e.getCause().getCause();
    String acutalSize = "实际为:" + (ee.getActualSize() / 1024) + "KB";
    message = "允许上传为:" + (ee.getPermittedSize() / 1024) + "kb" + acutalSize;
    }
    
    CustomErrorType cx = createExceptionAndSendMessage(status, request, ex);
    if (StringUtils.isNotBlank(message)) {
    cx.setMessage(message);
    }
    return new ResponseEntity<>(cx, status);
    
    }
    
    
    /**
    * 
    * @Title: createExceptionAndSendMessage
    * @Description: 封装异常并发送消息
    * @param status
    * @param request
    * @param ex
    * @return    
    * @return CustomErrorType    
    * @throws
    */
    public CustomErrorType createExceptionAndSendMessage(HttpStatus status, HttpServletRequest request, Throwable ex) {
    CustomErrorType customErrorType = new CustomErrorType();
    customErrorType.setStatus(status.value());
    customErrorType.setMessage(ex.getLocalizedMessage());
    customErrorType.setTimestamp(System.currentTimeMillis());
    customErrorType.setError(status.getReasonPhrase());
    // customErrorType.setException(ex.getCause().getCause().getMessage());
    messageQueue(customErrorType, request);
    return customErrorType;
    }
    
    
    private void messageQueue(CustomErrorType customErrorType, HttpServletRequest request) {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("value", customErrorType.getMessage());
    jsonObject.put("type", LogType.ERROR_LOG);
    jsonObject.put("ip", getIpAddr(request));
    jsonObject.put("port", request.getRemotePort());
    jsonObject.put("time", DateUtils.format(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS));
    if (StringUtils.isNotBlank(customErrorType.getMessage())) {
    redisTemplate.convertAndSend("log_queue", jsonObject.toJSONString());
    }
    
    
    }
    
    
    private HttpStatus getStatus(HttpServletRequest request) {
    Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
    if (statusCode == null) {
    return HttpStatus.INTERNAL_SERVER_ERROR;
    }
    return HttpStatus.valueOf(statusCode);
    }
    
    
    public static String getIpAddr(HttpServletRequest request) {
    
    String ip = request.getHeader("x-forwarded-for");
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    ip = request.getRemoteAddr();
    }
    return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }
    }
    • 源码配置解析

        

    • location specifies the directory where files will be stored. The default is "". A common value is to use the system's temporary directory, which can be obtained.

         //location指定存储文件的目录。默认的是“”。一个常见的值是使用系统的临时目录,该目录可以获得。

         //如果指定了locationname其实在默认tomcat记录路径上存储上传的文件,不易查找,建议上传专门指定文件上传目录

    • max-file-size specifies the maximum size permitted for uploaded files. The default is 1MB.

        //指定上传文件允许的最大大小。默认是1 mb。

    • max-request-size specifies the maximum size allowed for multipart/form-data requests. The default is 10MB

    //指定允许多部分/表单数据请求的最大大小。默认值是10 mb

    • file-size-threshold specifies the size threshold after which files will be written to disk. Default is 0, which means that the file will be written to disk immediately. 

    //指定文件写入磁盘后的大小阈值。默认值是0,这意味着文件将立即写入磁盘。

     微信公众号

     

     

  • 相关阅读:
    idea打开项目,没有项目文件,文件报红
    使用lombok自动生成链式调用
    gson常用的方式
    LOADING Redis is loading the dataset in memory Redis javaAPI实例
    redis.clients.jedis.exceptions.JedisDataException :READONLY You can't write
    Redis安装步骤
    springboot+jpa+mysql+redis+swagger整合步骤
    springboot+jpa+mysql+swagger2.0整合
    Daily Scrum 10.23
    Daily Scrum 10.22
  • 原文地址:https://www.cnblogs.com/niugang0920/p/12190463.html
Copyright © 2011-2022 走看看