I am trying to download a file from a REST service using JAX-RS.
This is my code which invokes the download by sending a GET request:
private Response invokeDownload(String authToken, String url) {
// Creates the HTTP client object and makes the HTTP request to the specified URL
Client client = ClientBuilder.newClient();
WebTarget target = client.target(url);
// Sets the header and makes a GET request
return target.request().header("X-Tableau-Auth", authToken).get();
}
However I am facing problems converting the Response into an actual File object. So what I did is the following:
public File downloadWorkbook(String authToken, String siteId, String workbookId, String savePath)
throws IOException {
String url = Operation.DOWNLOAD_WORKBOOK.getUrl(siteId, workbookId);
Response response = invokeDownload(authToken, url);
String output = response.readEntity(String.class);
String filename;
// some code to retrieve the filename from the headers
Path path = Files.write(Paths.get(savePath + "/" + filename), output.getBytes());
File file = path.toFile();
return file;
}
The file which is created is not valid, I debugged the code and noticed that output contains a String like that (much larger):
PK ͢�F���� �[ Superstore.twb�ysI�7����ߡ���d�m3��f���
Looks like binary. Obviously there is something wrong with the code.
How do I get the HTTP response body as a string from the Response object?
Edit:
Quote from the REST API reference about the HTTP response:
Response Body
One of the following, depending on the format of the workbook:
The workbook's content in .twb format (Content-Type: application/xml)
The workbook's content in .twbx format (Content-Type: application/octet-stream)
As you noticed yourself, you're dealing with binary data here. So you shouldn't create a String from your response. Better get the input stream and pipe it to your file.
Response response = invokeDownload(authToken, url);
InputStream in = response.readEntity(InputStream.class);
Path path = Paths.get(savePath, filename);
Files.copy(in, path);
1) I assume by this point you're clear on the difference between "binary file" and "text file". And that you can only capture the latter into a "string".
2) Sebastian gave you excellent advice for capturing a binary file (+1, Sebastian!). VERY IMPORTANT: you should always set the MIME type (Content-Type: xxx/yyy)in cases like this. Here is another link that might be useful.
3) Finally, there are cases where you might WANT to treat "binary" data as text. This is how e-mail attachments work with SMTP (a text protocol). In these cases, you want to use Base64 Encoding. For example: JAX-RS | Download PDF from Base64 encoded data
Related
My API returns an Excel (xslx) File for a GET Request. If a "Accept" Header is present, the binary result gets encoded/corrupt. I can send the request using fiddler with the minimum Headers required and everything works just fine. If i add an Accept Header like a browser does:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
The result gets larger (8kb instead of 4kb) and seems to be encoded in some way. Fiddler detects this encoding and asks to decode it. After decoding so, the result is valid again. When i use chrome browser instead, it downloads the larger (8kb) file, not decoded and therefor corrupt.
#GET
#Path("/export-report")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
//#Produces({ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })
public Response exportReport() throws IOException {
byte[] fileBytes = getFileBytes();
String filename = "report.xslx";
String mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
return Response.ok()
.header("Content-Disposition", "attachment; filename=\"" + filename + "\"")
.header("Content-Length", fileBytes.length)
.entity(fileBytes)
.header("Content-Type", mimeType)
.build();
}
I tried returning a File, a InputStream and a byte Array, it didn't change a thing.
I also had a look at
Input and Output binary streams using JERSEY?
I have no soltuion, any idea?
I am trying to download a PDF file from a response of Java REST call after custom authentication check.
I can see downloaded file but it is empty file.
Below is my code snippet.
//Custom HTTPClient
HTTPAuthClient client = new HTTPAuthClient(url,username,password)
Request request = new Request(downloadURL); //I'm downloading file content of an URL.
Response response = client.executeGet(request);
String response1 = response.getResponseBody();
InputStream is = new ByteArrayInputStream(response.getBytes());
response.setContentType("Content-type",application/pdf); //here response is //javax.servlet.HttpServletResponse
response.setHeader("Content-Disposition","attachment;filename="myfile.pdf");
IOUtils.copy(is,response.getOutPutStream());
response.flushBuffer();
With this code I could download the file but when I open the file and verified there is no data.
As part of response body also I can see some data.
Could you please help me out where I'm doing mistake I tried many options but did not find solution.
How can you use setContentType like this
response.setContentType("Content-type",application/pdf);
If only one avalible param in this method is String void setContentType(String type) so your method should be:
response.setContentType("application/pdf");
Java Doc to be sure.
I am working on java application for getting attachments from salesforce.
I have to show the salesforce attachments in my java application for particular object like Leads,Contacts etc. For that i am using Rest Api and got response body. But in response body there is url but i want binary data of attachment body.
I get response in body in following format:
{
Body = "/services/data/v23.0/sobjects/Attachment/00P90000004SRFlEAO/Body";
ContentType = "application/video";
Name = "Video.MOV";
attributes = {
type = Attachment;
url = "/services/data/v23.0/sobjects/Attachment/00P90000004SRFlEAO";
};
}
You get the actual attachment by performing a GET request to the Url returned in the Body field.
To get HTTP links with direct link to file (with NAME and EXTENSION)
like http://website.com/file.avi could be done with
URL FileLocation = new URL("string");
String Name = FileLocation.getFile();
which would return NAME with EXTENSION (/filename.ext)
but How to get Filename for URLs with php ID like
http:///website.com/download.php?d=9594
I want to do this in JAVA only.
You want to look for Content-Disposition field in the header of HTTP response, e.g.
Content-Disposition: attachment; filename="fname.ext"
Since it is in the HTTP header, you will need to start downloading the message first before getting the file name. Here is an example of how you use URLConnection and how to get a header field
File file=new File("C:/work/chandan/deepak.txt");
URL url=null;
....
....
url=file.toURL(); //file:/C:/work/chandan/deepak.txt
System.out.println("The url is" + url);
How do you make a HTTP GET request in Mule, and then stream the response to a file? My application stores the entire response in memory, but the response can be large, so this needs to be fixed. I want to save the response to a temporary file, and then stream the file contents back to the client.
Right now, I'm doing:
String restUrl = "http://www.url.com";
UMOEventContext context = RequestContext.getEventContext();
GetMethod method = new GetMethod(restUrl);
UMOMessage muleMessage = new MuleMessage(method);
muleMessage.setProperty(RestServiceWrapper.REST_SERVICE_URL, restUrl);
UMOMessage result = context.sendEvent(muleMessage, new MuleEndpointURI("vm://identifier")); //OutOfMemoryException
String body = result.getPayloadAsString();
I'm using Mule 1.3.3 and cannot upgrade. Thank you.