Read error response body in Java
Here is the bug report (close, will not fix, not a bug).
Their advice there is to code like this:
HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
_is = httpConn.getInputStream();
} else {
/* error from server */
_is = httpConn.getErrorStream();
}
How can I get the actual error behind HttpResponseException?
Why do you use BasicResponseHandler()? The handler is doing that for you. That handler is just an example and shouldn't be used in real code.
You should either write your own handler or call execute without a handler.
For example,
HttpResponse response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
responseBody = entity.getContent();
if (statusCode != 200) {
// responseBody will have the error response
}
Retrofit 2.0 how to get deserialised error response.body
solved it by:
Converter<MyError> converter =
(Converter<MyError>)JacksonConverterFactory.create().get(MyError.class);
MyError myError = converter.fromBody(response.errorBody());
Why is it important to read the response body of an HTTP request?
I believe the intent of this code is indeed to consume the response body so that the connection can be reused. However, I'm not sure that this approach is correct; it is also likely to depend on the version of Java you are using.
First, it should suffice to get the connection's InputStream
and close it; behind the scenes, the body still needs to be read, but closing the stream signals to the connection handler that the application wants to skip the body, and the handler can read and discard the content before putting the connection into a cache for re-use.
However, depending on the status, there could be an error stream instead of an input stream. Even in this case, the body needs to be consumed before the connection can be re-used, but many applications (like this one) don't bother reading the body of an error message. Since Java 7, however, if the error body is small enough, it will be consumed and buffered automatically.
Behind the scenes, a connection cache is used to retain open connections. Although the method names suggest a new connection is opened every time, in fact the cache is first checked for an open connection.
How can I get http response body when request is failed in java?
Try the below code :
package com.abc.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String url = "http://localhost:8888/login?token=token";
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
int responseCode = connection.getResponseCode();
InputStream inputStream;
if (200 <= responseCode && responseCode <= 299) {
inputStream = connection.getInputStream();
} else {
inputStream = connection.getErrorStream();
}
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String currentLine;
while ((currentLine = in.readLine()) != null)
response.append(currentLine);
System.out.println(response.toString());
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Resteasy error response body is unreachable
Look into http://download.eclipse.org/microprofile/microprofile-rest-client-1.0/apidocs/org/eclipse/microprofile/rest/client/ext/ResponseExceptionMapper.html
@Provider
public class CustomResponseExceptionMapper implements ResponseExceptionMapper<RuntimeException> {
public CustomResponseExceptionMapper () {
}
public boolean handles(int statusCode, MultivaluedMap<String, Object> headers) {
}
public CusomExceptionMapper toThrowable(Response response) {
try {
String responseString = (String)response.readEntity(String.class);
............
}
}
}
Or
public class CustomExceptionMapper
implements ResponseExceptionMapper<Throwable> {
}
Register the ResponseExceptionMapper Provider:
@Path("/xyz")
@RegisterProvider(CustomResponseExceptionMapper.class)
@RegisterRestClient
@Timeout
How to get custom error body message in WebClient properly?
The main issue with the example code you have give is the following line of code
throw new ResourceNotFound(clientHttpResponse.getBody().toString());
The type of this is Flux<DataBuffer>
, not the actual response body. This is leading to the issue you are seeing.
The way to solve this is invoking the bodyToMono
method on the error response body and mapping to a java object. This can be done via the onStatus
operator expose from the web client that allows you to take specific actions on specific status codes.
The code snippet below should resolve this
webClient.post()
.uri(uriTest).body(Mono.just(req), PartnerShipmentDto.class)
.retrieve()
.onStatus(HttpStatus::isError, res -> res.bodyToMono(ErrorBody.class)
.onErrorResume(e -> Mono.error(new ResourceNotFound("aaaa")))
.flatMap(errorBody -> Mono.error(new ResourceNotFound(errorBody.getMessage())))
)
.bodyToMono(PartnerShipmentDto.class)
.block();
The class ErrorBody
should contain all of the fields you want to map from json to the java object. The example below only maps the "message" field.
public class ErrorBody {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Related Topics
What's the Purpose of Meta-Inf
Download Attachments Using Java Mail
Eclipse Error: Could Not Find or Load Main Class
How to Compile Multiple Java Source Files in Command Line
How to Deal with the Urisyntaxexception
Differencebetween a Hashmap and a Treemap
Joda-Time: What's the Difference Between Period, Interval and Duration
Using an Instance of an Object as a Key in Hashmap, and Then Access It with Exactly New Object
Is It Bad Practice to Make a Setter Return "This"
Factorial Using Recursion in Java
JSON Gson.Fromjson Java Objects