1

I am trying to download a file from rest API, I am writing code in Java and react. but when i call that rest api it is not downloading that file instead gives me some garbage

      @POST
            @Path("/{loginId}")
            @Produces(MULTIPART_FORM_DATA)
            @Consumes(APPLICATION_JSON)
            public Response downloadExportedFile(@PathParam("loginId") String loginId, ExportFileDTO fileDetails) {
        File exportFolder = new File("C://directory");

                        File[] listOfFiles = exportFolder.listFiles();
for (File listOfFile : listOfFiles) {
           if (listOfFile.getName().equals(fileDetails.getFileName())) {
                                            InputStream is = new FileInputStream(listOfFile.getAbsolutePath());
                                            byte[] buffer = IOUtils.toByteArray(is);
                                            return Response.ok(listOfFile)
                                                    .header("content-disposition", "attachment; filename=" + new File(listOfFile.getName()).getName())
                                                .type(MediaType.APPLICATION_OCTET_STREAM_TYPE).build();
                                    }
    }

It should download the file instead it is giving me output as PK!b�h^�[Content_Types].xml �(����N�0E�H�C�-Jܲ@5��Q>�ēƪc[�ii����B�j7���{2��h�nm���ƻR����U^7/���%��rZY�@1__�f��q��R4D�AJ�h>����V�ƹ�Z�9����NV�8ʩ����ji){^��-I�"{�v^�P!XS)bR�r��K�s(�3�`c�0��������7M4�����ZƐk+�|\|z�(���P��6h_-[�@�!���Pk���2n�}�?�L��� ��%���d����dN"m,�ǞDO97�~��ɸ8�O�c|n���E������B��!$}�����;{���[����2���PK!�U0#�L_rels/.rels �(���MO�0��H�����ݐBKwAH�!T~�I����$ݿ'T�G�~����<���!��4��;#�w����qu*&r�Fq���v�����GJy(v��*����K��#F��D��.W ��=��Z�MY�b���BS�����7��ϛז�� ?�9L�ҙ�sbgٮ|�l!��USh9i�b�r:"y_dl��D���|-N��R"4�2�G�%��Z�4�˝y�7 ë��ɂ�����PK!

Monika
  • 195
  • 1
  • 1
  • 10

3 Answers3

0

According to this other stackoverflow question you should change the @Produces annotation to @Produces(MediaType.APPLICATION_OCTET_STREAM).

According to this second stackoverflow question you are asking an impossible question.

Out of curiosity I reproduced your problem here : see the full gist

  • If you change @POST to @GET it starts working
  • If you keep @POST, it has to be posted from a real form and can't post application/json
  • Finally, posting application/json means React is doing a programmatic XmlHTTPRequest. The above gist shall convince you there is no user prompt in that case

When you say it 'is giving me output', you're not telling where and how the post was requested . You will have to adapt that part.

Suricat
  • 131
  • 4
  • I tried @Produces(MediaType.APPLICATION_OCTET_STREAM) this also.. same output.. then I tried simple .txt .. it is showing me content of that .txt in response but not downloading that file – Monika Jul 27 '18 at 05:50
0

You have to change the associated mimetype by changing the the parameter of the @Produces annotation which basically describes what type of data you transmit in your response.

It should become:

@Produces("application/vnd.ms-excel")
C.Champagne
  • 5,381
  • 2
  • 23
  • 35
  • I want generic downloader for that I tried public final static String APPLICATION_OCTET_STREAM = "application/octet-stream"; but my problem is that file is not getting downloaded at client machine – Monika Jul 27 '18 at 05:56
0

actually It is APPLICATION_OCTET_STREAM response for a file. we have to handle download functionality at client side AS per Nate's answer here, the response of Ajax request is not recognized by a browser as a file. It will behave in the same way for all Ajax responses. You need to trigger the download popup manually.

downloadFile(fileDetails) {
    let username = getUserName();
    return fetch(`/files/${username}`, {
        method: 'POST',
        body: JSON.stringify(fileDetails)
    }).then(response => {
        return response.blob();
    }).then(response => {
        let blob = new Blob([response], {type: 'application/octet-stream'});
        let fileUrl = window.URL.createObjectURL(blob);
        Files.triggerDownload(fileUrl, fileDetails.fileName);
    }).catch((error) => {
        //myerror
    });
}

static triggerDownload(url, fileName) {
        let a = document.createElement('a');
        a.setAttribute('href', url);
        a.setAttribute('download', fileName);
        a.click();
    }

This will download the file at client machine

Monika
  • 195
  • 1
  • 1
  • 10