Get the zip file through a RESTful web service with the help of AngularJS

Utilizing REST jersey on the server side combined with AngularJS on the client side.

My task involves downloading a zip file requested by the client for a specific date range.

Server-side code: //Currently, I have hardcoded a single zip file for testing purposes

@POST
    @Path("/LogRange")
    @Produces({MediaType.APPLICATION_OCTET_STREAM} )
    @Consumes({ MediaType.APPLICATION_JSON} )
    public Response getLogsBetween(@HeaderParam(HttpHeaders.AUTHORIZATION) String authorization, 
            @Context HttpServletRequest request, @Context HttpServletResponse response, LogFolders folders){

        StreamingOutput stream = new StreamingOutput(){
            @Override
                public void write(OutputStream arg0) {
                    // TODO Auto-generated method stub
                    BufferedOutputStream bus = new BufferedOutputStream(arg0);
                    try {
                        File file = new File("C:\\ProgramData\\ABC\\Logfiles\\UI.zip");
                        FileInputStream fizip = new FileInputStream(file);
                        byte[] buffer2 = IOUtils.toByteArray(fizip);
                        bus.write(buffer2);
                        bus.flush();
                        bus.close();

                    } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    }
                }
            };
            return Response.status(Response.Status.OK).entity(stream).header("Content-Disposition","attachment; filename=\"log.zip\"").build();
}       

Client-side code:

$http({
    url : urlBase + endPoint,
    method: "POST",
    data: formData, //this is your json data string
    headers : {
        'Content-Type' : "application/json",
        'Authorization' : authCode,
    },
    responseType: 'arraybuffer'
}).success(function(response, status, headers, config) {

    var blob = new Blob([response], { type: "application/zip" });
    var objectUrl = URL.createObjectURL(blob);
    window.open(objectUrl);

    }).error(function (data, status, headers, config) {
    //upload failed
});

The downloaded file is appearing corrupted and displaying incorrectly when opened locally. If you have any advice on how to properly download the file, please provide your assistance. https://i.sstatic.net/FSpsO.png

Answer №1

If you're looking to download any type of file, the code below might be helpful. Just make sure to change the contentType as needed.

$scope.downloadFile = function(){
            $http({

                method : 'GET',
                url : $scope.BASEURL + 'file-download?fileType='+$scope.selectedFile,
                responseType: 'arraybuffer',
                headers : {
                    'Content-Type' : 'application/json'
                }

            }).success(function(data, status, headers, config) {
                // TODO when WS success
                var file = new Blob([ data ], {
                    type : 'application/json'
                });
                //trick to download store a file having its URL
                var fileURL = URL.createObjectURL(file);
                var a         = document.createElement('a');
                a.href        = fileURL; 
                a.target      = '_blank';
                a.download    = $scope.selectedFile+'.json';
                document.body.appendChild(a);
                a.click();

            }).error(function(data, status, headers, config) {

            });
        }

url : $scope.BASEURL + 'file-download?fileType='+$scope.selectedFile

Make sure to replace the URL with your webservice URL.

When using this service, make sure to return the file as byte[] and adjust the contentType as needed.

@RequestMapping(value = "/file-download", method = RequestMethod.GET, produces = "application/json")
public  @ResponseBody HttpEntity<byte[]> download(@RequestParam("fileType") String fileType, HttpServletRequest request, HttpServletResponse response){
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);

    HttpHeaders header = null;
    byte[] document = null;

    try {
        JsonEditorBo jeBo = new JsonEditorBo();

        String uploadsDir = "/download/";
        String realPathtoUploads = request.getSession().getServletContext().getRealPath(uploadsDir);

        if (!new File(realPathtoUploads).exists()) {
            new File(realPathtoUploads).mkdir();
        }

        String downloadPath = jeBo.dowloadedFilePath(realPathtoUploads, fileType);
        File file = new File(downloadPath);
        document = FileCopyUtils.copyToByteArray(file);
        header = new HttpHeaders();
        header.setContentType(new MediaType("application", "json"));
        header.set("Content-Disposition", "inline; filename=" + file.getName());
        header.setContentLength(document.length);

        response.setStatus(HttpServletResponse.SC_OK);

    } catch (Exception e) {
        e.printStackTrace();
    }

    return new HttpEntity<byte[]>(document, header);
}

