File is not getting download using JERSEY - java

I am using jersey API in my project. I stuck in a case that file needs to be downloaded but it's not. My code is as follow
#GET
#Produces("application/download")
public Response downloadFile(){
String data = getDatas();
ResponseBuilder response = Response.ok(data);
response.header("Content-Disposition","attachment;filename=UserData.txt");
response.header("charset", "UTF-8");
return Response.build();
}
I have added all the packages, paths are also fine. No Error came.
When I call this API, data comes in the response. I want this data to be in a file and in a downloadable format.
I also tried #Produces(MediaType.APPLICATION_OCTET_STREAM).
Please correct me if am doing wrong

I think you are not sending the response you have build.
first you're using a ResponseBuilder to build the resposne
ResponseBuilder response = Response.ok(data);
response.header("Content-Disposition","attachment;filename=UserData.txt");
response.header("charset", "UTF-8");
then you are returning the static Response.build() (notice the capital R) object, which is empty
you should return response.build()
also, you should produce octet-stream in your method annotions
#Produces(MediaType.APPLICATION_OCTET_STREAM)
and not
#Produces("application/download")
refer to this question: what's the correct way to send a file from REST web service to client?

Related

Wiremock encoding issue

I'm currently trying to use wiremock to mock the result of http calls in my unit tests, and when I try to get the response body, I got some encoding issues.
I write one methode to stub a post methode
public static void setupMockExecutionResponse(WireMockServer mockService) throws IOException {
mockService.stubFor(WireMock.post(WireMock.urlEqualTo("/reportExecutions"))
.willReturn(WireMock.aResponse()
.withStatus(HttpStatus.OK.value())
.withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE+"; charset=utf-8")
.withHeader("set-cookie", "JSESSIONID=1111111111111; SERVERID=jasper")
.withBody(
copyToString(
JasperClientMock.class.getClassLoader().getResourceAsStream("payload/execution-response.json"),
StandardCharsets.UTF_8))));
}
As you can see I specified that the charset of the response body is UTF-8, and in the header I add it too.
The json file used as the response is also encoded in UTF-8
{
"status":"ready",
"totalPages":1,
"requestId":"217f7dc9-47c4-4c44-bada-7e29b653887b",
"reportURI":"/test/test/test/test/export_test",
"exports":[
{
"status":"ready",
"outputResource":{
"contentType":"application/pdf",
"fileName":"export_test.pdf",
"outputFinal":true,
"outputTimestamp":0
},
"id":"6ca0038f-94ff-4bd9-bdf4-6a35259fd05e"
}
]
}
I expect when I make the post request to get the header specified in the setUp of the mock and the json string corresponding at my file.
feign.Response r = jasperFeignClient.executeReport(headerMap, requestBody);
checkResponseStatut(r.status(), EXECUTION_STEP, documentJasperRequest.getUrlReport(), requestBody);
getCookie(r, cookies);
String execResponse = IOUtils.toString(r.body().asInputStream(), String.valueOf(StandardCharsets.UTF_8));
I have the good return code (200), the cookies that I set, but my response body is messed up and look like this
So when I try to convert it to a java object I have parsing error, because it can't find the begining character of the json.
I even tryed to hard code the json string directly in the body of the stub, but that didn't change a things.
EDIT
When I make a direct call to the stubbed endpoint in my test, the encoding is good
#Test
public void testGetPDF(){
Response response = given().when().post("http://localhost:9561/reportExecutions");
String status = response.jsonPath().get("status");
System.out.println(status);
assertEquals(status, "ready");
}
It's only when I go into the class where the call is made that i got encoding issues.
It looks like your call via the Jasper client is by default setting accept-encodig:gzip (or something similar) and WireMock is therefore returning a gzipped body.
You should be able to resolve the issue by doing one of: a) disabling gzip in WireMock, b) disabling gzip in your client config, or c) ungzipping the body before attempting to parse it.
After updating all my pom dependencies to their latest version solved this encoding issue.

How to read body of HttpServletRequest multiple times?

