欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Springboot 添加图片

程序员文章站 2024-02-19 11:31:40
...

Springboot 上传图片

框架:ssm mybatis-plus
业务要求:
实现图片上传的操作
url:/pic/upload
参数信息:uploadFile
返回值:ImageVO对象

1. 校验文件有效性(service实现类)

传统图片格式大部分为.jpg .png .gif 以这三个格式为案例
1.1 定义图片后缀名的集合

private static Set<String> imageTypeSet = new HashSet<>();
   static{
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
    }

1.2 获取图片的名称

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

1.3 获取图片的类型
可以用正则表达式和集合进行校验

  int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);   //.jpg
        if(!imageTypeSet.contains(fileType)){//如果类型不匹配
            return ImageVo.fail();
        }

fileName.lastIndexOf(".") 由后向前获取数据
fileName.IndexOf(".")由前向后获取数据

2. 判断文件是否为恶意程序

如何判断文件是否为恶意程序? 需要判断文件是否含有图片的特性
2.1 将上传的文件的类型利用图片api进行转化
如果转化不成功则一定不是图片

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

2.2 校验是否有图片的特有属性
图片特有属性是高度/宽度等

   int width = bufferedImage.getWidth();
            int heigth = bufferedImage.getHeight();

2.3校验宽度和高度是否有值
某些文件可能设置了高度和宽度,需要进行进一步的校验

 if(width== 0||heigth==0 ){
                return ImageVo.fail();

            }

上述代码有异常需要处理
整体代码为

       try {
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            int width = bufferedImage.getWidth();
            int heigth = bufferedImage.getHeight();
            if(width== 0||heigth==0 ){
                return ImageVo.fail();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVo.fail();//返回失败即可
        }

ImageVo类

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVo implements Serializable {
    private static final long serialVersionUID = -7982524210249421268L;
    private Integer error; //是否有错误
    private String url;    //图片访问的虚拟的地址
    private Integer width; //宽度
    private Integer hight; //高度
    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 success(String url,Integer width,Integer hight){
        return new ImageVo(0,url,width,hight);
    }

}

3. 实现分目录存储

不可能将所有的上传的图片放到一个文件夹里,需要进行分目录存储.
方案一:利用hash之后每隔2-3位截取之后拼接
方案二:以时间为单位进行分割 yyyy/MM/dd
这里用的第二种方法
3.1 利用工具api将时间转化为指定的格式

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

3.2 动态生成文件目录 根目录+时间目录
根目录

 private String localDirPath = "G:/Javaworkspace/images";

文件目录

String LocalDir = localDirPath + datePath;

3.3 判断目录是否存在,如果不存在就创建目录

 File dirFile = new File(LocalDir);
        if (!dirFile.exists()){
            dirFile.mkdirs(); //如果不存在则创建目录
        }

4 防止文件重名

4.1 生成UUID

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

4.2 动态生成文件名

 String uuidFileName = uuid + fileType;

```java


### 5. 实现文件上传 准备文件路径
文件路径:目录+文件名

```java
  String realFilePath = LocalDir + uuidFileName;

5.1 封装文件真实对象

File imageFile = new File(realFilePath);

5.2 实现文件上传

        try {
            uploadFile.transferTo(imageFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

6 自定义虚拟路径

String url = "#";
        return ImageVo.success(url);

整体代码 service实现类

    //定义图片后缀名集合
    private static Set<String> imageTypeSet = new HashSet<>();
    private String localDirPath = "G:/Javaworkspace/images";
    static{
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
    }
    @Override
    public ImageVo upload(MultipartFile uploadFile) {
        //校验图片的类型    1.利用正则表达式  2.利用几集进行校验
        //1.1 获取图片的名称 abc.jpg
        String fileName = uploadFile.getOriginalFilename();//获取原始文件名
        fileName = fileName.toLowerCase();//将所有的字母都小写
        //1.2 获取图片的类型
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);   //.jpg
        if(!imageTypeSet.contains(fileType)){//如果类型不匹配
            return ImageVo.fail();
        }
        //2.如何判断文件是否为恶意程序  文件是否有图片的特有属性
        //2.1将上传的文件的类型利用图片API进行转化,  如果转化不成功则一定不是图片
        try {
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            //2.2校验是否有图片的特有属性 高度/宽度
            int width = bufferedImage.getWidth();
            int heigth = bufferedImage.getHeight();
            //2.3校验宽度和高度是否有值
            if(width== 0||heigth==0 ){
                return ImageVo.fail();

            }
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVo.fail();//返回失败即可
        }
        //3.实现分目录存储
        // 方案一:利用hash之后每隔2-3位截取之后拼接
        // 方案二:以时间为单位进行分割  yyyy/MM/dd
        //3.1利用工具api将时间转化为指定的格式
        String datePath = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
        //3.2 动态生成文件目录 2部分=根目录+时间目录
        String LocalDir = localDirPath + datePath;
        //3.3 判断目录是否纯在,如果不纯在就创建
        File dirFile = new File(LocalDir);
        if (!dirFile.exists()){
            dirFile.mkdirs(); //如果不存在则创建目录
        }
        //4 防止文件重名,需要自定义文件名称 UUID
        //4.1生成UUID
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //4.2动态生成文件名
        String uuidFileName = uuid + fileType;
        //5 实现文件上传 准备文件路径 目录+文件名称
        String realFilePath = LocalDir + uuidFileName;
        //5.1 封装文件真实对象
        File imageFile = new File(realFilePath);
        //5.2实现文件上传
        try {
            uploadFile.transferTo(imageFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //6.暂时 ,使用京东图片代替
        //检查文件上传业务是否正确
        String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1596623702331&di=b1138fe0361d8b9b7111331ba5b33742&imgtype=0&src=http%3A%2F%2Fa1.att.hudong.com%2F05%2F00%2F01300000194285122188000535877.jpg";
        return ImageVo.success(url);
    }
}

Controller层

 @Autowired
    FileService fileService;
    @RequestMapping("/file")
    public String file(MultipartFile fileImage){
        //实现文件上传\
        String fileDirPath = "G:/Javaworkspace/images";
        File dirFile = new File(fileDirPath);
        if(dirFile.exists()){
            //如果文件目录没有,则应该新建目录
            dirFile.mkdir();
        }
        //3.准备文件上传的全路径  路径+文件名称'
        String fileName = fileImage.getOriginalFilename();//文件名称.后缀
        File realFile = new File(fileDirPath+"/"+fileName);
        //将字节信息输出到文件中
        try {
            fileImage.transferTo(realFile);//实现文件的上传
            return "文件上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败";
        }
    }
    /*
     *实现图片上传的操作
     * url:/pic/upload
     * 参数信息:uploadFile
     * 返回值:ImageVO对象
     */
    @RequestMapping("/pic/upload")
    public ImageVo upload(MultipartFile uploadFile){

        return fileService.upload(uploadFile);
    }
    }

service接口

public interface FileService {

    ImageVo upload(MultipartFile uploadFile);
}

html页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>实现文件长传</h1>
	<!--enctype="开启多媒体标签"  -->
	<form action="http://localhost:8091/file" method="post" 
	enctype="multipart/form-data">
		<input name="fileImage" type="file" />
		<input type="submit" value="提交"/>
	</form>
</body>
</html>

参数
Springboot 添加图片