如何在 JAVA 的 rest API 中将图像返回给浏览器?

Posted

技术标签:

【中文标题】如何在 JAVA 的 rest API 中将图像返回给浏览器?【英文标题】:How to return an Image to browser in rest API in JAVA? 【发布时间】:2018-03-18 10:28:25 【问题描述】:

我想在点击localhost:8080:/getImage/app/path=imagePath 之类的 API 时获取图像

当我点击这个 API 时,它会返回一个图片。

这可能吗?

实际上,我已经尝试过了,但它给了我一个错误。 这是我的代码,

@GET
@Path("/app")
public BufferedImage getFullImage(@Context UriInfo info) throws MalformedURLException, IOException 
    String objectKey = info.getQueryParameters().getFirst("path");

    return resizeImage(300, 300, objectKey);



public static BufferedImage resizeImage(int width, int height, String imagePath)
        throws MalformedURLException, IOException 
    BufferedImage bufferedImage = ImageIO.read(new URL(imagePath));
    final Graphics2D graphics2D = bufferedImage.createGraphics();
    graphics2D.setComposite(AlphaComposite.Src);
    // below three lines are for RenderingHints for better image quality at cost of
    // higher processing time
    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    graphics2D.drawImage(bufferedImage, 0, 0, width, height, null);
    graphics2D.dispose();
    System.out.println(bufferedImage.getWidth());
    return bufferedImage;

我的错误,

java.io.IOException: The image-based media type image/webp is not supported for writing

有什么方法可以在点击 java 中的任何 URL 时返回图像?

【问题讨论】:

将图像存储为 base64 编码字符串并返回该字符串。如果需要,我可以提供示例代码 【参考方案1】:

您可以使用IOUtils。这是代码示例。

@RequestMapping(path = "/getImage/app/path/filePath", method = RequestMethod.GET)
public void getImage(HttpServletResponse response, @PathVariable String filePath) throws IOException 
    File file = new File(filePath);
    if(file.exists()) 
        String contentType = "application/octet-stream";
        response.setContentType(contentType);
        OutputStream out = response.getOutputStream();
        FileInputStream in = new FileInputStream(file);
        // copy from in to out
        IOUtils.copy(in, out);
        out.close();
        in.close();
    else 
        throw new FileNotFoundException();
    

【讨论】:

【参考方案2】:

我没有测试它,因为我在这台机器上没有环境,但逻辑上它应该像下面这样工作,将它作为输入流读取并让你的方法返回@ResponseBody byte[]

@GET
@Path("/app")
public @ResponseBody byte[] getFullImage(@Context UriInfo info) throws MalformedURLException, IOException 
    String objectKey = info.getQueryParameters().getFirst("path");

    BufferedImage image = resizeImage(300, 300, objectKey);
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    ImageIO.write(image, "jpg", os);
    InputStream is = new ByteArrayInputStream(os.toByteArray());
    return IOUtils.toByteArray(is);

更新 根据@Habooltak Ana 的建议,不需要创建输入流,代码应如下所示

@GET
@Path("/app")
public @ResponseBody byte[] getFullImage(@Context UriInfo info) throws
MalformedURLException, IOException 
    String objectKey = info.getQueryParameters().getFirst("path");

    BufferedImage image = resizeImage(300, 300, objectKey);
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    ImageIO.write(image, "jpg", os);
    return os.toByteArray();

【讨论】:

嗨,您在此方法中返回的输入流正在返回 byte[] 数组。它给出了错误。我应该在 pom.xml 或任何文件中添加一些东西吗? 你是对的,我告诉过你我没有这台机器的环境,但是我已经更新了答案,请检查 直接返回os.toByteArray()会更好【参考方案3】:

只需返回具有正确 HTTP 标头(Content-Type 和 Content-Disposition)的文件对象即可在大多数情况/环境中工作。

伪代码

File result = createSomeJPEG(); 
/*
 e.g.
 RenderedImage rendImage = bufferedImage;
 File file = new File("filename.jpg");
 ImageIO.write(rendImage, "jpg", file);
*/
response().setHeader("Content-Disposition", "attachment;filename=filename.jpg;");
response().setHeader("Content-Type", "image/jpeg");
return ok(result);

另见:

file downloading in restful web services what's the correct way to send a file from REST web service to client?

【讨论】:

【参考方案4】:

这是一个简单的解决方案:

@GET
@Path("/somePath")
public void getImage(@Context HttpServletResponse res) throws IOException 
    java.nio.file.Path path = Paths.get("filePath");
    res.getOutputStream().write(Files.readAllBytes(path));
    res.getOutputStream().flush();

【讨论】:

以上是关于如何在 JAVA 的 rest API 中将图像返回给浏览器?的主要内容,如果未能解决你的问题,请参考以下文章

在Angular 4中将数据发送到JAVA post REST API时出现CORS错误

如何在Spring Boot Rest API中的BeanUtils.copyProperties中将String转换为枚举

如何在yii2 restful api中将两个表中的关系数据显示为json格式

如何在 Django Rest Framework 中将当前用户设置为用户字段?

如何在 Laravel REST API 中使用 PUT 方法更新图像?

如何在 RAML 中将 REST 服务标记为已弃用