springboot 实现图片上传功能

本文介绍了在SpringBoot项目中实现图片上传功能的过程,包括数据库设计、Mapper与Service层的处理、自定义异常以及BaseController层的异常处理。在实现过程中,针对文件上传可能出现的错误,如文件类型、大小等,定义了一系列自定义异常类。最终,图片保存在static/images/book/目录下。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springboot 实现图片上传功能

   这几天在做重构学校的图书馆项目,用sprinboot重新搭建项目,原项目是使用PHP搭建的,刚开始看着挺懵的,慢慢的就看懂。这个项目中遇到的难题是照片上传功能,弄了挺久才实现出来。

   此功能没有导入如何jar包。

   这里介绍呢,我就按照项目本身的结构来实现这个功能。

   首先是数据库的数据结构,项目先是通过照片名(xxx.jpg)保存到数据库(picurl).
   故我的想法是通过新书的名字,获取到这个新书对应的照片名,进行对上传上的照片进行名字的修改。
在这里插入图片描述

1.Mapper层
	<!--上传图片-->
	<select id="changeAvatar" resultType="NewBooks">
	    select * from newbooks where title=#{title}
	</select>
2.Service层
@Override
public NewBooks changePicUrl(String title) {
    //根据参数调用方法
    NewBooks newBooks = newBooksMapper.changeAvatar(title);
    if (newBooks == null){
        throw new NewsBookNotException("书库没有该书数据,请先添加!");
    }
    return newBooks;
}
3.自定义异常
3.1service层自定义异常

   为了便于统一管理自定义异常,在service包中创一个ex包用来放自定义异常的基类异常,继承自RuntimeException类,并从父类生成子类的五个构造方法。
在这里插入图片描述创建NewsBookNotException类,当用户输入到的书名,在数据库中没有找到数据,则会出对应的信息。
在这里插入图片描述

3.2 上传文件自定义异常

处理异常

1.在处理上传文件的过程中,用户可能会选择错误的文件上传,此时就应该抛出对应的异常并进行处理。所以需要创建文件上传相关异常的基类,即在com.cy.store.controller.ex包下创建FileUploadException类,并继承自RuntimeException类。

package com.pzlib.service.ex;

/** 文件上传相关异常的基类 */
public class FileUploadException extends RuntimeException {
    public FileUploadException() {
        super();
    }

    public FileUploadException(String message) {
        super(message);
    }

    public FileUploadException(String message, Throwable cause) {
        super(message, cause);
    }

    public FileUploadException(Throwable cause) {
        super(cause);
    }

    protected FileUploadException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

2.在处理上传的文件过程中,经分析可能会产生以下异常。这些异常类都需要继承自FileUploadException类。

// 上传的文件为空
controller.ex.FileEmptyException
// 上传的文件大小超出了限制值
controller.ex.FileSizeException
// 上传的文件类型超出了限制
controller.ex.FileTypeException
// 上传的文件状态异常
controller.ex.FileStateException
// 上传文件时读写异常
controller.ex.FileUploadIOException

3.创建FileEmptyException异常类,并继承FileUploadException类。

package com.pzlib.service.ex;

/** 上传的文件为空的异常,例如没有选择上传的文件就提交了表单,或选择的文件是0字节的空文件 */
public class FileEmptyException extends FileUploadException {
    // Override Methods...
}

4.创建FileSizeException异常类,并继承FileUploadException类。

package com.pzlib.service.ex;

/** 上传的文件的大小超出了限制值 */


public class FileSizeException extends FileUploadException {
    // Override Methods...
}

5.创建FileTypeException异常类,并继承FileUploadException类。

package com.pzlib.service.ex;
/** 上传的文件类型超出了限制 */
public class FileTypeException extends FileUploadException {
    // Override Methods...
}

6.创建FileStateException异常类,并继承FileUploadException类。

package com.pzlib.service.ex;

/** 上传的文件状态异常 */
public class FileStateException extends FileUploadException {
    // Override Methods...
}

7.创建FileUploadIOException异常类,并继承FileUploadException类。

package com.pzlib.service.ex;

/** 上传文件时读写异常 */
public class FileUploadIOException extends FileUploadException {
    // Override Methods...
}

8.然后在BaseController的handleException()的@ExceptionHandler注解中添加FileUploadException.class异常的处理;最后在方法中处理这些异常。

@ExceptionHandler({ServiceException.class, FileUploadException.class})
public JsonResult<Void> handleException(Throwable e) {
    JsonResult<Void> result = new JsonResult<Void>(e);
    if (e instanceof UsernameDuplicateException) {
        result.setState(4000);
    } else if (e instanceof UserNotFoundException) {
        result.setState(4001);
    } else if (e instanceof PasswordNotMatchException) {
        result.setState(4002);
    } else if (e instanceof InsertException) {
        result.setState(5000);
    } else if (e instanceof UpdateException) {
        result.setState(5001);
    } else if (e instanceof FileEmptyException) {
        result.setState(6000);
    } else if (e instanceof FileSizeException) {
        result.setState(6001);
    } else if (e instanceof FileTypeException) {
        result.setState(6002);
    } else if (e instanceof FileStateException) {
        result.setState(6003);
    } else if (e instanceof FileUploadIOException) {
        result.setState(6004);
    }
    return result;
}
4.BaseController层
package com.pzlib.controller;


import com.pzlib.controller.ex.*;
import com.pzlib.service.ex.*;
import com.pzlib.util.JsonResult;
import org.springframework.web.bind.annotation.ExceptionHandler;

/** 控制器类的基类 */
public class BaseController {
    /** 操作成功的状态码 */
    public static final int OK = 200;