CHANGES NEEDED: Please replace the code below and test if it works correctly.

java.nio.file.Path path = Paths.get("C:\\ProgramData\\ABC\\Logfiles\\UI.zip");\
byte[] data = Files.readAllBytes(path);
                    output.write(data);
                    output.flush();

Answer №2

Coding in Different Languages

    <html ng-app="ReviwerApp">

    <div   ng-controller="downloadCtrl">

    <button ng-click="downloadzippedPdfs()" class="btn btn-danger">Download</button>

   </div>

   </html>

Using JavaScript

'use strict';

angular.module('downloads', []);

 //Setting up Routers
 myApp.config(function($stateProvider) {




 $stateProvider.state('downloads', {
 url: '/downloads',
 templateUrl: 'partials/downloads/downloads.html',
 data:{
    auth:true
 }
 });

 });


 //Working with Factories
 myApp.factory('downloadServices', ['$http', function($http) {

 var factoryDefinitions = {
  getdownloadcontent: function() {



        return  $http.get('/smartcompare/rest/download/zip/2017-06-30', {
            headers: {'Authorization': 'Basic xyz12345'},
          responseType: 'arraybuffer' 
       }).then(function(response) { return response;  });
  },
}

return factoryDefinitions;
}
 ]);







 //Implementation in Controllers
myApp.controller('downloadCtrl', ['$scope', 'downloadServices' , 
 function($scope, downloadServices ) {

 var fileName = "comressedpdfreports.zip";
    var a = document.createElement("a");
    document.body.appendChild(a);

downloadServices.getdownloadcontent().then(function(response){
    $scope.downloadzippedPdfs =    function () {




            var file = new Blob([response.data], {type: 'application/zip'});
            var fileURL = URL.createObjectURL(file);
            a.href = fileURL;
            a.download = fileName;
            a.click();

    };

   });
   }]);

