图片存储与回显

图片的存储与回显,从前端写到后台,我所用的一套处理方式,记录下,路过的小猿,少踩坑。
先说下我的业务背景吧,我在前端所要封装的信息主要是一个完整的类信息,类下包括所要传递的图片以及一些别的属性,没错,我这是将属性与图片一起封装传递的。工程的后台架构是springBoot+ssm,前台架构是angularJs,jquery等,本来想着angularJs的双向绑定想着省事点,没想到因为这个在图片存储这一块踩了一路的坑。

存储思路:将所有信息包括图片封装为一个FormData对象,传递formdata至后台处理,后台将图片存储到指定路径,返回一个文件名,将文件名保存至数据库,然后通过springBoot的一些优雅的方式让图片在页面显示。

html部分代码

姓名*
介绍
形象照

这里的图片输入框我没有用angularJs的方式去处理,不为别的,纯粹是菜。包括后面的获取input输入框的基本信息与图片信息,我也没用angularJs处理,还是因为足够纯粹。

js部分代码
处理input输入框,通过jquery获取输入框的信息,封装为FormData对象。突然发现这个对象用来前后交互真是非常友好,特别是对于我这种前端比较纯粹的后台。


这里需要注意以下几点

  • 此处采用的是angular的请求方式,如果你用的是别的框架,可以在我的参考链接里看看。
  • 此处未采用form标签封装input,所以也没有在form标签里添加这个属性 enctype=“multipart/form-data”,如果你用form标签,好像也可以不添加,浏览器应该能识别你所要传输的信息
  • headers: {‘Content-Type’: undefined} ,文本类型不声明,浏览器智能匹配
  • transformRequest: angular.identity,这个参数,在我使用的图片传输里,是最坑我的,务必声明,如果不声明,你再F12的控制台是看不到传递的图片信息,因为没传递。。。
  • method : ‘POST’, data : formData, 如果你用的是post的请求方式,在angularJs里,传递参数要用data表示,get的话是用params,不然,可能会传递失败

SpringMvc部分代码

@CrossOrigin //跨域处理
@RestController
@RequestMapping(value = "teacher")
public class TeacherController {

    //文件保存地址
    @Value("${img.upload-path}")
    private String uploadPicturePath;

    @Autowired
    private TeacherService teacherService;

    /**
     * 新增讲师
     * @param tch_picFile
     * @param tch
     * @return
     */
    @RequestMapping(value = "addTch",method = RequestMethod.POST)
    public ResultInfo addTch(@RequestParam(value = "tch_picFile",required = false)MultipartFile tch_picFile,Teacher tch){
        //定义用于接收所传图片的文件名
        String filename = null;
        //定义流对象接收前端所传的图片信息
        InputStream ism = null;
        try{       
            if (tch_picFile != null && tch_picFile.getOriginalFilename() != null){
                //获取前端所传图片的名字,用于判断文件后缀
                filename = tch_picFile.getOriginalFilename();
                //获取图片流资源
                ism = tch_picFile.getInputStream();
                //通过工具类处理图片并返回文件名
                String pic_name = PictureUtil.picUtil(ism, filename, uploadPicturePath);
                //判断巩工具类返回的路径是否为空,不为空则保存到stu对象中
                tch.setTch_pic(pic_name);
            }

            //避免产生undefined
            if (tch.getTch_desc().equals("undefined")){
                tch.setTch_desc("");
            }

            //保存
            teacherService.addTch(tch);

        } catch (Exception e) {
            e.printStackTrace();
            return new ResultInfo(false,"讲师添加失败");
        }
        return new ResultInfo(true,"讲师添加成功");
    }
}

这里需要注意的地方

  • @CrossOrigin springBoot对于跨域的解决措施之一
  • @RequestParam(value = “tch_picFile”,required = false)MultipartFile tch_picFile 获取前台传过来的图片信息,这里的value跟在前台formdata封装的key要一致,不然要空指针,同时也要用MultipartFile 去接受文件,,,别的信息会因为你的formdata设置的key与你的bean里的属性名一样,所以会被自动封装为你指定的bean对象

