Jak przysłać pobierane bajty plików z Azure Storage i je do controllera?

0

Cześć wszytkim ! Dostaję URL do pliku na Azurze i jest prawidłowy. Natomiast gdy staram się przesłać tablicę bajtów każedo pliku dostaję w postman coś takiego( patrzeć na screenshota) mysłałem że dostanę tablicę bajtów, natomiast dostaje od razu zserealizowany tekst i zdjęcie... Które wygląda że źle się zserealizowało. Jak można to naprawić żeby dostawać same bajty plików? I Dlatego zdjęcie wygląda w taki sposób?
Controller

    @PostMapping("/files/getBytes")
    public ResponseEntity<byte[]> getFileBytes(@RequestBody List<String> keys) {
        return filesStore.getBytes(keys);
    }

Service

    public List<URL> getUrls(List<String> keys) {
        List<URL> urls = new ArrayList<>();
        if (keys.size() == 0) return urls;
        BlobContainerSasPermission blobContainerSasPermission = new BlobContainerSasPermission()
                .setReadPermission(true);
        BlobServiceSasSignatureValues builder = new BlobServiceSasSignatureValues(OffsetDateTime.now().plusDays(1), blobContainerSasPermission)
                .setProtocol(SasProtocol.HTTPS_ONLY);
        keys.forEach(it -> {
            try {
                urls.add(new URL(blobClient.getClient().getBlobClient(it).getBlobUrl() + "?" + blobClient.getClient().generateSas(builder)));
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        });

        return urls;
    }

    public ResponseEntity<byte []> getBytes(List<String> keys) {
        List<ByteArrayOutputStream> outputStreams = new ArrayList<>();

        getUrls(keys).forEach(it -> {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            InputStream inputStream = null;
            try {
                inputStream = it.openStream();
                byte[] byteChunk = new byte[4096];
                int readByte;
                while ((readByte = inputStream.read(byteChunk)) > 0)
                    byteArrayOutputStream.write(byteChunk, 0, readByte);

                outputStreams.add(byteArrayOutputStream);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return ResponseEntity.ok().headers(headers).body(Arrays.toString(outputStreams.toArray()).getBytes());
    }
1

Na oko to pewnie ten Arrays.toString() doda Ci sporo dodatkowych znaków, bo to jest dla ludzi, a nie dla maszyn.

Jeśli nie zależy Ci jakoś szczególnie na transferze to użyj wbudowanego w Springa mechanizmu serializacji.

return ResponseEntity.ok().headers(headers).body(outputStreams.stream().map(b -> b.toByteArray()).collect(Collectors.toList()));

To Ci zwróci tablicę z danymi w base64.

1

Arrays.toString(outputStreams.toArray()).getBytes()

To nie robi tego co chcesz. Ani trochę. Jednocześnie nie do końca rozumiem co ty chcesz dostać w odpowiedzi. Posklejane bajty z wielu plików? Jaki to ma sens?
Dodatkowo takie składanie w pamięci pewnie skończy się szybko OutOfMemory. Spring ma takie cudo jak kontroler z typem zwracanym ResponseEntity<StreamingResponseBody> gdzie body jest takim cudakiem

StreamingResponseBody streamingResponseBody = outputStream -> someFunctionWritingToStream(outputStream );

I w ten sposób możesz pisać bezpośrednio bez składowania wszystkiego w pamięci.

0

test.png

0
  @PostMapping("/files/getBytes")

    public ResponseEntity<StreamingResponseBody> getFileBytes(@RequestBody List<String> keys) {

        StreamingResponseBody stream = output -> filesStore.getBytes(keys, output);

        return ResponseEntity

                .ok()

                .contentType(MediaType.APPLICATION_OCTET_STREAM)

                .body(stream);

    }

    public List<URL> getUrls(List<String> keys) {

        List<URL> urls = new ArrayList<>();

        if (keys.size() == 0) return urls;

        BlobContainerSasPermission blobContainerSasPermission = new BlobContainerSasPermission()

                .setReadPermission(true);

        BlobServiceSasSignatureValues builder = new BlobServiceSasSignatureValues(OffsetDateTime.now().plusDays(1), blobContainerSasPermission)

                .setProtocol(SasProtocol.HTTPS_ONLY);

        keys.forEach(it -> {

            try {

                urls.add(new URL(blobClient.getClient().getBlobClient(it).getBlobUrl()+"?"+blobClient.getClient().generateSas(builder)));

                urls.add(new URL(blobClient.getClient().getBlobClient(it).getBlobUrl() + "?" + blobClient.getClient().generateSas(builder)));

            } catch (MalformedURLException e) {

                e.printStackTrace();

            }

        });


        return urls;

    }


    public void getBytes(List<String> keys, OutputStream outputStream) {

        getUrls(keys).forEach(url -> {

            InputStream inputStream = null;

            try {

                inputStream = url.openStream();


                int numberOfWrittenByte;

                byte[] data = new byte[1024];

                while ((numberOfWrittenByte = inputStream.read(data, 0, data.length)) != -1)

                    outputStream.write(data, 0, numberOfWrittenByte);


            } catch (IOException e) {

                e.printStackTrace();

            } finally {

                try {

                    if (inputStream != null)

                        inputStream.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        });

    }
0

Na moje oko jest ok. Dostałeś ładnie posklejane bajty z tych kilku plików. Prawdziwe pytanie brzmi:. Co ty w ogóle chcesz osiągnąć? Bo takie sklejanie bajtów ma zero sensu. A oglądanie bajtów binarnego pliku jako tekstu na sensu jeszcze mniej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1