-->

Unmarshalling response depending on HTTP code duri

2019-07-28 01:35发布

问题:

Calling a Rest Webservice using the Spring Rest Template as follows-

ResponseEntity<String> response = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, entity, String.class); 

and get the output in String format as

<Info xmlns="http://schemas.test.org/2009/09/Tests.new" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>FirstName</FirstName>
<LastName>LastName</LastName>
<TestGuid>Guid</TestGuid>
<TestUID>1</TestUID>
<Token>token</Token>
<TestUserID>14</TestUserID>
</Info>

When trying to unmarshal it to java class as follows

ResponseEntity<Info> response = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, entity, Info.class)

The Info class is defined as

@XmlRootElement(name = "Info", namespace = "http://schemas.test.org/2009/09/Tests.new")
public class Info implements Serializable{

    private String FirstName;
    private String LastName;
    private String TestGuid;
    private String TestUID;
    private String Token;
    private String TestUserID;

    //getters and setter

}   

If the Response http code is 500 then the response is not of type info but of other type infoException.

Can we specify to the resttemplate to unmarshal the output depending on the Http response code?

回答1:

The rest template checks response for error before extracting the data. So one way would be to create Rest Template with the implementation of ResponseErrorHandler and override the handleError method to extract the error response to your object using converters and then wrap this error object into exception. Something like this.

    class ErrorObjectResponseHandler implements ResponseErrorHandler {

      private List<HttpMessageConverter<?>> messageConverters;

      @Override
      public boolean hasError(ClientHttpResponse response) throws IOException {
        return hasError(response.getStatusCode());
      }

      protected boolean hasError(HttpStatus statusCode) {
        return (statusCode.is4xxClientError() || statusCode.is5xxServerError());
      }

      @Override
      public void handleError(ClientHttpResponse response) throws IOException {
        HttpMessageConverterExtractor<Error> errorMessageExtractor =
          new HttpMessageConverterExtractor(Error.class, messageConverters);
        Error errorObject = errorMessageExtractor.extractData(response);
        throw new SomeException(errorObject);
      }

      public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        this.messageConverters = messageConverters;
      }


回答2:

Spring 5 offers ExtractingResponseErrorHandler specifically for this purpose



回答3:

Its XML to POJO cannot be de-serialize due to Mapping from XML to class. Try using this POJO.

public class Info implements Serializable{

    private String TestGuid;

    private String TestUID;

    private String FirstName;

    private String xmlns;

    private String Token;

    private String LastName;

    private String TestUserID;

    //getters and setter
}