图片工具类部分代码

public class PictureUtil {

    /**
     * 保存图片,并返回绝对路径
     * @param stu_pic 图片资源
     * @param pic_name 图片名用于判断后缀
     * @param filePath 保存路径
     * @return 将返回的文件名存进数据库
     */
    public static String picUtil(InputStream stu_pic,String pic_name,String filePath){
        String fileName = null;
        FileInputStream fileInputStream = null;
        try{
            fileName = getFileName(pic_name);
            fileInputStream = (FileInputStream) stu_pic;
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath + File.separator + fileName));
            byte[] bs = new byte[1024];
            int len;
            while ((len = fileInputStream.read(bs)) != -1) {
                bos.write(bs, 0, len);
            }
            bos.flush();
            bos.close();

        }catch (Exception e){
            e.printStackTrace();
        }
        return fileName;
    }

    /**
     * 生成图片名跟后缀
     * @param file_name
     * @return
     */
    public static String getFileName(String file_name){
        Date date = new Date();
        long time = date.getTime();
        String pic_name = time+"";
        if (file_name.contains(".png")){
            pic_name += ".png";
        }
        if (file_name.contains(".jpg")){
            pic_name += ".jpg";
        }
        return pic_name;
    }
}

后台对图片处理的思路,本来是想保存绝对路径到数据库,然后返回前台二进制,再在前台显示,,,但是在无意中突然发现,springBoot一个很优雅的特性,就是,你可以指定本地的一个路径作为资源路径,该文件下的所有文件能被页面html直接识别,img的src属性能够直接访问到,,,这样就很舒服了啊,所以仅保存文件名到数据库,便于图片的回显。这一点是在一个博客中学习到的,博客链接文末会有,很nice的以为兄台。

以上就是图片从前台到后台的一个大致过程,写的比较慌乱
接下来说说图片回显的一个大致思路:
首先通过配置类实现本地路径的资源化,让它能被前端页面访问到,然后在controller里面引用在这个资源路径通过picutil将图片存储在这个路径下,这样之后你只要返回给前台文件名,再进行一些简单处理,img的src标签就能直接访问到了,具体如下

springBoot配置类部分代码

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Created by carlson chis on 2019/1/10 0010.
 * Describe:
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //在D:/imgdemo/下如果有一张 Excalibar.jpg的图片,那么:
        //【1】访问:http://localhost:8080/imgs/Excalibar.jpg 可以访问到
        //【2】html 中 
        registry.addResourceHandler("/imgs/**").addResourceLocations("file:D:/imgdemo/");
    }
}

这里还是非常感谢那位优雅的博客主:
https://blog.csdn.net/qq_30447263/article/details/81085171

springMvc部分代码

 /**
     * 获取图片
     * @param tch_id
     * @return
     */
    @RequestMapping(value = "findPicByTchId")
    public String findPicByTchId(int tch_id){
        return teacherService.findPicByTchId(tch_id);
    }

这里就返回了图片的文件名,例如1547193961615.png

js部分代码

//获取讲师照片
    $scope.findPicByTchId=function(tch_id){ 
        $http.get('http://localhost:8486/teacher/findPicByTchId?tch_id='+tch_id).success(function(response){
                var pic_url = "http://localhost:8486/imgs/"+response;
                $("#tch_pic").attr("src", pic_url);  //给img赋值,显示图片
            }
        });
    }

html部分代码

大概的过程就是这样子,如果有问题,请指正呀。。。。

参考链接
https://blog.csdn.net/xllily_11/article/details/52330280
https://www.cnblogs.com/yangtoude/p/jquery-ajax-formdata-upload.html
https://blog.csdn.net/qq_41669724/article/details/80748952
https://blog.csdn.net/wei389083222/article/details/51289704
https://blog.csdn.net/qq_30447263/article/details/81085171

你可能感兴趣的:(项目笔记)