如何返回多值响应



我目前正在撰写一篇文章API,它获取发票编号列表,然后使用resttamplate调用另一个API,以获取每个发票编号的pdf。之后,我将所有这些pdf文件连接到一个文件中,并返回该文件作为响应,这里的问题是,有发票有一个无效的发票号码,所以当我将此发票号码发送给其余的API时,无法获取pdf,所以我想获取失败的发票并将其发送回我的其余API的调用方,如何返回成功发票的pdf和包含失败发票号码列表的JSON对象。提前感谢那是我的Api后

@PostMapping(value = "/gen-report")
public ResponseEntity<byte[]> generateReport(
@RequestHeader(value = HttpHeaders.AUTHORIZATION) String headerAuthorization) {
byte[] res = null;
List<String> failedInvoices = new ArrayList<>();
ResponseEntity<byte[]> response = null;
ArrayList<RequestParameters> requests = new ArrayList<>();
RequestParameters rp1 = new RequestParameters("360", "3600382368", "N");
RequestParameters rp2 = new RequestParameters("360", "3600382367", "N");
requests.add(rp1);
requests.add(rp2);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
List<byte[]> responses = new ArrayList<>();
for (RequestParameters parameter : requests) {
MultiValueMap<String, String> map = mobileOrderReportService.genrateReportService(parameter);
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
response = null;
byte[] content = null;
content = requestReportByInvoiceNumber(entity);
if (content != null) {
responses.add(content);
} else {
failedInvoices.add(parameter.getOrderNum());
}
}
try {
res = mergePDF(responses);
} catch (DocumentException ex) {
Logger.getLogger(MobileOrderReportController.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(MobileOrderReportController.class.getName()).log(Level.SEVERE, null, ex);
}
headers.setContentType(MediaType.parseMediaType("application/pdf"));
String filename = "pdf1.pdf";
headers.add("content-disposition", "inline;filename=" + filename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
response = new ResponseEntity<byte[]>(res, headers, HttpStatus.OK);
return response;
}

该方法在成功发票时返回字节[],在失败发票时返回null

public byte[] requestReportByInvoiceNumber(HttpEntity<MultiValueMap<String, String>> entity) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<byte[]> response = null;
try {
response = restTemplate.exchange(mobileOrderReportService.getUrl(), HttpMethod.POST, entity,
byte[].class);
byte[] content = response.getBody();
return content;
} catch (RestClientException ex) {
logger.error("request to UReport failed in requestReportByInvoiceNumber method !...");
return null;
}
}

方法合并pdf并返回一个pdf

public byte[] mergePDF(List<byte[]> pdfFilesAsByteArray) throws DocumentException, IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Document document = null;
PdfCopy writer = null;
for (byte[] pdfByteArray : pdfFilesAsByteArray) {
try {
PdfReader reader = new PdfReader(pdfByteArray);
int numberOfPages = reader.getNumberOfPages();
if (document == null) {
document = new Document(reader.getPageSizeWithRotation(1));
writer = new PdfCopy(document, outStream); // new
document.open();
}
PdfImportedPage page;
for (int i = 0; i < numberOfPages;) {
++i;
page = writer.getImportedPage(reader, i);
writer.addPage(page);
}
} catch (Exception e) {
e.printStackTrace();
}
}
document.close();
outStream.close();
return outStream.toByteArray();
}

您已经标记了"Multipart";,这可能是一个解决方案。您当前发送的不是一个,而是一个字节数组,即一个文件。使用多部分响应,您确实可以有多个(或者在您的情况下是2个(部分:

  • 与合并的PDF部分
  • 失败发票编号的列表,可以是纯文本、JSON,也可以是您希望发送的方式

多部分响应如下https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html(向下滚动至示例(

一个更容易和";"更脏";方法是,只需在您的标题响应中包含错误的发票号码。您可以定义自定义标头,因此可以随意命名。

无论哪种方式,您的客户端都需要进行调整,要么能够读取多部分响应(如果您的客户端没有反应式通信,则需要为此编写HttpMessageConverter(Webflux((,要么读取自定义标头。

最新更新