简体   繁体   中英

how return multivalued response

I'm currently writing a post API that gets a list of invoices number and then calls another API with resttamplate to obtain a pdf for every invoice number after that I concatenate all these pdf files to one file and return this file as a response, the problem here that there are invoices have an invalid invoice number so when I send this invoice number to the rest API can't get pdf so I want to get the failed invoices and send them back to the caller of my rest API, how to return pdf of the successful invoice and JSON object that contain a list of failed invoices number. Thanks in advance that's my postApi

    @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;
    }

this method returns the byte[] with the successful invoice or null with the failed invoice

    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;
        }
    }

method merge pdf and return one 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();

    }

You already tagged "Multipart", which could be a solution. You're currently not sending one but just a byte array ie a file. With a multipart response, you could indeed have multiple (or in your case 2) parts:

  • Part with the merged PDF
  • List of failed invoice numbers either as plain text, JSON, or however you would like to send it.

A multipart response looks like this https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html (scroll down to the example)

An easier and "dirtier" way would be, to just include the faulty invoice numbers in your header response. You can define custom headers, so feel free to name it as you wish.

Either way, your client needs to be adapted, either by being able to read a multipart response (for which you need to write an HttpMessageConverter if your client isn't communicating reactively (Webflux)) or by reading the custom header.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM