Spring Boot File Download Progress

Viewed 20

I have a small problem regarding a download controller I want to implement. I want to make files accessible through an url, therefore I am using a spring boot controller. Because there could be several data types, I use the Apache Tika lib to determine the correct media type. I am currently bound to use the JAX-RS Requests. To save the byte array to a File, I use guava.

@GET
@Path("/getMedia")
public Response downloadMedia(@QueryParam("company") final String company,
                              @QueryParam("username") final String username,
                              @QueryParam("password") final String password,
                              @QueryParam("messageId") final int messageId) throws IOException {
    ApplicationContext ctx = CyMega.getInstance().getContext(company);
        if (ctx == null) {
            return Response.status(Response.Status.UNAUTHORIZED).entity("Company not found").build();
        }
        ExternalAuthenticationService extService = ctx.getBean(ExternalAuthenticationService.class);

        ExternalAuthObj authObj = extService.validateLogin(company, username, password);
        if (authObj.getCode() != 0) {
            return Response.status(Response.Status.UNAUTHORIZED).entity(authObj)build();
    }

    ChatService chatService = ctx.getBean(ChatService.class);
    ChatGroupMessage message = chatService.getSingleChatGroupMessage(messageId);


    if (message != null) {
        Byte[] blobs = chatService.getBlob(messageId);
        byte[] blob = ArrayUtils.toPrimitive(blobs);
        File file = new File(message.getFilename());
        Files.write(blob, file);

        TikaConfig config = TikaConfig.getDefaultConfig();
        Detector detector = config.getDetector();
        Metadata metadata = new Metadata();
        ByteArrayInputStream inputStream = new ByteArrayInputStream(blob);
        TikaInputStream tikaInputStream = TikaInputStream.get(inputStream);
        metadata.add(TikaCoreProperties.RESOURCE_NAME_KEY, message.getFilename());
        org.apache.tika.mime.MediaType mediaType = detector.detect(tikaInputStream, metadata);
        return Response.status(Response.Status.OK)
                .header("Content-Length", String.valueOf(blob.length))
                .header(HttpHeaders.CONTENT_TYPE, mediaType)
                .entity(file).build();
    } else {
        return Response.status(Response.Status.NOT_FOUND).build();
    }
}

By using this code, the file successfully will be send to the client. The only problem is that I also want to track the progress of the download. I tried defining the Content-Length, but this causes my request to load way longer than necessary. Is there any way to achieve that? Should I use a ByteArrayStream as response entity? It would be awesome if someone could provide an example on how to do that properly.

Thanks in advance!

0 Answers
Related