0

I am using RestTemplate to handle communications between our service and a polycom rmx device which has an http api mostly consisting of post calls transmitting xml back and forth. The problem comes when there is an error (ie, something not found), it will not return the expected response and so I get an error

org.springframework.http.converter.HttpMessageNotReadableException: Could not unmarshal to [class com.ourclass.polycom.rmx.sdk.RESPONSETRANSRES]: unexpected element (uri:"", local:"RESPONSE_GENERAL"). Expected elements are <{}ACTION>,<{}ADDITIONAL_INFO>

So its tring to deserialize the error object to RESPONSETRANSRES because thats what was passed in (see code below), but because of the error response we are actually getting a RESPONSEGENERAL object and so it doesnt know how to marshal as that instead.

protected <Request, Response> Response doPost(String uri, Request data, Class<Response> responseClass) throws Exception
    {
        String requestUrl = null;
        try
        {
            RestTemplate restApi = obtainRestTemlate(true);
            ResponseEntity<Response> response = restApi.exchange(requestUrl, HttpMethod.POST, createRestRequest(HttpMethod.POST, uri, data), responseClass);
            validateResponseStatus(response.getStatusCode());
            return response.getBody();
        }
        catch (Exception e)
        {
            throw translateError(requestUrl, e);
        }
    }

Since this is for an error case, I would prefer to catch the exception, get the payload and reparse it into the object I know it to be. Is that possible and how?

I was looking over this SO answer but e.getResponseBodyAsString(); is not a member of my exception. Its probably also important to note that when the errors happen, the status code is still 200 ok. so the catch indicated in the post would not happen for me.

Community
  • 1
  • 1
owen gerig
  • 6,165
  • 6
  • 52
  • 91
  • REST API does provide error handling for both error code level and for status code level. refer this example for instance: http://howtodoinjava.com/jersey/jax-rs-jersey-custom-exceptions-handling-with-exceptionmapper/ – Amit Mahajan Sep 09 '16 at 19:25

1 Answers1

0

Not the best solution and kind of a hack I made it returned as a String than try to manually marshal it as the expected response and upon error marshal it as the other object.

    Class<?> requestClass = data.getClass();
    Method method = requestClass.getMethod("setTRANSCOMMONPARAMS", TransCommonParamsContent.class);
    TransCommonParamsContent newTransCommonParams = new TransCommonParamsContent();
    newTransCommonParams.setMCUTOKEN(transCommonParamsContent.getMCUTOKEN());
    newTransCommonParams.setMCUUSERTOKEN(transCommonParamsContent.getMCUUSERTOKEN());
    method.invoke(data, newTransCommonParams);

    String responseString = doPost(getBaseUri(), data, String.class);
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(responseClass);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        @SuppressWarnings("unchecked")
        Response response = (Response) unmarshaller.unmarshal(new StringReader(responseString));
        return response;
    } catch (Exception e) {
        JAXBContext jaxbContext = JAXBContext.newInstance(RESPONSEGENERAL.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        RESPONSEGENERAL errorResponse = (RESPONSEGENERAL) unmarshaller.unmarshal(new StringReader(responseString));
owen gerig
  • 6,165
  • 6
  • 52
  • 91