Jersey 2 REST Client - Read Multipart Response / OctetStream Response - java

I'm building a Jersey 2 client, which calls a service to get a file from the server.
The service returns binary file content as application/octet-stream
NOw, this is my code where I call the webservice
Response response = target.request().header(HttpHeaders.COOKIE, this.cookie)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM)
.accept(MediaType.APPLICATION_OCTET_STREAM).get();
I get a HTTP 200 Response. But i don't understand how I can get the file content from the response.
EDIT
The service documentation says "To GET the binary file content and the metadata, use header Accept: multipiart/mixed"
So, I tried the below
Response response = target.request()
.header(HttpHeaders.COOKIE, this.cookie)
.header(HttpHeaders.CONTENT_TYPE, "multipart/mixed")
.accept("multipart/mixed").get();
Even here, I get a HTTP status 200 response. But How do I read the file content??
Please help!!

Take a look at the documentation you will see that response has a readEntity method that you can use to read the inputstream:
InputStream in = response.readEntity(InputStream.class);
... // Read from the stream
in.close();

Related

400 Bad request on Java Webclient multipart/formdata post request

Im having problems on posting a multipart/formdata request to a REST api. The request returns an 400 Bad Request response.
This is how the request should look like. The link shows you a screenshot captured on a successful request by the web interface.
Successful request
This is the Java code I created.
public void importModel(String projectId, String modelId, MultipartFile file, String fileName) throws IOException {
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("data", file.getBytes(), MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "form-data; name=data; filename=" + fileName);
MultiValueMap<String, HttpEntity<?>> parts = builder.build();
WebClient webClient = WebClient.builder()
.filters(exchangeFilterFunctions -> {
exchangeFilterFunctions.add(logRequest());
exchangeFilterFunctions.add(logResponse());
})
.build();
String request = webClient.post()
.uri(getBaseUriBuilder()
.pathSegment(getTeamSlug())
.path(API_PATH_PROJECTS)
.pathSegment(projectId)
.path(API_PATH_MODEL)
.pathSegment(modelId)
.path("/importasync")
.build())
.contentType(MediaType.MULTIPART_FORM_DATA)
.contentLength(file.getSize())
.header(HttpHeaders.AUTHORIZATION, getPrefixedAuthToken())
.body(BodyInserters.fromMultipartData(parts))
.exchange()
.flatMap(FlatService::apply)
.block();
return;
}
Any help is much appreciated. Thank in advance!
Have you tried to send the request with alternative Software like POSTMAN.
There you can check for the request properties that are being sent with the request
a 400 error can occur due to the following issues with your request
Wrong URL: Same as 404-Error a Bad Request is generated, when the user types in a wrong internet address or he adds special chars to the address.
Error full Cookies: If the Cookie inside your browser is to old or broken it can also be a 400.
Old outdated DNS-Entries: In your DNS-Cache could lie files that point to wrong or outdated IP- addresses
Too big files: when you try to upload very large files, the server can deny the request.
Too long header lines: the communication between the client and server is done with header information about the request. some servers set a limit to the header length.
Also if you can find out the more specific 400 error like this:
400.1: Invalid Destination Header
400.2: Invalid Depth Header
400.3: Invalid If Header
400.4: Invalid Overwrite Header
400.5: Invalid Translate Header
400.6: Invalid Request Body
400.7: Invalid Content
400.8: Invalid Timeout
400.9: Invalid Lock Token
If you are not the server admin you could ask him about specifications of the server. or use tools like postman where you can try to send requests to the server and find out more specific error codes.

Empty content-type while downloading file with Jersey client

I'm trying to download a file with the Jersey client.
I'm requesting an API, and I don't have API source code.
For one URL, the API returns an empty "Content-Type" header (the header is present but empty).
Jersey does not like this:
Unable to parse "Content-Type" header value: ""
I'd like to keep the Jersey client if possible
Is an API supposed to return an empty content-type?
Is there any header I can add to my request that may solve the problem? I tried content-type and accept without success.
You can set the Content-Type header manually after you receive the response.
Response res = target.request().get();
res.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/octect-stream");
InputStream file = res.readEntity(InputStream.class);

JAX-RS Jersey Read entity with Content-Type "*"

