Unable to download file from swagger - java

#ApiResponses(value = {
#ApiResponse(code = 200, message = "Perfect") })
public void getLabel(#QueryParam("orderItemsId") String orderItemsId,HttpServletRequest httpServletRequest,HttpServletResponse response) {
String dataDirectory = httpServletRequest.getSession().getServletContext().getRealPath("/WEB-INF/files/label.pdf");
Path file = Paths.get(dataDirectory);
if (Files.exists(file))
{
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "attachment; filename=\"label.pdf\"");
try
{
Files.copy(file, response.getOutputStream());
response.getOutputStream().flush();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
I am using springfox-swagger2 - version 2.5.0 with springfox-swagger-ui - version 2.5.0.
without content-Disposition header swagger is unable to sync output file in swagger-ui, it shows data in binary form(i guess)kind-of corrupted and whereas with this header i get a link in ResponseBody which also downloads pdf but corrupted form same as it syncs in swagger-ui.
I have done a research it shows we need to provide datatype:"file" in response link . but #ApiResponse doesn't contain any datatype field. Though it has field with response but i am not sure what class to give for
octet-stream output. I have tried OutputStream but it doesn't work.
Edit : Swagger UI does not support the downloading of file. whereas same url if called through other source will do the job.

Swagger UI does not support the downloading of file. whereas same url if called through other source will do the job.

Related

Java - Sending file over HTTP Server

I made a HTML server using com.sun.net.httpserver library. I want to send a jar file to the client to make them download it.
This method below actually make the client download the file:
#Override
public void handle(HttpExchange httpExchange) {
File file = new File("Test.jar");
try {
httpExchange.sendResponseHeaders(200, file.length());
OutputStream outputStream = httpExchange.getResponseBody();
Files.copy(file.toPath(), outputStream);
outputStream.close();
} catch (IOException exception) {
exception.printStackTrace();
}
}
but it sends the jar file as a zip. How do I get it to send it as a jar file instead? And is there a better way to send files?
Please try adding the following to get correct filename for the download:
httpExchange.getResponseHeaders().add("Content-Disposition", "attachment; filename=Test.jar");
You might also want do add the following to get the corrent content-type:
httpExchange.setAttribute(HTTPExchange.HeaderFields.Content_Type.toString(), "application/java-archive");
Please see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a listing of content-types for different suffixes.

Download or pull a file from azure git repo using rest api

My requirement is to Download / pull a file from azure git repo And convert it to a byte Array. I searched in Azure git repo API but I couldn't found the rest api call. Please help to get the solution.
I tried with the below url but it's returning unicode value in content object.
GET https://dev.azure.com{organization}/{project}/_apis/git/repositories/{repositoryId}/items?path={path}&versionDescriptor.version={versionDescriptor.version}&versionDescriptor.versionType={versionDescriptor.versionType}&includeContent=true&api-version=6.0
are you saying you want to use a get request from Microsoft azure? I would maybe recommend using fetch to retrieve your data. something along the lines of:
fetch("https://westus.api.cognitive.microsoft.com/face/v1.0/detect? returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=emotion&recognitionModel=
recognition_01&returnRecognitionModel=false&detectionModel=detection_01"
, {
method: 'post',
headers: {
'Content-Type': 'application/octet-stream',
'Ocp-Apim-Subscription-Key': '<subscription key>'
},
body: makeblob(contents)
}).then((response) => response.json()).then(success => {
that.setState({selectedFile: url1});
that.setState({facesArray: success});
console.log("facesArray is", that.state.facesArray);
console.log("new selected state is", that.state.selectedFile);
// console.log(success);
}).catch(error =>
console.log("did not work ",error))
I understand i'm using a post request, but if you change the subscription key, body, fetch url, and content type, you might be able to get what your are looking for. Also, you can somehow contact microsoft azure services for more help on their api.
Have you tried this? Make sure you add httpclient to your gradle/madle build. Replace azurePathString with your URL.
public byte[] executeBinary(URI uri) throws IOException, ClientProtocolException {
HttpGet httpget = new HttpGet(azurePathString);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
entity.writeTo(baos);
return baos.toByteArray();
}
You could use API: https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/items?path={path}&versionDescriptor.version={versionDescriptor.version}&download=true&api-version=6.0 to download the target file, and then read this file and convert its content to a byte Array. See: Items - Get for more details.

How can I download a file which I have dynamically created on Apache TomCat Server?

I created an ".xlsx" file (CustomerData.xlsx) by using "Apache POI".
The problem is that the file is created on my TomCat Server and I have to download it.
I tried the following code, in order to download the file:
HttpServletResponse response = null;
response.setContentType("xlsx");
response.setHeader(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"attachment; filename=C:\CustomerData.xlsx");
try {
workbook.write(response.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but unfortunately, it does not seem to work.
In case you have any idea or suggestion, do not hesitate posting it.
You mix content type and attachment information into a single header which cannot work.
Instead write
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment;filename=CustomerData.xlsx");

Jersey servlet returns zip file that contains more bytes than response sent

I'm trying to implement a simple servlet that returns a zip file that is bundled inside the application (simple resource)
So I've implemented the following method in the server side:
#GET
#Path("{path}/{zipfile}")
#Produces("application/zip")
public Response getZipFile(
#PathParam("path") String pathFolder,
#PathParam("zipfile") String zipFile) IOException {
String fullPath= String.format("/WEB-INF/repository/%s/%s",
pathFolder, zipFile);
String realPath = ServletContextHolder.INSTANCE.getServletContext()
.getRealPath(fullPath);
File file = new File(realPath );
ResponseBuilder response = Response.ok((Object) file);
return response.build();
}
When I call this method from the borwser, the zip file is downloaded and its size is the same number of bytes as the original zip in the server.
However, when I call this using a simple XMLHttpRequest from my client side code:
var oXHR = new XMLHttpRequest();
var sUrl = "http://localhost:8080/path/file.zip"
oXHR.open('GET', sUrl);
oXHR.responseType = 'application/zip';
oXHR.send();
I can see in the Network tab of the Developer tools in chrome that the content size is bigger, and I'm unable to process this zip file (for instance JSzip doesn't recognize it).
It seems like somewhere between my response and the final response from org.glassfish.jersey.servlet.ServletContainer, some extra bytes are written/ some encoding is done on the file.
Can you please assist?
Best Regards,
Maxim
When you use an ajax request, the browser expects text (by default) and will try to decode it from UTF-8 (corrupting your data).
Try with oXHR.responseType = "arraybuffer"; : that way, the browser won't change the data and give you the raw content (which will be in oXHR.response).
This solution won't work in IE 6-9 : if you need to support it, check JSZip documentation : http://stuk.github.io/jszip/documentation/howto/read_zip.html
If it's not the right solution, try downloading directly the zip file (without any js code involved) to check if the issue comes from the js side or from the java side.

Download a file through Spring MVC controller using streams

I am using spring MVC with REST service for one of my project. I am having a service to attach and download user files.
I am using below service API for upload and save file into server directory
http://myrestserver/attachmentService/attach/userKey
And below service API for download files from server directory
http://myrestserver/attachmentService/download/userKey/fileKey
The issue is that when a file is downloaded, the downloaded URL shows the REST service API URL. To avoid this, I thought of write a controller for attach and download file.
I wrote a spring controller which handle file attachment process. Even I wrote a controller(say download.do) for download a file, but when a file downloaded, the file name shows as the same name of the controller(downloaded file name shows "download.do" always) instead of original file name.
Below code is from my download.do controller
WebResource resource = null;
resource = client.resource("http://myrestserver/attachmentService/download/userKey/fileKey");
clientResponse = resource.accept(MediaType.APPLICATION_OCTET_STREAM).get(
ClientResponse.class);
InputStream inputStream = clientResponse.getEntityInputStream();
if(inputStream != null){
byteArrayOutputStream = new ByteArrayOutputStream();
try {
IOUtil.copyStream(inputStream, byteArrayOutputStream);
} catch (IOException e) {
log.error("Exception in download:"+ e);
}
}
And, in my service API, the code is
file = new File(directory, attachmentFileName);
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(attachmentContent);
fileOutputStream.close();
response = Response.ok((Object) file).type(MediaType.APPLICATION_OCTET_STREAM);
response.header("Content-Disposition", "attachment; filename=" + "\"" + attachmentFileName
+ "\"");
return response.build();
By analyzing the issue, I understood that, am not setting file header in downloaded file through download.do controller.
If I am using outstream in download.do controller, I will not be able to set the file header.
Can any one help me to resolve this issue. My primary aim is to hide my rest service URL from downloaded file by stream through a MVC controller.
I found a post (Downloading a file from spring controllers )in stack overflow almost like my question, but the file type is previously known. Please note that, in my application user can attach any type of file.
You have to set the Content-Disposition prior to writing the file to the output stream. Once you start writing to the output stream, you cannot set headers any longer.

Categories