I'm using Rest template to make a request to a service. But I'm getting response code 400 and response null. I made the same call by postman, with the same parameters and I'm getting the body response. How do I get the body response?
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add("Authorization", "Bearer " + token);
headers.add("kms_credencial", parametros.get("KMS_CREDENCIAL"));
headers.add("kms_credencial_tipo", parametros.get("KMS_CREDENCIAL_TIPO"));
HttpEntity<MultiValueMap<String,Object>> entity =
new HttpEntity<MultiValueMap<String, Object>>(request, headers);
ResponseEntity<String> response = null;
response = restTemplate.exchange(parametros.get("SERVICE_HUB2_BASE_URL") + "/fw/v1/pdf/kms/lote/assinaturas",
HttpMethod.POST, entity, String.class);
Could someone tell me what's wrong?
I had the same problem.
From what I've seen, ResteTemplate doesn't accept an error response (400, 500) with a 'large' body.
I still haven't found a solution, but I'm studying the parameters that the method accepts to see if any of them allows receiving a larger body
I have an API end-point that I need to post to.
Using Postman I do the following:
Set the method to be POST
Add the URL
In the Headers I set: Content-Type to be application/json
In the Body I add my json string
I hit [Send] and get a 200 response with the expected response.
However, in C# .Net Framework 4.8 (LinqPad 5) I do
var c = new HttpClient(); // Disposed of later
c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string data = #"{ ""a"": ""b"", ""c"": ""d"" }"; // copied from Postman.
HttpContent payload = new StringContent(data, Encoding.UTF8, "application/json");
var msg = new HttpRequestMessage(HttpMethod.Post, new Uri("https://the.url"), UriKind.Absolute)
{
Content = payload,
};
var response = c.SendAsync(msg).GetAwaiter().GetResult(); // It's a synchronous flow
And this responds with a 502 Bad Gateway.
What am I missing...?
I should point out that I need to use the HttpClient and not RestSharp.
I am calling an external server using HttpRequestExecutingMessageHandler. I am using a JSON to object transformer to convert the JSON data. But I am getting the following exception.
Caused by: com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
at [Source: (String)"�
when I checked the headers I found the following.
Transfer-Encoding=chunked
Is this the reason for the exception log?
The outbound gateway and JsonToObjectTransformer are given below:
#ServiceActivator(inputChannel = "channelOutboundRequest")
#Bean
public HttpRequestExecutingMessageHandler outboundGateway() {
final HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(
endpoint);
handler.setExpectedResponseType(String.class);
handler.setHttpMethod(HttpMethod.POST);
handler.setOutputChannelName("channelResponse");
handler.setAdviceChain(Collections.singletonList(advice()));
return handler;
}
#Bean
#Transformer(inputChannel = "channelResponse", outputChannel = "channelReply")
public JsonToObjectTransformer transformer(ObjectMapper objectMapper) {
final JsonObjectMapper<?, ?> mapper = new Jackson2JsonObjectMapper(objectMapper);
return new JsonToObjectTransformer(DetailsDTO.class, mapper);
}
If the header is causing the issue, how can I handle the response?
Note: If I hit the external server directly using postman, I am getting the response in JSON structure.
I have no idea what's wrong here.. If I use the simple restemplate call like below, it works properly.
JSONObject jsonObject = new JSONObject("{\"code\":\"F001\",\"transactionId\":\"1008566223232\"}");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth("token");
HttpEntity<String> request =
new HttpEntity<String>(jsonObject.toString(), headers);
String respns = restTemplt.postForObject("http://endpoint", request, String.class);
System.out.println(respns);
JSONObject response = new JSONObject(respns);
One difference I could find was in the response headers. those are given below:
Outbound gateway response headers :-
{Transfer-Encoding=chunked, http_requestMethod=GET, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel#d8b195e, Server=nginx, Accept=/, Connection=keep-alive, User-Agent=PostmanRuntime/7.28.0, Host=localhost:8901, Accept-Encoding=gzip, deflate, br, http_statusCode=200 OK, Date=1622533072000, Authorization=Bearer token, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel#d8b195e, Cache-Control=no-cache, ETag=W/"1009-5SzdL+uWyY6ZcMWht5dMtm2Sxlc", Content-Encoding=gzip, http_requestUrl=http://inboundurl, id=be07fc8d-d478-5fa9-33e4-61a2b5f92468, Content-Length=207, contentType=application/json;charset=utf-8, Content-Type=application/json, requestFrom=CUSTOM_HEADER, timestamp=1622533092827}
Normal restTemplate call response header
[Server:"nginx", Date:"Tue, 01 Jun 2021 07:34:54 GMT", Content-Type:"application/json; charset=utf-8", Content-Length:"4105", Connection:"keep-alive", Access-Control-Allow-Origin:"*", Content-Security-Policy:"default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests", X-DNS-Prefetch-Control:"off", Expect-CT:"max-age=0", X-Frame-Options:"SAMEORIGIN", Strict-Transport-Security:"max-age=15552000; includeSubDomains", X-Download-Options:"noopen", X-Content-Type-Options:"nosniff", X-Permitted-Cross-Domain-Policies:"none", Referrer-Policy:"no-referrer", X-XSS-Protection:"0", ETag:"W/"1009-llD9DqxYkEsjyikWajYk+16cb1k""]
Can anyone please help?
After many trials and errors, I found the reason for this. Accept-Encoding=gzip, deflate, br this header in the outbound gateway request is the root cause. the response I am getting is a long string and it is getting compressed because of this header. i added a header filter before the outbound gateway to remove this header.
#Bean
#Transformer(inputChannel = "channelHeaderFilterReq", outputChannel = "channelHeaderFilterRes")
public HeaderFilter filter() {
return new HeaderFilter("Accept-Encoding");
}
Now everything works fine..!!
When i use okhttp3 ver 4.7.2 to create a json request with third api, I will receive response 204. But when I use asyncHttpClient to create the same json request, I will receive correct data.
This is my code using okhttp3:
MediaType JSON = MediaType.get("application/json");
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
OkHttpClient client = new OkHttpClient().newBuilder().addInterceptor(interceptor).build();
RequestBody body = RequestBody.create("{}", JSON);
Request request = new Request.Builder()
.url(URL).post(body).build();
System.out.println("Start");
okhttp3.Response response = client.newCall(request).execute();
System.out.println(response.body().string()); // null
System.out.println(response.code()); // 204
This is my code using asyncHttpClient:
ListenableFuture<org.asynchttpclient.Response> whenResponse = client
.preparePost(URL)
.addHeader("Content-Type", "application/json").setBody("{}").execute();
org.asynchttpclient.Response response = whenResponse.get();
System.out.println(response.getResponseBody()); // Correct response body
System.out.println(response.getStatusCode()); // 200
Request json send by okhttp have conten-type is application/json; charset=utf-8, third api allow only application/json. So their response 204.
I am new to both Spring boot and rest calls.
I am trying to consume a rest service and I do not have any information about that rest API except URL. When I hit that URL from a browser I am getting a response as {key:value}. So, I assumed that it is a JSON response.
I am consuming it in spring boot as follows
restTemplate.getForObject(url, String.class) .
This is giving Invalid mime type "content-type: text/plain; charset=ISO-8859-1": Invalid token character ':' in token "content-type: text"
I assume that this error is because response content type is set to text/plain but it is returning JSON format.
EDIT:
Tried this way but did not work.
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters",headers);
ResponseEntity<String> result = restTemplate.exchange(url,HttpMethod.GET,
entity, String.class);
How to handle and solve it?
You might want to read about the request headers your REST API needs. Content-Type header specifies the media type of the request you're sending to the server. Because you're just getting data from the server you should set the Accept header to the kind of response you want i.e., Accept: application/json.
Unfortunately, you can't set headers using getForObject(). You could try this:
URL url = new URL("Enter the URL of the REST endpoint");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/json");
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuffer content = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
}