“This is the sixth day of my participation in the First Challenge 2022. For details: First Challenge 2022”

As mentioned in the title, I recently encountered a scenario problem. Initially, I wanted to transfer flows between microservices. It turned out that the flow would be lost in the process of transfer

1 Scenario Problems

In daily projects, there are often functions to import and export Excel. In the first requirement function, the function design is as follows: the front-end uploads Excel to the background, the background parses Excel, uploads the file to the cloud server, and returns the file fileId. After clicking the submit button on the page, the background will download the file stream from the cloud server according to the fileId of the file.

In the initial design scheme, the back-end microservice is divided into different services according to different functions, so the operation of cloud service data is a single microservice, and the common business microservice module is only accessed through feIGN, so feIGN interface invocation is adopted

The feIGN interface call directly passes the file stream as a common parameter in the FEIGN interface. There is a problem in the way of feIGN call, that is, the queried stream cannot be returned to the business service.

Graph LR A[Business Services] -->B(Cloud Related Services) B[Cloud related Services] -->A(Business Services)

2 Solution

Query related data and find that the stream cannot be directly called through the FEIGN interface, because the stream cannot be effectively converted during transmission, so the received stream is empty. There are two ways to solve this problem. The first way is to transfer the stream into a byte array, which can be effectively transferred in feIGN interface calls. The second passes the flow through a Response object; Feign interface calls need to be configured to pass streams.

1 through the byte array

Cloud Service Interface

    @PostMapping("/upload")
    @ResponseBody
    public byte[] upload() throws IOException {

        // Simulate a file stream from a cloud service
        InputStream is = new ZipInputStream(null);

        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while((len = is.read(buffer)) ! = -1) {
            bos.write(buffer,0,len);
        }
        bos.flush();
        return bos.toByteArray();
    }
Copy the code

Feign interface

    @PostMapping("/upload")
    @ResponseBody
    byte[] upload();
Copy the code

Business services

    byte[] bytes = ossClient.upload();
	InputStream is = new ByteArrayInputputStream(bytes);
Copy the code

2 through the Response


    @PostMapping("/upload")
    @ResponseBody
    public void upload(HttpServletResponse resp) throws IOException {

        // Simulate a file stream from a cloud service
        InputStream is = new ZipInputStream(null)
              
        OutputStream os = response.getOutputStream();
        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = is.read(bytes)) ! = -1) {
            os.write(bytes, 0, len);
        }
        is.close();
        os.flush();
        os.close();
   
    }
Copy the code

Feign interface

    @PostMapping("/upload")
    @ResponseBody
    feign.Response upload(HttpServletResponse resp);
Copy the code

Business services

    Response response = ossClient.upload();
	InputStream is = response.body().asInputStream();
Copy the code

3 summary

It can be seen from the above methods that the flow is transmitted through transformation, and there is no way to directly transmit the flow. For the third method, we still need to learn and explore, and we welcome knowledgeable scholars to supplement and correct.