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!