    /** @ExceptionHandler用于统一处理方法抛出的异常 */
    @ExceptionHandler({ServiceException.class,FileUploadException.class})
    public JsonResult<Void> handleException(Throwable e) {
        JsonResult<Void> result = new JsonResult<Void>(e);
        if (e instanceof UsernameDuplicateException) {
            result.setState(4000);
        } else if (e instanceof UserNotFoundException) {
            result.setState(4001);
        } else if (e instanceof PasswordNotMatchException) {
            result.setState(4002);
        } else if (e instanceof NewsBookNotException) {
            result.setState(4003);
        }else if (e instanceof UpdateException) {
            result.setState(5001);
         }else if (e instanceof InsertException) {
            result.setState(5002);
        }else if (e instanceof SelectException) {
            result.setState(5003);
        }else if (e instanceof DeleteException) {
            result.setState(5004);
        }else if (e instanceof FileEmptyException) {
            result.setState(6000);
        } else if (e instanceof FileSizeException) {
            result.setState(6001);
        } else if (e instanceof FileTypeException) {
            result.setState(6002);
        } else if (e instanceof FileStateException) {
            result.setState(6003);
        } else if (e instanceof FileUploadIOException) {
            result.setState(6004);
        }
        return result;
    }
}
5.FileUrlController

    自定义了异常,需要FileUrlController类继承BaseController类,捕获到异常信息。

package com.pzlib.controller;

import com.pzlib.controller.ex.*;
import com.pzlib.entity.NewBooks;
import com.pzlib.service.INewsBootService;

import com.pzlib.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@RestController
public class FileUrlController extends BaseController {

    @Autowired
    private INewsBootService newsBootService;

    /** 头像文件大小的上限值(1MB) */
    public static final int AVATAR_MAX_SIZE = 1 * 1024 * 1024;
    /** 允许上传的头像的文件类型 */
    public static final List<String> AVATAR_TYPES = new ArrayList<String>();

    /** 初始化允许上传的头像的文件类型 */
    static {
        AVATAR_TYPES.add("image/jpeg");
        AVATAR_TYPES.add("image/jpg");
        AVATAR_TYPES.add("image/png");
        AVATAR_TYPES.add("image/bmp");
        AVATAR_TYPES.add("image/gif");
        AVATAR_TYPES.add("image/pjpeg");
        AVATAR_TYPES.add("image/x-png");

    }


    @PostMapping("/newsImage")
    public JsonResult<String> newsImage(@RequestParam("file") MultipartFile file,String title) {
        // 判断上传的文件是否为空
        if (file.isEmpty()) {
            // 是:抛出异常
            throw new FileEmptyException("上传的头像文件不允许为空");
        }

        // 判断上传的文件大小是否超出限制值
        if (file.getSize() > AVATAR_MAX_SIZE) { // getSize():返回文件的大小,以字节为单位
            // 是:抛出异常
            throw new FileSizeException("不允许上传超过" + (AVATAR_MAX_SIZE / 1024) + "KB的头像文件");
        }

        // 判断上传的文件类型是否超出限制
        String contentType = file.getContentType();
        // boolean contains(Object o):当前列表若包含某元素,返回结果为true;若不包含该元素,返回结果为false
        if (!AVATAR_TYPES.contains(contentType)) {
            // 是:抛出异常
            throw new FileTypeException("不支持使用该类型的文件作为头像,允许的文件类型:" + AVATAR_TYPES);
        }

        //获取jar包所在目录
        ApplicationHome h = new ApplicationHome(getClass());
        File jarF = h.getSource();
        //在jar包所在目录下生成一个upload文件夹用来存储上传的图片
        String parent = jarF.getParentFile().toString()+"/classes/static/images/book/";
        System.out.println(parent);

        // 保存头像文件的文件夹
        File dir = new File(parent);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        // 保存的头像文件的文件名
        String suffix = "";
        String originalFilename = file.getOriginalFilename();
        int beginIndex = originalFilename.lastIndexOf(".");
        if (beginIndex > 0) {
            suffix = originalFilename.substring(beginIndex);
        }
        NewBooks newBooks = newsBootService.changePicUrl(title);
        String string = newBooks.getPicurl();
        String[] split = string.split("\\.");
        String filename =split[0]+ suffix;

        // 创建文件对象,表示保存的头像文件
        File dest = new File(dir, filename);
        // 执行保存头像文件
        try {
            file.transferTo(dest);
        } catch (IllegalStateException e) {
            // 抛出异常
            throw new FileStateException("文件状态异常,可能文件已被移动或删除");
        } catch (IOException e) {
            // 抛出异常
            throw new FileUploadIOException("上传文件时读写错误,请稍后重新尝试");
        }

        /*// 头像路径
        String avatar = "/images/book/" + filename;
        // 返回成功头像路径*/
        return new JsonResult<String>(OK);
    }

   运行结果

在这里插入图片描述运行失败:
在这里插入图片描述

   &图片保存路径是在target/classes/static/images/book/xxx.jpg,
在这里插入图片描述
   &如果是打包成jar包,则路径和jar路径一样。

在这里插入图片描述
   如有错误请指正,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值