个人技术总结——springboot的图片上传和返回图片

222000101白文成 学生 2023-06-06 11:37:04
这个作业属于哪个课程<软件工程-23年春季学期>
这个作业要求在哪里作业要求的链接
这个作业的目标个人技术总结
其他参考文献CSDN、《构建之法》

目录

  • 一、技术概述
  • 1.问题
  • 2. 问题详述
  • 二、技术详述
  • 1.springboot的图片上传
  • 2.springboot将图片返回给前端
  • 三、技术使用中遇到的问题和解决过程
  • 四、总结
  • 五、参考文献

一、技术概述

1.问题

springboot的图片上传和如何返回给前端

2. 问题详述

上传问题:在菜谱的发布界面,我们的菜谱类中包含一个picture字段用来存图片的相对路径,但是菜谱类中有嵌套了步骤类集合,每个步骤类又有picture字段存图片的相对路径,那么这样就无法用MultipartFile实现一次上传嵌套的图片消息。返回问题:我们的图片是保存在系统里面,前端无法通过数据库的相对路径找到系统中的图片,如何将图片返回给前端。

二、技术详述

1.springboot的图片上传

使用MultipartFile 接收前端上传的图片

    //增加菜谱图片
    @PostMapping("/addMenuPicture")
    public R addMenuPicture(Menu menu,MultipartFile pictureFile){
        Menu dataMenu = menuService.getById(menu.getId());

        String PicName = pictureFile.getOriginalFilename();  //获取文件原名
        String menuSaveUri=fengmianUploadPath+"/"+PicName;        //拼接保存图片的真实地址
        File menuSaveFile = new File("/DeliciousFoodIsland/pic/"+menuSaveUri);

        try {
            pictureFile.transferTo(menuSaveFile);  //保存文件到真实存储路径下
        } catch (IOException e) {
            e.printStackTrace();
        }

        dataMenu.setPicture(menuSaveUri);
        menuService.updateById(dataMenu);

        return R.success("发布成功");
    }

2.springboot将图片返回给前端

将图片编码为base64返回给前端

转化为base64的工具类

public class Base64Helper {
    /**
     * 编码
     *
     * @param byteArray
     * @return
     */
    public static String encode(byte[] byteArray) {
        return new String(new Base64().encode(byteArray));
    }


    /**
     * 本地图片转换成base64字符串
     *
     * @param imgFile 图片对象
     * @return
     * @author huangshikai
     */
    public static String ImageToBase64ByLocal(File imgFile) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;

        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);

            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Base64Encoder base64Encoder = new Base64Encoder();
        // 对字节数组Base64编码
        String base64Str = Base64.encodeBase64String(data);

        base64Str.replaceAll("(\r\n|\r|\n|\n\r)", "");//替换base64后的字符串中的回车换行
        return base64Str;// 返回Base64编码过的字节数组字符串
    }

    /**
     * 本地图片转换成base64字符串
     *
     * @param imgFilePath 本地图片存放路径
     * @return
     * @author huangshikai
     */
    public static String ImageToBase64ByLocal(String imgFilePath) {
        return ImageToBase64ByLocal(new File(imgFilePath));
    }

}

将图片编码为base64返回给前端

Menu menu= menuService.myGetById(id);
        menu.setPictureBase64(base64Helper.ImageToBase64ByLocal("/DeliciousFoodIsland/pic/"+menu.getPicture()));
        MenuDto menuDto = new MenuDto();
        menuDto.setMenu(menu);

三、技术使用中遇到的问题和解决过程

问题:在菜谱的发布界面,我们的菜谱类中包含一个picture字段用来存图片的相对路径,但是菜谱类中有嵌套了步骤类集合,每个步骤类又有picture字段存图片的相对路径,那么这样就无法用MultipartFile实现一次上传嵌套的图片。

菜谱Menu类:

@Data
public class Menu {

    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private Long id;
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private Long userId;
    private String title;
    private String userName;
    private String picture;
    private String video;
    private String description;
    private Double score;
    private Integer scoreNum;
    private LocalDateTime createTime;
    //自动填充时间
    private LocalDateTime updateTime;
    private String tag;
    private Integer difficulty;
    private String state;
    @TableField(exist = false)
    private String pictureBase64;
    @TableField(exist = false)
    private List<Step> stepList = new ArrayList<>();
    @TableField(exist = false)
    private List<Ingredient> ingredientList = new ArrayList<>();
    @TableField(exist = false)
    private List<Comment> commentList= new ArrayList<>();
}

步骤Step类

@Data
public class Step {
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private Long id;
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private Long menuId;
    private String content;
    private Integer myorder;
    //存放相对路径
    private String picture;

}

解决过程:将菜谱图片上传和步骤图片上传单独做出两个接口,再单独做一个上传菜谱其余消息的接口。

增加菜谱图片

@PostMapping("/addMenuPicture")
    public R addMenuPicture(Menu menu,MultipartFile pictureFile){
        Menu dataMenu = menuService.getById(menu.getId());

        String PicName = pictureFile.getOriginalFilename();  //获取文件原名
        String menuSaveUri=fengmianUploadPath+"/"+PicName;        //拼接保存图片的真实地址
        File menuSaveFile = new File("/DeliciousFoodIsland/pic/"+menuSaveUri);

        try {
            pictureFile.transferTo(menuSaveFile);  //保存文件到真实存储路径下
        } catch (IOException e) {
            e.printStackTrace();
        }

        dataMenu.setPicture(menuSaveUri);
        menuService.updateById(dataMenu);

        return R.success("发布成功");
    }


增加步骤图片
@PostMapping("/addSteppicture")
    public R addSteppicture(Step step,MultipartFile pictureFile){
        Step datastep = stepService.getById(step.getId());

        String PicName = pictureFile.getOriginalFilename();  //获取文件原名
        String stepSaveUri=fengmianUploadPath+"/"+PicName;        //拼接保存图片的真实地址
        File menuSaveFile = new File("/DeliciousFoodIsland/pic/"+stepSaveUri);

        try {
            pictureFile.transferTo(menuSaveFile);  //保存文件到真实存储路径下
        } catch (IOException e) {
            e.printStackTrace();
        }

        datastep.setPicture(stepSaveUri);
        stepService.updateById(datastep);

        return R.success("发布成功");
    }


发布菜谱的其余信息

@ResponseBody
    @PostMapping("/addMenu")
    public R addMenuTest3(@RequestBody Menu menu){

        Menu dataMenu = menuService.getById(menu.getId());

        dataMenu.setTitle(menu.getTitle());
        dataMenu.setDescription(menu.getDescription());
        dataMenu.setTag(menu.getTag());
        dataMenu.setDifficulty(menu.getDifficulty());

        menuService.updateById(dataMenu);


        List<Ingredient> ingredientList = menu.getIngredientList();
        for(int i = 0;i!=ingredientList.size();i++){
            ingredientService.save(ingredientList.get(i));
        }

        List<Step> stepList = menu.getStepList();
        for(int i = 0;i!=stepList.size();i++){
            stepService.save(stepList.get(i));
        }

        return R.success("发布成功");
    }

四、总结

嵌套的图片上传目前还没看到能够一次上传的,但是可以将接口进行更细粒度的拆分。

五、参考文献

https://blog.csdn.net/weixin_42273775/article/details/109064057
https://blog.csdn.net/weixin_44732379/article/details/108914567

...全文
183 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

688

社区成员

发帖
与我相关
我的任务
社区描述
2023年福州大学软件工程实践课程W班的教学社区
软件工程团队开发软件构建 高校 福建省·福州市
社区管理员
  • FZU_SE_teacherW
  • 张书旖
  • 郭渊伟
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