首页 > 解决方案 > 响应实体返回两个服务方法

问题描述

我有两个服务返回两个不同的 ResponseEntity。

public ResponseEntity<InputStreamResource> getA(...) {
return ResponseEntity
            .ok()
            .headers(headers)
            .contentType(MediaType.APPLICATION_PDF)
            .contentLength(out.size())
            .body(new InputStreamResource(bis)); }
public ResponseEntity<InputStreamResource> getB(...) {
return ResponseEntity
            .ok()
            .headers(headers)
            .contentType(MediaType.APPLICATION_PDF)
            .contentLength(out.size())
            .body(new InputStreamResource(bis)); }

每个服务都有一个调用和返回的控制器。

public ResponseEntity<InputStreamResource> getA(...) {
return aService.getA(...) }
public ResponseEntity<InputStreamResource> getB(...) {
return bService.getB(...) }

我正在尝试创建另一个控制器,它可以同时返回这两个服务。

public ResponseEntity<InputStreamResource> getAB(...) {
return aService.getA(...) *and* bService.getB(...) ?????? }

不确定如何将两个 ResponseEntities 返回合并为一个。

标签: javaspringcontroller

解决方案


从 Service 方法返回 ResponseEntity 不是一个好主意。

控制器层应该负责生成 ResponseEntity 对象。那是他的事,不是服务层的事。同样,服务层的职责是根据给定的输入准备某种 DTO 对象,然后控制器将环绕该 DTO 并将其作为响应发送。

所以,我建议在这里做一些结构性的改变。

服务层

public InputStreamResource getA(...) {
  return A 
}
public InputStreamResource getB(...) {
  return B 
}

控制器层

public ResponseEntity<InputStreamResource> getA(...) {
  return new ResponseEntity<>(aService.getA(...) (
}
public ResponseEntity<InputStreamResource> getB(...) {
  return new ResponseEntity<>(bService.getB(...) )
}

合并 2 个流


如果您的目标是一个接一个地流式传输 2 个不同的 pdf 文档,那么我认为可以先将内存中的 pdf 文档与您可能使用的任何 pdf 库合并。然后创建一个 InputStreamResource 作为响应。

但是,如果流可以按顺序运行,那么下面是一个使用SequenceInputStream合并 2 个流的工作示例-

@RequestMapping(
        path = "/sayHello",
        method = RequestMethod.GET,
        produces = MediaType.TEXT_PLAIN_VALUE
)
public ResponseEntity<InputStreamResource> get() {
        byte[] inputBytes1 = "Hello".getBytes();
        // 1st stream has "Hello" text
        ByteArrayInputStream baos1 = new ByteArrayInputStream(inputBytes1);

        byte[] inputBytes2 = "World".getBytes();
        // 2nd stream has "World" text
        ByteArrayInputStream baos2 = new ByteArrayInputStream(inputBytes2);

        // combined stream will have "HelloWorld" text
        SequenceInputStream combinedStream = new SequenceInputStream(baos1, baos2);
        InputStreamResource inputStreamResource = new InputStreamResource(combinedStream);
        return ResponseEntity.ok().body(inputStreamResource);
    }

输出->

 curl -X GET  http://localhost:8083/sayHello
 HelloWorld

推荐阅读