在对 BLOB 发出 GET 请求时,HttpServletResponse 如何与 fetch API 纠缠在一起?
How is HttpServletResponse entangled with the fetch API when making a GET request for a BLOB?
使用 Spring 启动,我正在尝试实现一个 REST 控制器,它可以处理一个 GET 请求,请求从我的数据库中 return 一个 BLOB 对象。
谷歌搜索了一下,并将各个部分放在一起,我创建了以下代码片段:
@GetMapping("student/pic/studentId")
public void getProfilePicture(@PathVariable Long studentId, HttpServletResponse response) throws IOException {
Optional<ProfilePicture> profilePicture;
profilePicture = profilePictureService.getProfilePictureByStudentId(studentId);
if (profilePicture.isPresent()) {
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(profilePicture.get().getPicture());
outputStream.close();
}
}
我正在使用 VanillaJS 和 fetch-API:
发送 GET 请求
async function downloadPicture(profilePic, studentId) {
const url = "http://localhost:8080/student/pic/" + studentId;
const response = await fetch(url);
const responseBlob = await response.blob();
if (responseBlob.size > 0) {
profilePic.src = URL.createObjectURL(responseBlob);
}
}
不知何故,这行得通。太好了,但是现在我想了解 HttpServletResponse
在这种情况下的用法,我并不熟悉。在我看来,fetch-API 使用了 HttpServletResponse(甚至可能创建它),因为我没有创建这个对象或对它做任何事情。
令我感到非常奇怪的是,我的控制器方法 getProfilePicture()
的 return 类型是 void
,但我仍在发送响应,这绝对不是无效。
此外,如果在我的数据库中找不到 profilePicture,例如由于传递了一个不存在的 studentId,我的控制器方法不会执行任何操作。但是,我仍然收到 200 的响应代码。这就是为什么我在我的 Javascript 中添加了 responseBlob.size > 0
部分以检查是否有肯定响应。
有人能给我解释一下这个魔法吗?
response.getOutputStream();
javadoc 说“Returns a ServletOutputStream 适合在响应中写入二进制数据。”它实际上是响应流,您将图片字节写入其中。它与客户端阅读响应无关。或者你可以 return 一个字节数组,它会自动写入响应流,结果是一样的。
要 return 不同的 http 状态代码,您应该将方法 return 类型更改为 ResponseEntity<byte[]>
:
@GetMapping("student/pic/studentId")
public ResponseEntity<byte[]> getProfilePicture(@PathVariable Long studentId, HttpServletResponse response) throws IOException {
Optional<ProfilePicture> profilePicture = profilePictureService.getProfilePictureByStudentId(studentId);
if (profilePicture.isPresent()) {
return ResponseEntity.ok(profilePicture.get().getPicture()); //status code 200
} else {
return ResponseEntity.notFound().build(); //status code 404
}
}
ResponseEntity 基本上是 return 不同状态 codes/messages.
的弹簧方式
您通过 javascript 手动下载图像是否有原因?您可以只创建一个带有 http link 的 img 元素到图像,浏览器将自动显示图像内容:<img src="http://localhost:8080/student/pic/studentId">
使用 Spring 启动,我正在尝试实现一个 REST 控制器,它可以处理一个 GET 请求,请求从我的数据库中 return 一个 BLOB 对象。
谷歌搜索了一下,并将各个部分放在一起,我创建了以下代码片段:
@GetMapping("student/pic/studentId")
public void getProfilePicture(@PathVariable Long studentId, HttpServletResponse response) throws IOException {
Optional<ProfilePicture> profilePicture;
profilePicture = profilePictureService.getProfilePictureByStudentId(studentId);
if (profilePicture.isPresent()) {
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(profilePicture.get().getPicture());
outputStream.close();
}
}
我正在使用 VanillaJS 和 fetch-API:
发送 GET 请求async function downloadPicture(profilePic, studentId) {
const url = "http://localhost:8080/student/pic/" + studentId;
const response = await fetch(url);
const responseBlob = await response.blob();
if (responseBlob.size > 0) {
profilePic.src = URL.createObjectURL(responseBlob);
}
}
不知何故,这行得通。太好了,但是现在我想了解 HttpServletResponse
在这种情况下的用法,我并不熟悉。在我看来,fetch-API 使用了 HttpServletResponse(甚至可能创建它),因为我没有创建这个对象或对它做任何事情。
令我感到非常奇怪的是,我的控制器方法 getProfilePicture()
的 return 类型是 void
,但我仍在发送响应,这绝对不是无效。
此外,如果在我的数据库中找不到 profilePicture,例如由于传递了一个不存在的 studentId,我的控制器方法不会执行任何操作。但是,我仍然收到 200 的响应代码。这就是为什么我在我的 Javascript 中添加了 responseBlob.size > 0
部分以检查是否有肯定响应。
有人能给我解释一下这个魔法吗?
response.getOutputStream();
javadoc 说“Returns a ServletOutputStream 适合在响应中写入二进制数据。”它实际上是响应流,您将图片字节写入其中。它与客户端阅读响应无关。或者你可以 return 一个字节数组,它会自动写入响应流,结果是一样的。
要 return 不同的 http 状态代码,您应该将方法 return 类型更改为 ResponseEntity<byte[]>
:
@GetMapping("student/pic/studentId")
public ResponseEntity<byte[]> getProfilePicture(@PathVariable Long studentId, HttpServletResponse response) throws IOException {
Optional<ProfilePicture> profilePicture = profilePictureService.getProfilePictureByStudentId(studentId);
if (profilePicture.isPresent()) {
return ResponseEntity.ok(profilePicture.get().getPicture()); //status code 200
} else {
return ResponseEntity.notFound().build(); //status code 404
}
}
ResponseEntity 基本上是 return 不同状态 codes/messages.
的弹簧方式您通过 javascript 手动下载图像是否有原因?您可以只创建一个带有 http link 的 img 元素到图像,浏览器将自动显示图像内容:<img src="http://localhost:8080/student/pic/studentId">