nl.gridshore.nosapi.impl.NosApiResponseErrorHandler.java Source code

Java tutorial

Introduction

Here is the source code for nl.gridshore.nosapi.impl.NosApiResponseErrorHandler.java

Source

/*
 * Copyright (c) 2011. Gridshore
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package nl.gridshore.nosapi.impl;

import nl.gridshore.nosapi.ClientException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestClientException;

import java.io.IOException;
import java.nio.charset.Charset;

/**
 * <p>ResponseErrorHandler that knows the error codes that NOS API uses. We obtain the json values from these
 * exceptions and in any other situation throw the default spring Client and server applications.</p>
 *
 * @author Jettro Coenradie
 */
public class NosApiResponseErrorHandler implements ResponseErrorHandler {
    private final static Logger logger = LoggerFactory.getLogger(NosApiResponseErrorHandler.class);

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        HttpStatus statusCode = response.getStatusCode();
        return (statusCode.series() == HttpStatus.Series.CLIENT_ERROR
                || statusCode.series() == HttpStatus.Series.SERVER_ERROR);
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        logger.debug("Handle error '{}' received from the NOS server.", response.getStatusCode().name());
        HttpStatus statusCode = response.getStatusCode();
        MediaType contentType = response.getHeaders().getContentType();
        Charset charset = contentType != null ? contentType.getCharSet() : null;
        byte[] body = FileCopyUtils.copyToByteArray(response.getBody());

        switch (statusCode) {
        case BAD_REQUEST:
        case UNAUTHORIZED:
        case FORBIDDEN:
            throwClientException(charset, body);
        default:
            // do nothing, let the series resolving do it' work
        }

        switch (statusCode.series()) {
        case CLIENT_ERROR:
            throw new HttpClientErrorException(statusCode, response.getStatusText(), body, charset);
        case SERVER_ERROR:
            throw new HttpServerErrorException(statusCode, response.getStatusText(), body, charset);
        default:
            throw new RestClientException("Unknown status code [" + statusCode + "]");
        }
    }

    private void throwClientException(Charset charset, byte[] body) throws IOException {
        String jsonContentString = (charset != null) ? new String(body, charset) : new String(body);

        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readValue(jsonContentString, JsonNode.class);
        String type = rootNode.getFieldNames().next();

        JsonNode errorNode = rootNode.get("error");
        int code = errorNode.get("code").getIntValue();
        String message = errorNode.get("message").getTextValue();
        throw new ClientException(code, type, message);
    }
}