Utilizing Java

 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.StreamingOutput;
 import sun.misc.BASE64Decoder;

 @Path("/download")

 public class FileDownloadService {



    @Path("/zip/{date}")

    @GET
    public Response downloadzipFile( @HeaderParam("authorization") String authString, @PathParam("date") String date)
    { 
      {
     StreamingOutput fileStream =  new StreamingOutput() 
        {
            @Override
            public void write(java.io.OutputStream output) throws IOException, WebApplicationException 
            {
                try
                {

                    java.nio.file.Path path = Paths.get( "DailyReports"+File.separator+date+".zip");
                    byte[] data = Files.readAllBytes(path);
                    output.write(data);
                    output.flush();
                } 
                catch (Exception e) 
                {
                    throw new WebApplicationException("File Not Found !!");
                }
            }
        };
        return Response
                .ok(fileStream, MediaType.APPLICATION_OCTET_STREAM)
                .header("content-disposition","attachment; filename = "+date+".zip")
                .build();


    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adding a lag time between the entrance and exit animations of a ViewAnimator in Android

    I want to add some animation effects to my view transaction with a ViewAnimator. The challenge is to make my view slide out and in from the SAME direction. While I need the in and out animation to occur simultaneously, how can I insert a delay bet ...

Troubleshooting issues with the Select List component in ReactJS

Having an issue with the select list as the onChange event is not triggering. Struggling to set the selected value from the list in the this.state variable. Any assistance on this matter would be greatly appreciated. class SelectActivity extends React.C ...

Experiencing difficulty moving information from React form to DATA.txt file through Express

I've tried various things, but I keep encountering the same error. Changing the file path didn't seem to make a difference. The current structure of my project is as follows: {nodemodules,public,scr (containing all files including App.jsx),DATA. ...

Creating a javascript variable in c#

Currently, I am working on incorporating the selected index text from a DropDownList into a JavaScript string. My approach involves storing the text in a hidden field and retrieving it through C# to ensure the JavaScript variable retains its value even aft ...

employing async/await in the function of a backend API

I'm facing an issue with the following code snippet: service.js module.exports = { getUser }; async function getUser({ data }) { return new Promise((resolve, reject) => { const id = data["id"]; const doc = await db.colle ...

Managing the size of personalized shapes in Three.js

I need help with a custom object that represents a frame created by subtracting two meshes. generateFrame (width, height, depth) { const frameMesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1)); frameMesh.scale.set(width, height, depth); c ...

Delete specific rows by clicking a button in AngularJS

I have a table with checkboxes for each row and I am trying remove the selected rows when a button is clicked. The selected row indexes are stored in an array using ng-change, but I cannot figure out how to delete them all at once with a single button clic ...

This TypeScript error occurs when the props are not compatible and cannot be assigned to

Hello fellow Internet dwellers! I am a novice in the world of coding and TypeScript, seeking some assistance here. I am attempting to extract an array of objects from props, transform it into a new object with specific information, and then return it - ho ...

Is there a way for my component to function seamlessly within another component without the need for redundant code?

Is there a way to avoid repeating code when using my component inside another component? For example, in the file NextPage.js, the <LogoutButton/> component does not perform its function. How can I ensure that the <LogoutButton/> behaves the s ...

Explore VsCode's capability to create projects using the Maven Archetype command without relying on Maven

After setting up Maven 3.6.3 on my Windows 10 machine and installing the Maven for Java extension in VSCode, I ran mvn -version to confirm the installation. However, when attempting to create a Maven project by right-clicking in an empty folder in VSCode, ...

What is the best way to customize the appearance of an XML snippet using Greasemonkey?

I am attempting to customize an XML fragment retrieved from a server response using a Greasemonkey script. Take a look at this sample XML fragment from w3schools.com: <note> <to> Tove</to> <from>Jani</from> <heading ...

What causes the oninput event to act differently in Angular as opposed to regular JavaScript?

As I delve into learning Angular with TypeScript, I've encountered some inconsistencies compared to JavaScript that are puzzling me. Take for example this function that works flawlessly with pure JavaScript, where it dynamically sets the min and max a ...

What makes this effective in JavaScript?

While working on a project, I encountered the task of comparing coordinates in two arrays at the same index to see if they are identical. There are various methods to achieve this, but one particular approach piqued my interest. Why does it yield the expec ...

Optimal application of transactions in JMS and EJB

I am curious about the correct way to utilize JMS transactions within an EJB container. I came across this code snippet that demonstrates sending messages using JMS in a stateless bean: @Stateless public class SendEventsBean { private static final Logg ...

Automatically fill in a text box with previously saved information

Does anyone have suggestions on how to create this type of textbox or what it is called? (View original image here) ...

Want to automatically redirect the home page? Here's how!

I am trying to automatically redirect the home page after clicking the update button. Below is the code for my handleSubmit function: const handleSubmit = (e) => { e.preventDefault(); // retrieving data from the backend axios .put(`${ ...

Show errors related to parsley within a bootstrap tooltip

I am currently working with Parsley 2.0.0-rc5 and I would like to display the error messages using a Bootstrap tooltip. The issue I am facing is that the "parsley:field:error" event fires before the error message is displayed in the error container, maki ...

javascript Arabic speech synthesis

Attempting to utilize SpeechSynthesisUtterance for Arabic language Successfully functioning with English content $(document).ready(function() { var u1 = new SpeechSynthesisUtterance('Hello world!'); u1.lang = 'en-US'; u1.pitch ...

Error in mandatory data required by the Screenleap API in JavaScript

I have a JSON encoded data stored in a variable called $json. Here is how it appears: I have referred to the documentation at "https://www.screenleap.com/api/presenter" ...

Is there a comparison you can make between v-for and a similar feature in Stencil? (such as a functionality akin to v-for

When working with arrays in Stencil, I need to repeat a specific element multiple times based on the array. In Vue, I typically use v-for for this purpose, but what is the equivalent in Stencil? ...