Springboot 添加图片

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 自定义虚拟路径

6.1 创建image.properties

#配置图片服务器
image.localDirPath=G:/Javaworkspace/images
image.urlPath=http://image.jt.com
image.imageTypes=.jpg,.png,.git

6.2 为属性动态赋值

 //为属性动态赋值`
    @Value("${image.localDirPath}")
    private String localDirPath;// = "G:/Javaworkspace/images";
    @Value("${image.urlPath}")
    private String urlPath; //= "http://image.jt.com";  

6.3 实现路径拼接

String url = urlPath + datePath + uuidFileName;

整体代码 service实现类

   @Service
@PropertySource("classpath:/properties/image.properties")
//@PropertySource("classpath:/properties/image.properties")
public class FileServiceImpl implements FileService{
    /*
     *  1. 校验文件有效性 .jpg .png .gif
     *  2. 校验文件是否为恶意程序    (木马.exe).jpg
     *  3. 提高用户检索图片的效率    分目录存储
     *  4. 为了防止重名图片的提交    自定义文件的名称\
     *  5. 实现图片的物理上传    本地磁盘中
     *  6. 准备一个访问图片的虚拟的路径
     */
    //定义图片后缀名集合
    private static Set<String> imageTypeSet = new HashSet<>();

    //为属性动态赋值`
    @Value("${image.localDirPath}")
    private String localDirPath;// = "G:/Javaworkspace/images";
    @Value("${image.urlPath}")
    private String urlPath; //= "http://image.jt.com";   //定义了虚拟路径的域名
    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. 实现路径拼接
        //检查文件上传业务是否正确
        //图片存储的根目录 G:\Javaworkspace\images\2020\08\05\90065a76326b4a72994583621c5c84fb.jpg
        String url = urlPath + datePath + uuidFileName;
        //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>

参数
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值