All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.jsonrpc4j.spring.rest.JsonRpcResponseErrorHandler Maven / Gradle / Ivy

package com.googlecode.jsonrpc4j.spring.rest;

import org.springframework.http.HttpHeaders;
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 org.springframework.web.client.UnknownHttpStatusCodeException;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JsonRpcResponseErrorHandler
		implements ResponseErrorHandler {
	
	public static final JsonRpcResponseErrorHandler INSTANCE =  new JsonRpcResponseErrorHandler();
	
    private  final Logger logger = LoggerFactory.getLogger(this.getClass());
    
	/**
	 * for supported codes see {@link com.googlecode.jsonrpc4j.DefaultHttpStatusCodeProvider}
	 */
	private final Set JSON_RPC_STATUES = new HashSet();
	
	
	private JsonRpcResponseErrorHandler() {
		JSON_RPC_STATUES.add(HttpURLConnection.HTTP_INTERNAL_ERROR);
		JSON_RPC_STATUES.add(HttpURLConnection.HTTP_BAD_REQUEST);
		JSON_RPC_STATUES.add(HttpURLConnection.HTTP_NOT_FOUND);
	}
	
	@Override
	public boolean hasError(ClientHttpResponse response)
			throws IOException {
		
		final HttpStatus httpStatus = getHttpStatusCode(response);
		
		if (JSON_RPC_STATUES.contains(httpStatus.value())) {
			// Checks the content type. If application/json-rpc then allow handler to read message
			final MediaType contentType = response.getHeaders().getContentType();
			if (MappingJacksonRPC2HttpMessageConverter.APPLICATION_JSON_RPC.isCompatibleWith(contentType))
				return false;
		}
		
		return
				httpStatus.series() == HttpStatus.Series.CLIENT_ERROR ||
						httpStatus.series() == HttpStatus.Series.SERVER_ERROR;
	}
	
	@Override
	public void handleError(ClientHttpResponse response)
			throws IOException {
		final HttpStatus statusCode = getHttpStatusCode(response);
		
		switch (statusCode.series()) {
			case CLIENT_ERROR:
				throw new HttpClientErrorException(statusCode, response.getStatusText(),
						response.getHeaders(), getResponseBody(response), getCharset(response));
			case SERVER_ERROR:
				throw new HttpServerErrorException(statusCode, response.getStatusText(),
						response.getHeaders(), getResponseBody(response), getCharset(response));
			default:
				throw new RestClientException("Unknown status code [" + statusCode + "]");
		}
	}
	
	
	private HttpStatus getHttpStatusCode(ClientHttpResponse response) throws IOException {
		final HttpStatus statusCode;
		try {
			statusCode = response.getStatusCode();
		} catch (IllegalArgumentException ex) {
			throw new UnknownHttpStatusCodeException(response.getRawStatusCode(),
					response.getStatusText(), response.getHeaders(), getResponseBody(response), getCharset(response));
		}
		return statusCode;
	}
	
	private byte[] getResponseBody(ClientHttpResponse response) {
		try {
			final InputStream responseBody = response.getBody();
			if (responseBody != null) {
				return FileCopyUtils.copyToByteArray(responseBody);
			}
		} catch (IOException ex) {
            // No body in response 401 for example
            logger.debug("Can not read resonse body", ex);
		}
		return new byte[0];
	}
	
	private Charset getCharset(ClientHttpResponse response) {
		HttpHeaders headers = response.getHeaders();
		MediaType contentType = headers.getContentType();
		return contentType != null ? contentType.getCharset() : null;
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy