1

I have an application that works on Java and AngularJS.

I create pdf files with Java, using FileOutputStream to store them:

        @RequestMapping(value = "/getPdf",
                method = RequestMethod.GET)
        @RolesAllowed(AuthoritiesConstants.USER)
        public List<String> getPdf(@RequestParam(value = "id") Long id){
                FileOutputStream fileStream = null;
                String fileName = textRepository.findOne(id).getTitle() + ".pdf";
                String text = textRepository.findOne(id).getUserText();
                try {
                    fileStream = new FileOutputStream(fileName);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                // create an API client instance
                Client client = new Client("", "");
                client.convertHtml(text, fileName);

                try {
                    fileStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                List<String> out = new ArrayList<>();
                out.add(fileName);
                return out;
        }

 They are created in the root directory of my application.

Now I want to implement a functionality that lets the user to download a pdf by clicking on a link or a button. I have tried with $window.open(), but I can't manage to get the path to my pdf file.

     $scope.getPdf = function (id) {
                TextService.getPdf(id).success(function(data){
                      $window.open('../../../../../../' + data[0], '_blank', 'download');
                });

            };

Here i get an error saying that Cannot GET /data.pdf

EDIT - solved the problem

I had to do a POST method that sends the file:

    @RequestMapping(value = "/getPdf",
            method = RequestMethod.POST)
    @RolesAllowed(AuthoritiesConstants.USER)
    public ResponseEntity<byte[]> getPdf(@RequestBody Long id){
        String filename = textRepository.findOne(id).getTitle() + ".pdf";
        String text = textRepository.findOne(id).getUserText();
        ByteArrayOutputStream pdf  = new ByteArrayOutputStream();

       // create an API client instance
        Client client = new Client("", "");
        client.convertHtml(text, pdf);

        byte[] content = pdf.toByteArray();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/pdf"));
        headers.setContentDispositionFormData("inline", filename);
        headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
        ResponseEntity<byte[]> response = new ResponseEntity<>(content, headers, HttpStatus.OK);
        return response;

    }

and back to my AngularJS client i have a service that calls the Java method:

angular.module("eddieApp")
    .factory("TextService", function($http){
        return{
            getPdf: function(id){
                return $http.post('texts/getPdf', id, { responseType: 'arraybuffer' });
            }
        };
    });

Now in the controller all i had to do is call the service and open a window with the pdf:

$scope.getPdf = function (id) {
            TextService.getPdf(id).success(function(data){
                var file = new Blob([data], {type: 'application/pdf'});
                var fileURL = ($window.URL || $window.webkitURL).createObjectURL(file);
                $window.open(fileURL, '_blank', 'download');
            });

        };

Hope it helps someone!

Adel
  • 129
  • 1
  • 3
  • 12

2 Answers2

0

If you are serving the angular portion from a webserver, you cannot access the filesystem of the server. That would be a severe security problem.

Why not provide another @RequestMapping(value = "/getFile") which serves the file directly to the user, using the proper MIME type as well?

Here is a similar question Return generated pdf using spring MVC with an answer on how to do that.

Community
  • 1
  • 1
Joey
  • 1,349
  • 14
  • 26
0

i hope to help. I think the problem is in the window.open, first should exist a service that makes a post with the url, call the service will pass the id and now if you make the window.open

step
  • 186
  • 7