单张或者多张的 求大佬讲个方案 现在是能传 但想要个最佳方案。。虽然数据库存图片就离谱。。。。
1
RedBeanIce 2020-09-25 09:20:42 +08:00
都 springboot 了,数据库还存图片的二进制吗?
|
2
myCupOfTea 2020-09-25 09:22:56 +08:00
数据库存图片确实离谱
|
3
muskill 2020-09-25 09:22:59 +08:00
存 base64 呢
|
4
lower 2020-09-25 09:27:28 +08:00
现在的方案是什么样的呢?
|
5
napsterwu 2020-09-25 09:27:49 +08:00 via iPhone 1
blob 直接当成文件下载送出去,前端直接用 img src 拿
|
6
monkeyWie 2020-09-25 09:28:00 +08:00
提供一个接口,然后以字节流的方式写出图片不就行了吗,注意设置好正确的 Content-Type 就行
|
7
yazinnnn 2020-09-25 09:44:40 +08:00
说实话,数据库存图片挺扯淡的
|
8
fhsan 2020-09-25 09:49:35 +08:00
http body stream
|
9
charten 2020-09-25 09:56:19 +08:00 1
我从前端的角度谈一下,我们这边请求 blob 实际上就是请求二进制流,跟普通的请求没什么区别。你只要把图片的二进制数据放进 body 就可以了。另外,如果有请求多张的情况,可以跟前端约定好一个二进制格式,比如以某个字符,比如 0x3b 之类的作为文件的开头,后面加 4 个字节用于表示图片的二进制长度:
0x3b 0x00 0x00 0x11 0xff <图片数据....4607 个字节> 0x3b 0x00 0x00 0x22 0xff <图片数据...8959 个字节> ... |
10
securityCoding 2020-09-25 10:02:57 +08:00
不要在错误的路上越走越远 , 掉头吧
|
11
wysnylc 2020-09-25 10:16:40 +08:00
调头,OSS
|
12
justlikemaki 2020-09-25 10:34:31 +08:00
敏感图片你们也存 oss ?
|
13
crclz 2020-09-25 10:54:05 +08:00 1
@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()); } |
14
spacebound 2020-09-25 11:19:15 +08:00
@monkeyWie +1,前端直接不用处理,调接口就行了
|
15
0x666666 2020-09-25 11:28:03 +08:00
都 0202 年了,微服务都用上了,数据库还存图片?
|
16
tanranran 2020-09-25 11:28:44 +08:00
base64
|
17
radiocontroller 2020-09-25 11:30:32 +08:00
专业的事交给专业的服务
|
18
zliea 2020-09-25 11:32:45 +08:00
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); |
19
zliea 2020-09-25 11:33:37 +08:00 1
如果是 byte[], 可以使用 ByteArrayResource
|
20
zjsxwc 2020-09-25 11:46:19 +08:00
还不如图片加密后文件保存本地,mysql 存图片解密密码,需要的时候通过密码和加密后的文件得到原图返回给客户端
|
21
hejingyuan199 2020-09-25 15:27:58 +08:00
虽然我不知道如何回答。
但我想附和一下,我也是把图片存数据库的。 我现在的项目是个测试性项目,不是正规使用。 我们的数据库供所有开发人员同时使用的。 不同的开发人员有不同的功能,功能互不干涉,但是共用一个数据库和表。 如果图片存在服务器本地,数据库只存图片名称,那大家各自在测试时都拿不到图片。 所以我把图片转成 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> |
22
hejingyuan199 2020-09-25 15:33:30 +08:00
@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); } } |
23
bxd5812127 2020-09-25 16:15:34 +08:00
后端给前端提供两个接口,一个拿所有图片的 id,一个根据 id 拿一个图片,前端根据 id 排队拿图片有没有搞头,拿完一个在拿一个。
|
24
THESDZ 2020-09-25 16:34:35 +08:00
后端应该提供的能力是 <img src="url"/> 的这个 url,内部实现可以直接通过 resp 传输流
|