《SpringBoot 图片上传功能》

图片上传返回值分析

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

error : 表示错误信息 0 上传成功!! 1.上传失败.
url地址 : 图片虚拟路径地址(区分真实磁盘地址)
width/height : 作为图片/宽和高必须的属性.

商品回显VO封装

结构

@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);
    }
}

给客户端发送的信息

注解

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
  • Data - 是Lombok的注解 实现get/set方法和tostring方法
  • Accessors(chain = true) - 是当前类的方法名优化
  • NoArgsConstructor - 无参构造
  • AllArgsConstructor - 有参构造

封装状态以及信息

    private Integer error;
    private String url;
    private  Integer width;
    private Integer 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);
    }
正确的返回值

controller层

@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 - 方法是专门用文件上传的方法,页面发送的文件就这么接受


编辑properties配置文件

image.localDirPath=E:/Tmooc_image
image.urlPath=localhost:8080
  • 1 - 图片保存的地址
  • 2 - 图片显示的链接获知域名

service业务层

结构

@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();
        }
    }

我们文件上传在业务从通过各种测试后才实现

  • 1 - 图片的后缀校验文件上传是否为图片类型? jpg|png|gif…
  • 2 - 为了防止恶意程序 木马.exe.jpg
  • 3 - 为了保证检索速度,需要将图片 分目录存储.
  • 4 - 何防止文件重名???

1 - 校验文件上传是否为图片类型

//1.校验文件类型  abc.jpg
String fileName = uploadFile.getOriginalFilename().toLowerCase();
//1.1 利用正则表达式校验是否满足图片格式要求
if(!fileName.matches("^.+\\.(jpg|png|gif)$")){
    
    
    return ImageVO.fail();
}
uploadFile – 获取图片
getOriginalFilename() – 获取上传图片的名字
toLowerCase() – 把图片的名字都要改小写

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

2 - 校验是否为图片对象

BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
   int width = bufferedImage.getWidth();
   int height = bufferedImage.getHeight();
   if(width==0 || height==0){
    
    
       return ImageVO.fail();
   }
ImageIO —— 是java自己的工具类io流的方式来获取图片
read —— 是图片ImageIO里面的获取图片路径方式
uploadFile.getInputStream() —— 动态的获取客户发来的图片
BufferedImage —— Java将一副图片加载到内存中的方法是
getWidth/getHeight —— 是获取图片的宽度和高度

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

3 - 实现分目录存储

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 —— 日期的格式 (y 年 M 月 d 日)
format —— 格式化时间 (当前的时间为准)
localDirPath + dateDirPath —— 拼接了图片存储路径和时间(E:/Tmooc_image/2021/01/26)
File —— 基于图片的路径和时间创建文件夹

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

4 - 利用UUID动态生成图片名称

String uuid = UUID.randomUUID().toString().replace("-", "");
String Filetype = filename.substring(filename.lastIndexOf("."));
String newFileName = uuid + Filetype;
UUID —— 编码自动生成器
randomUUID —— 随机生成编码
toString —— 编码转成字符串的形式
replace —— 替换字符串里面的字符 ( - 替换 空)
substring —— 定义字符串从哪里开始
filename.lastIndexOf(".") —— 定义了从图片名字李米娜的 点 开始 (.jpg)
uuid + Filetype —— 把uuid的编码拼接图片的类型 (absadfa.jpg)

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

5 - 实现图片上传

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

fileDirpath + newFileName —— 图片存储的地址和存储的图片名称
transferTo —— 客户端发来的图片进行存储

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

6 - 编辑图片的路径

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

猜你喜欢

转载自blog.csdn.net/weixin_45103228/article/details/113820568