"SpringBoot Image Upload Function"

Image upload return value analysis

{
    
    
	"error":0
	"url":图片的保存路径
	"width":图片的宽度
	"height":图片的高度
}

error: Indicates the error message 0 Upload successful!! 1. Upload failed.
URL address: virtual path address of the picture (distinguish from the real disk address)
width/height: required attribute as picture/width and height.

Commodity echo VO package

structure

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO {
    
    
    private Integer error;
    private String url;
    private  Integer width;
    private Integer height;

    // {"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
    public static ImageVO fail(){
    
    
        return new ImageVO(1,null,null,null);
    }

    public static ImageVO success(String url,Integer width,Integer height){
    
    
        return new ImageVO(1,null,null,null);
    }
}

给客户端发送的信息

annotation

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
  • Data-is Lombok's annotations to implement get/set methods and tostring methods
  • Accessors(chain = true)-is the method name optimization of the current class
  • NoArgsConstructor-No-argument construction
  • AllArgsConstructor-parameterized construction

Package status and information

    private Integer error;
    private String url;
    private  Integer width;
    private Integer height;

Package status code, address, height and width

Return method

 public static ImageVO fail(){
    
    
        return new ImageVO(1,null,null,null);
    }
错误的返回值
   public static ImageVO success(String url,Integer width,Integer height){
    
    
        return new ImageVO(1,null,null,null);
    }
正确的返回值

controller layer

@RestController
@CrossOrigin("http://localhost:8081")
@RequestMapping("/")
public class imageController {
    
    

    @Autowired
    private ImageService imageService;

    @PostMapping("upload")
    public ImageVO uploadFile(MultipartFile uploadFile){
    
    
        return imageService.upload(uploadFile);
    }
}

MultipartFile-The method is to upload files exclusively, and the files sent on the page are accepted in this way


Edit the properties configuration file

image.localDirPath=E:/Tmooc_image
image.urlPath=localhost:8080
  • 1-The address where the picture is saved
  • 2-Know the domain name from the link shown in the picture

service business layer

structure

@Service
@PropertySource(value = "classpath:/properties/image.properties",encoding = "UTF-8")
public class FileServiceImpl implements FileService{
    
    

    @Value("${image.localDirPath}")
    private String localDirPath;    // = "E:/Tmooc_image";
    @Value("${image.urlPath}")
    private String urlPath;         // = "localhost:8080";

    @Override
    public ImageVO upload(MultipartFile uploadFile){
    
    
        //1.校验文件类型  abc.jpg
        String fileName = uploadFile.getOriginalFilename().toLowerCase();
        //1.1 利用正则表达式校验是否满足图片格式要求
        if(!fileName.matches("^.+\\.(jpg|png|gif)$")){
    
    
            return ImageVO.fail();
        }

        //2.校验是否为图片对象
        try {
    
    
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if(width==0 || height==0){
    
    
                return ImageVO.fail();
            }

            //3.实现分目录存储
            //3.1 动态生成hashcode编码 之后2位一隔 生成多级目录.目录层级太深 笛卡尔积较大 遍历不便
            //3.2 可以动态以当前的时间为存储的目录结构 yyyy/MM/dd
            String dateDirPath =
                new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());

            //文件存储的目录  E:/Tmooc_image/2021/01/26/
            String fileDirPath = localDirPath + dateDirPath;
            File fileDir = new File(fileDirPath);
            if(!fileDir.exists()){
    
      //判断文件目录是否存在

                fileDir.mkdirs();  //创建目录
            }

            //4.利用UUID动态生图片名称   uuid.jpg
            String uuid =
                    UUID. randomUUID().toString().replace("-", "");
            //abc.jpg
            String fileType = fileName.substring(fileName.lastIndexOf("."));
            String newFileName = uuid + fileType;
            //5.实现文件上传
            File realFile = new File(fileDirPath + newFileName);
            uploadFile.transferTo(realFile);

            //6.编辑图片的虚拟路径
            //6.1磁盘地址: E:\JT_IMAGE\2021\01\26\1b0e435933ac42cabec53b20ffbcfe90.png
            //6.2虚拟地址  http://image.jt.com\2021\01\26\1b0e435933ac42cabec53b20ffbcfe90.png
            String url = urlPath + dateDirPath + newFileName;
            return ImageVO.success(url,width,height);

        } catch (IOException e) {
    
    
            e.printStackTrace();
            return ImageVO.fail();
        }
    }

