## 业务实现

1.根据前端数据创建VO封装信息

error : 确认是否由错误 0代表正常 1错误
url : 图片访问的虚拟地址
width : 宽度 后期用于校验用户传入的是否是图片而不是恶意木马程序
height : 高度 同上

fail : 用户信息不正常
Success(String url) : 用户传入的图片url地址
Success(全参) : 宽和高修改图片大小

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVo implements Serializable {
    private static final long serialVersionUID = -3443836973308784819L;
    private Integer error;  //确认是否有错误 0正常 1错误
    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){
        return new ImageVo(0,url,null,null);
    }
    public static ImageVo fail(String url,Integer width,Integer height){
        return new ImageVo(0,null,width,height);
    }
}

2.Controller业务实现

文件上传可以使用SpringMVC的工具API来简化定义接收的文件类型为 MultipartFile

/**
     * 实现图片上传的操作
     * url:http://localhost:8091/pic/upload?dir=image
     * 参数:uploadfile
     * 返回值:ImageVO对象
     */
    @RequestMapping("/pic/upload")
    public ImageVo upload(MultipartFile uploadFile){
        return fileService.upload(uploadFile);
    }

3.Service层实现

public interface FileService {
    ImageVo upload(MultipartFile uploadFile);
}

3.ServiceImpl实现类(重点)

1.检验文件的有效性
根据文件的后缀检验文件的有效性,检验文件有效性有两种方式1.正则表达式 2.利用Set集合进行校验数据是否存在即可
1.1获取图片的名称
获取原始文件名,用户上传文件对象+getOriginalFilename();
fileName.toLowerCase(); 将用户文件名后缀改成小写(大写可能会出现问题所以转换一下)

String fileName = uploadFile.getOriginalFilename();  //获取原始文件名
fileName = fileName.toLowerCase();

1.2获取图片类型
fileName.lastIndexOf("."); 从后往前截取数据,因为后缀名是倒数后四位数(.jpg)所以从 “.” 开始截取
fileName.substring(“截取到的数据”); 将截取到的数据转换为字符串

/** 1.校验图片类型  1.利用正则表达式进行校验 2.利用集合进行校验 set 数据是否存在即可 */
        //1.1获取图片名称
        String fileName = uploadFile.getOriginalFilename();  //获取原始文件名
        fileName = fileName.toLowerCase();                   //将所有的字母都小写
        //1.2获取图片的类型
        int index = fileName.lastIndexOf(".");           //从后往前截取
        String fileType = fileName.substring(index);        //得到.jpg

1.21定义类型集合
利用Set集合校验数据是否存在所以要先定义图片类型集合
在实现类下定义Set集合

private static Set<String> imageTypeSet = new HashSet<>();

定义本地根目录

private String localDirPath = "F:/IDEAWorkspaces/images";

添加全局通用的静态代码块存储图片类型

static {
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
    }

1.2.2校验图片类型
利用Set集合中的 contains(参数) 方法判断由于判断的是不符合类型的所以是非 不等于 如果类型不合法则返回提示信息

if (!imageTypeSet.contains(fileType)){              //如果类型不匹配
                return ImageVo.fail();                      //图片上传失败
        }

2.判断图片是否为恶意程序 文件是否具有图片的特有特性
2.1将用户上传的文件通过图片的API进行转化 ,如果转化不成功则一定不是图片类型

BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());

2.2转换成功后判读是否有图片的的特性(高/宽),利用转换完成的图片对象获得图片的宽和高.

//2.2是否有图片的特有属性 高度/宽度
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();

2.3校验宽度和高度是否有值,如果没有值则给出提示ImageVo.fail();

//2.3校验宽度和高度是否有值
            if (width == 0 || height == 0){
                return ImageVo.fail();
            }

此步骤需要捕捉异常信息(ImageVo.fail()😉

3.实现分目录储存

方案1.利用hash之后之后每隔2-3位截取之后拼接
方案2.以时间为单位进行分割 yyyy/MM/dd
我们使用第二种方案

3.1利用工具API将时间转化为指定的格式new一个简单日期格式并赋值

String datePath =  new SimpleDateFormat("/yyyy/MMMM/dd/").format(new Date())

3.2动态生成文件目录 根目录(已创建)加上时间目录

String localDir = localDirPath + datePath;  //拼接本地dir目录

3.3判断目录是否存在,如果不存在则新建,传建文件夹并赋值(文件目录)

File dirFile = new File(localDir);

如果不存在就新建

if (!dirFile.exists()){
            dirFile.mkdirs(); //如果不存在则新建目录
        }

4.为防止文件重名需要动态生成文件名称(UUID)
4.1生成UUID
UUID.randomUUID()生成随机UUID,.toString()转换成字符串,.replace更换分隔符

String uuid = UUID.randomUUID().toString().replace("/", "")

4.2动态生成文件名称 uuid+.jpg(拼接)

String uuidFileName = uuid + fileType;

5.实现文件上传
需要文件的全路径 目录+文件名称

String realFilePath = localDir + uuidFileName;

5.1封装文件真实对象(new File)

File imageFile = new File(realFilePath);

5.2实现文件上传
将封装的文件真是对象封装到参数(uploadFile)中,carch返回告知文件上传失败

try {
            uploadFile.transferTo(imageFile);
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVo.fail(); //告知文件上传失败
        }

6.文件url(暂时替代)

String url="https://pic4.zhimg.com/80/v2-75532bcc80253c151e129911a3be96b2_qhd.jpg";

返回图片url地址

return ImageVo.Success(url);