跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • SpringBoot 接口怎么传数据库中的 BLOB 图片给前端
未分類
2 10 月 2020

SpringBoot 接口怎么传数据库中的 BLOB 图片给前端

SpringBoot 接口怎么传数据库中的 BLOB 图片给前端

資深大佬 : sandman511 9

单张或者多张的 求大佬讲个方案 现在是能传 但想要个最佳方案。。虽然数据库存图片就离谱。。。。

大佬有話說 (26)

  • 資深大佬 : RedBeanIce

    都 springboot 了,数据库还存图片的二进制吗?

  • 資深大佬 : myCupOfTea

    数据库存图片确实离谱

  • 資深大佬 : muskill

    存 base64 呢

  • 資深大佬 : lower

    现在的方案是什么样的呢?

  • 資深大佬 : napsterwu

    blob 直接当成文件下载送出去,前端直接用 img src 拿

  • 資深大佬 : monkeyWie

    提供一个接口,然后以字节流的方式写出图片不就行了吗,注意设置好正确的 Content-Type 就行

  • 資深大佬 : yazinnnn

    说实话,数据库存图片挺扯淡的

  • 資深大佬 : fhsan

    http body stream

  • 資深大佬 : charten

    我从前端的角度谈一下,我们这边请求 blob 实际上就是请求二进制流,跟普通的请求没什么区别。你只要把图片的二进制数据放进 body 就可以了。另外,如果有请求多张的情况,可以跟前端约定好一个二进制格式,比如以某个字符,比如 0x3b 之类的作为文件的开头,后面加 4 个字节用于表示图片的二进制长度:
    0x3b 0x00 0x00 0x11 0xff <图片数据….4607 个字节>
    0x3b 0x00 0x00 0x22 0xff <图片数据…8959 个字节>
    …

  • 資深大佬 : securityCoding

    不要在错误的路上越走越远 , 掉头吧

  • 資深大佬 : wysnylc

    调头,OSS

  • 資深大佬 : justlikemaki

    敏感图片你们也存 oss ?

  • 資深大佬 : crclz

    @GetMapping(“{id}”)
    public ResponseEntity<byte[]> getFile(@PathVariable long id) {
    var blob = blobRepository.findById(id).orElse(null);
    return ResponseEntity.ok()
    .contentType(MediaType.IMAGE_JPEG)
    .body(blob.getData());
    }

  • 資深大佬 : spacebound

    @monkeyWie +1,前端直接不用处理,调接口就行了

  • 資深大佬 : 0x666666

    都 0202 年了,微服务都用上了,数据库还存图片?

  • 資深大佬 : tanranran

    base64

  • 資深大佬 : radiocontroller

    专业的事交给专业的服务

  • 資深大佬 : ztechstack

    InputStreamResource resource = new InputStreamResource(gridFSDBFile.getInputStream(),
    gridFSDBFile.getFilename());

    return (ResponseEntity<Resource>) ResponseEntity
    .ok()
    .header(HttpHeaders.CONTENT_DISPOSITION, “attachment; filename=”” + gridFSDBFile.getFilename() + “””)
    .contentLength(gridFSDBFile.getLength())
    .contentType(MediaType.APPLICATION_OCTET_STREAM)
    .body(resource);

  • 資深大佬 : ztechstack

    如果是 byte[], 可以使用 ByteArrayResource

  • 資深大佬 : zjsxwc

    还不如图片加密后文件保存本地,mysql 存图片解密密码,需要的时候通过密码和加密后的文件得到原图返回给客户端

  • 資深大佬 : hejingyuan199

    虽然我不知道如何回答。
    但我想附和一下,我也是把图片存数据库的。

    我现在的项目是个测试性项目,不是正规使用。
    我们的数据库供所有开发人员同时使用的。

    不同的开发人员有不同的功能,功能互不干涉,但是共用一个数据库和表。
    如果图片存在服务器本地,数据库只存图片名称,那大家各自在测试时都拿不到图片。
    所以我把图片转成 Base64 字符串存进数据库了。
    还有的表里存着 Blob 类型的用户上传的附件(文件或图片)。

    一直看到大家说大文件不应该存数据库,
    也许未来转为生产环境时候再改吧。

    如果数据库存着 Base64 字符串,往前端发送应该比较简单了吧。
    Blob 我看到我们的这边用的是,
    (代码风格很渣,随便接受 Critics )

    /***** Student Chose One Application*****/
    @RequestMapping(value=”/history/{ticketNum}”, method=RequestMethod.GET)
    public String historyApplication(@PathVariable String ticketNum, Model model, HttpServletRequest request) {
    String search = (String) request.getSession().getAttribute(“searchTicketNum”);
    Optional<Application> app = applicationService.findApplication(ticketNum);
    if (app.isPresent()) {
    model.addAttribute(“applicationObj”, app.get());
    Optional<User> user = AIBTuserdetailsService.findByUserName(app.get().getCreatedBy());
    model.addAttribute(“userObj”,user.get());
    model.addAttribute(“urlTicketNum”, ticketNum);

    model.addAttribute(“documents”, applicationService.getDocumentUrl(ticketNum, app.get().getId()));
    ————————————————————————————————–
    //调用 blob 类型的文件

    model.addAttribute(“logs”, applicationService.getAuditLog(app.get().getId()));
    //Optional<Course> course = courseService.findByCourseid(user.get().getCurrentCourseCode());
    //if(course.isPresent()) {
    // model.addAttribute(“course”, course.get().getCourseName());}
    //else {
    // model.addAttribute(“course”, “Not found”);
    //}
    }
    model.addAttribute(“applicationList”, applicationService.findApplications(search));
    return “student/history”;
    }

    In ApplicationService.java

    public Map<String, String> getDocumentUrl(String ticketNum, int applicationId) {
    Map<String, String> result = new HashMap<>();
    for (String fileName : documentRepository.findAllFileNameByApplicationId(applicationId)) {
    ———————————————————————————
    //get document out from Database

    if (!fileName.isEmpty()) {
    try {
    result.put(fileName, ticketNum + “/” + URLEncoder.encode(fileName, String.valueOf(StandardCharsets.UTF_8)));
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    }
    }
    if (result.isEmpty()) {
    return null;
    } else {
    return result;
    }
    }

    In DocumentRepository.java

    public interface DocumentRepository extends JpaRepository<Document, Integer> {
    Optional<Document> findByFileNameAndApplicationId(String fileName, int applicationId);
    @Query(value=”select file_name from document where application_id =:application_id”, nativeQuery=true)
    List<String> findAllFileNameByApplicationId(@Param(“application_id”) int applicationId);
    }

    //This is parts of Class Document

    @Entity
    @Table(name = “Document”)
    public class Document {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private int applicationId;
    private String fileName;
    private String fileType;
    @Lob
    private byte[] data;
    …
    }

    仅供参考
    这个流程似乎就是前面一些 V 友说的以文件下载方式传到前端的。

    前端是这样的:
    <div class=”three”>
    <p>
    <b>Attachment:</b>
    </p>
    <div class=”links”>
    <a target=”_blank” th:each=”element : ${documents}”
    th:href=”@{/student/downloadFile/{url}(url=${element.value})}”><img th:src=”@{/image/qubiezhen.png}”>[[${element.key}]]</a>
    </div>
    </div>

  • 資深大佬 : hejingyuan199

    @hejingyuan199

    补上最关键的数据传输

    @RequestMapping(value=”/downloadFile/{ticketNum}/{fileName}”, method=RequestMethod.GET)
    public ResponseEntity<Resource> downloadFile(@PathVariable String ticketNum, @PathVariable String fileName) {
    // Load file from database
    Optional<Document> doc = applicationService.getDocument(ticketNum, fileName, Boolean.FALSE);

    if (doc.isPresent()) {
    return ResponseEntity.ok()
    .contentType(MediaType.parseMediaType(doc.get().getFileType()))
    .header(HttpHeaders.CONTENT_DISPOSITION, “attachment; filename=”” + doc.get().getFileName() + “””)
    .body(new ByteArrayResource(doc.get().getData()));
    } else {
    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
    }

  • 資深大佬 : bxd5812127

    后端给前端提供两个接口,一个拿所有图片的 id,一个根据 id 拿一个图片,前端根据 id 排队拿图片有没有搞头,拿完一个在拿一个。

  • 資深大佬 : THESDZ

    后端应该提供的能力是 <img src=”url”/> 的这个 url,内部实现可以直接通过 resp 传输流

  • 資深大佬 : hyperbin

    @charten 怎么保证图片里没有 0x3b ?

  • 資深大佬 : charten

    @hyperbin 不用保证呀,又不是拿 0x3b 去当分割符,0x3b 只是一个标识符,标识符一个块的开始,这个标识符可以 0x00 到 0xff 的任意一个字符,关键是紧跟着的后四位字节,代表了这个块的长度,你真正要拿图片要通过这个长度去拿,就是 slice 方法。当然也可以根据这个长度跳过去拿下一张图片。psd 文件的二进制格式基本上都是这样的

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具