I am using Jax-RS to make a request to a server, which just returns a one word String, and read that response into a String variable. The issue is that I have no idea how to use the response, as its Content-Type is *; charset=UTF-8 (I verified this using Postman). Jax-RS has difficulty parsing this kind of header. Here is my code:
MultivaluedMap<String, String> formData = new MultivaluedHashMap<String, String>();
formData.add("username", username);
formData.add("target", "10");
Response response = target.request().accept(MediaType.APPLICATION_JSON_TYPE).post(Entity.form(formData));
String responseString = response.readEntity(String.class);
This POST request works. I get an actual Response that I can inspect. However, when I try to read this response into a String (last line of code), the following error is thrown:
org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "Content-Type" header value: "*; charset=UTF-8" ! at
org.glassfish.jersey.message.internal.InboundMessageContext.exception(InboundMessageContext.java:338) ! at
org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:333) ! at
org.glassfish.jersey.message.internal.InboundMessageContext.getMediaType(InboundMessageContext.java:446) ! at
org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:869)
How do I make Jax-RS properly read this kind of Content-Type?!?
I do not think there is any way to get Jersey / Jax-RS to properly read that kind of Content-Type. A solution for any kind of Response that has a Content-Type that Jax-RS does not like is to simply remove the header and (if needed) add your own Content-Type header that is more appropriate for the Response. Do this BEFORE trying to read the Response entity. This fixed my issue:
response.getHeaders().remove("Content-Type");
response.getHeaders().add("Content-Type", "text/plain");
String responseString = response.readEntity(String.class);

HTTP Status 406 – Not Acceptable in spring MVC Rest Service

Here is my code :
#RequestMapping(value = "/report/download", method = RequestMethod.GET,produces="application/vnd.ms-excel")
public Response getReportFile(#QueryParam("reportid") Long reportId)
{
System.out.println("Param"+reportId);
Long n=(long) 10;
String json=reportService.getReportFile(n);
File file = new File("D:\\Agent Information.xls");
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition","attachment; filename=Sample.xls");
return response.build();
}
i am getting the below Error in java console: Handler execution resulted in exception: Could not find acceptable representation
Your webservice is saying that the response type it is returning is not provided in the Accept HTTP header in your Client request.
So while making HTTP Request you have to add 'Accept Headers' . If it's JSON request then you will add 'Accept : application/json'. Similarly for your current example it will be
'Accept: text/plain'
'Accept-Charset: utf-8'
Find all accept headers here. And follow this steps to resolve
1) Find out the response (content type) returned by web service.
2) Provide this (content type) in your request Accept header.

file size increased during upload

I am uploading file using httpclient. After uploading file size get changed. During file upload some extra things get added in to file.
Before uploading file it contains:
hi this is vipin check
After uploading the file contains:
--j9q7PmvnWSP9wKHHp2w_KCI4Q2jCniJvPbrE0
Content-Disposition: form-data; name="vipin.txt"; filename="vipin.txt"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
hi this is vipin check
--j9q7PmvnWSP9wKHHp2w_KCI4Q2jCniJvPbrE0--
Why file size is changing?
Why does this extra contents get added?
My httpclient code is:
HttpPut httppost = new HttpPut(URIUtil.encodeQuery(newUrl));
httppost.setHeader("X-Auth-Token", cred.getAuthToken());
httppost.addHeader("User-Agent", "NetMagic-file-upload");
System.out.println("Dest : " + dest.getAbsolutePath());
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = (ContentBody) new FileBody(src);
mpEntity.addPart(dest.getName(), cbFile);
httppost.setEntity(mpEntity);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
You're doing a PUT request, yet your client uses multipart encoding as commonly uses in HTML form posts.
What appears to be happening is that the client is sending the file to be uploaded as multipart entity, but the server is treating it as an plain file. It is not entirely clear where the fault lies.
It is possible that the server is ignoring the content type in the request header. That would most likely be a bug in the servlet (or whatever) that is responsible for handing the upload request.
It is possible that the client is not setting a content type in the request header. I'd have expected that the client library would take care of that for you. But it is possible that you need to do it explicitly.
I'd advise looking at the request headers as they are sent by the client or received by the server to see if there is a proper multi-part content-type. That will help you determine where the problem is.
But there is an obvious solution. If the server cannot cope with multiparts, change the client side to not send them.

Categories