Our file upload is only realized after the business has passed various tests

  • 1-The suffix of the picture is verified whether the file upload is a picture type? jpg|png|gif...
  • 2-To prevent malicious program Trojan horse.exe.jpg
  • 3-In order to ensure the retrieval speed, the pictures need to be stored in directories.
  • 4-How to prevent duplicate file names???

1-Verify that the file upload is of image type

//1.校验文件类型  abc.jpg
String fileName = uploadFile.getOriginalFilename().toLowerCase();
//1.1 利用正则表达式校验是否满足图片格式要求
if(!fileName.matches("^.+\\.(jpg|png|gif)$")){
    
    
    return ImageVO.fail();
}
uploadFile-get the picture
getOriginalFilename() – Get the name of the uploaded image
toLowerCase()-Change the name of the picture to lowercase

图片的后缀不许跟我们设定的一摸一样

2-Check whether it is a picture object

BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
   int width = bufferedImage.getWidth();
   int height = bufferedImage.getHeight();
   if(width==0 || height==0){
    
    
       return ImageVO.fail();
   }
ImageIO-is java's own tool class io stream method to get pictures
read —— is the way to get the image path in the image ImageIO
uploadFile.getInputStream()-dynamically get the picture sent by the customer
BufferedImage-The way Java loads an image into memory is
getWidth/getHeight-is to get the width and height of the picture

图片的高度或者宽度 0 那么后面的业务不执行 (可能是病毒)

3-Implement sub-directory storage

String dateDirPath = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
  //文件存储的目录  E:/Tmooc_image/2021/01/26/
  String fileDirPath = localDirPath + dateDirPath;
  File fileDir = new File(fileDirPath);
  if(!fileDir.exists()){
    
      //判断文件目录是否存在
      fileDir.mkdirs();  //创建目录
  }
SimpleDateFormat —— date format (M month d day in y year)
format —— format time (current time shall prevail)
localDirPath + dateDirPath —— spliced ​​image storage path and time (E:/Tmooc_image/2021/01/26)
File-Create a folder based on the path and time of the picture

图片存储路径和时间拼接成新的路径,如果文件夹不存在的话创建一个,如果存在的话执行下一个业务

4-Use UUID to dynamically generate picture name

String uuid = UUID.randomUUID().toString().replace("-", "");
String Filetype = filename.substring(filename.lastIndexOf("."));
String newFileName = uuid + Filetype;
UUID-automatic code generator
randomUUID —— Randomly generate code
toString —— the form of encoding into a string
replace —— replace the characters in the string (- replace empty)
substring-defines where the string starts
filename.lastIndexOf(".") —— Defines starting from the point of the picture name Li Mina (.jpg)
uuid + Filetype —— The type of picture stitched with uuid encoding (absadfa.jpg)

好多的图片名字是相同 为了这个我们使用UUID来编码出字符串,然后获取图片的后缀 最后拼接UUID和后缀做出新的图片名称

5-Realize image upload

File realFile = new File(fileDirpath + newFileName);
uploadFile.transferTo(realFile);

fileDirpath + newFileName —— The address of the image storage and the name of the stored image
transferTo —— The image sent by the client is stored

存储的目录,文件夹,图片名称都有了 我们把这些拼接并且进行存储到磁盘中

6-Edit the path of the picture

String url = urlPath +  dateDirpath + newFileName;
return ImageVO.success(url, whdth, height);
查询的域名+文件文件路径+图片名称 封装成URL给客户端响应,通过URL能看图片

Guess you like

Origin blog.csdn.net/weixin_45103228/article/details/113820568