Basically I need to read the body of HttpServletRequest multiple times, based on my research I found that one of easiest way for doing that is by using ContentCachingRequestWrapper
Here is how I implemented it:
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);
try{
MultipartRequest multipartRequest = new MultipartRequest(requestWrapper, ImageDirecoty, 1024*1024*5);
String test = requestWrapper.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
System.out.print(test);
} catch(IOException e){
System.out.println(e.getMessage());
return;
}
FYI: I am uploading a simple file from my client to server.
Now at first it reads the request body just fine, but in the second line which I have String test = requestWrapper to read it's content and to output it to console I don't get my Ecplise console outputing me anything and I don't get any error too, I'd really appreciate if somebody tell me what am i doing wrong.
actually the easy est way to do it is to use(convert the response), to some kind of Pojo class, and then saving it to whatever you want.
here is a link to convert it to pojo
http://www.jsonschema2pojo.org/
also you can use library's like Retrofit 2.0 to make your http calls much easier.
http://square.github.io/retrofit/

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.

How do I get Rest Assured to return the text (non-encrypted or streamed) value in my REST response?

I recently moved over to Java and am attempting to write some REST tests against the netflix REST service.
I'm having an issue in that my response using rest assured either wants to send a gzip encoded response or "InputStream", neither of which provide the actual XML text in the content of the response. I discovered the "Accept-Encoding" header yet making that blank doesn't seem to be the solution. With .Net I never had to mess with this and I can't seem to find the proper means of returning a human readable response.
My code:
RestAssured.baseURI = "http://api-public.netflix.com";
RestAssured.port = 80;
Response myResponse = given().header("Accept-Encoding", "").given().auth().oauth(consumerKey, consumerSecret, accessToken, secretToken).param("term", "star wars").get("/catalog/titles/autocomplete");
My response object has a "content" value with nothing but references to buffers, wrapped streams etc. Trying to get a ToString() of the response doesn't work. None of the examples I've seen seem to work in my case.
Any suggestions on what I'm doing wrong here?
This has worked for me:
given().config(RestAssured.config().decoderConfig(DecoderConfig.decoderConfig().noContentDecoders())).get(url)
I guess in Java land everything is returned as an input stream. Using a stream reader grabbed me the data I needed.
Until its version 1.9.0, Rest-assured has been providing by default in the requests the header "Accept-Encoding:gzip,deflate" with no way of changing it.
See
https://code.google.com/p/rest-assured/issues/detail?id=154
It works for me:
String responseJson = get("/languages/").asString();

Error while calling RESTful Web-Service using Jersey Client POST method

Getting an error while trying to consume a Restful web service using
POST method(with form param).
I want to consume a REST application using POST method.
Please find below the resource class I want to access.
#Path("/user")
public class User {
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response get(#FormParam("username") String userName,
#FormParam("userid") String userId ){
}
I tried using Jesry Client for accessing.Please find below the code i tried.
I tried adding values to FormParam as shown below.
Trail 1
WebResource webResource = client.resource("baseURL/user");
String input = "userid:1001,username:demo1";
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, input);
I am getting a an error response back "The server encountered an internal error () that prevented it from fulfilling this request".
I think I am not adding the values to FormParam properly.
Trial 2
I also tried adding the form params using the below code
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("userid", "1001");
formData.add("username", "demo1");
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);
This also resulted in the same error.
Trial 3
Form f = new Form();
f.add("userid", "1001D");
f.add("username", "1001D");
ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).post(ClientResponse.class, f);
This also resulted in the same error.
Any help is appreciated.
Since your error indicates "Server encountered an internal error" you need to look at the server (logs) to see what went wrong. Certainly your 3rd client looks fine to reach the service you defined (assuming you are using something real instead of the string "baseURL").
You can easily test your server is working separately from your client by creating a HTML page to reach the service. Create a HTML form using enctype="application/x-www-form-urlencoded" and posting to your service endpoint (what you are calling "baseURL/user") with form parameters userid and username. When you view the HTML form in a browser and hit the submit button, it will call your server - if you get the same error you can be sure it is nothing to do with your client code.
Hope http://yogeshmprajapati.blogspot.in/2011/12/login-to-fb-from-java.html will help you.

Categories