Está en la página 1de 5

package com.app.common.web.

controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
tionHandler;
import com.app.common.ClientError;
import com.app.common.ErrorMessage;
import com.app.common.exception.NotValidException;
import com.app.common.exception.RequestNotValidException;
import com.app.common.exception.UserAuthenticationException;
import com.app.common.util.CollectionUtilities;
import com.app.common.util.StringUtilities;
/**
* {@link ControllerAdvice} that handles exceptions thrown by any classes that
* are {@link org.springframework.web.servlet.mvc.Controller}s within this
* application. This particular implementation extends
* {@link ResponseEntityExceptionHandler} which is a convenient abstract base
* class that provides methods for handling several common Spring MVC
* exceptions. See
* <code>http://www.jayway.com/2013/02/03/improve-your-spring-rest-api-part-iii/
</code>
* for discussion.
*
* @author Aditya R
*/
@ControllerAdvice
public class AllControllersExceptionHandler extends
ResponseEntityExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AllControll
ersExceptionHandler.class);
private static final String LOG_MESSAGE_EXCEPTION_CAUGHT_SEPARATOR = "':
";
private static final String ERROR_FAILURE = "failure";
/**
* Handler method for {@link RequestNotValidException}.
*
* @param exception
* the {@link RequestNotValidException}
* @param request
* the current {@link WebRequest}.
* @return a {@link ResponseEntity} instance.
*/
@ExceptionHandler(value = RequestNotValidException.class)
public ResponseEntity<Object> handleRequestNotValidException(
final Exception exception, final WebRequest request) {
final HttpStatus responseStatus = HttpStatus.BAD_REQUEST;
final RequestNotValidException notValidException = (RequestNotVa
lidException) exception;
final ErrorMessage errorMessage = new ErrorMessage(
notValidException.getErrors());
LOGGER.error(
"RequestNotValidException raised! Sending HTTP status '{
}' along {}",
responseStatus, errorMessage);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<Object>(errorMessage, headers, respons
eStatus);
}
/**
* Handler method for any {@link RuntimeException}s that are not handled
in
* other methods in this class.
*
* @param exception
* the {@link RuntimeException}.
* @param request
* the current {@link WebRequest}.
* @return a {@link ResponseEntity} instance
*/
@ExceptionHandler(value = RuntimeException.class)
public ResponseEntity<Object> handleRuntimeException(
final Exception exception) {
final HttpStatus responseStatus = HttpStatus.INTERNAL_SERVER_ERR
OR;
LOGGER.error("Received the following Runtime Exception and retur
ning '"
+ responseStatus + LOG_MESSAGE_EXCEPTION_CAUGHT_SEPARATO
R,
exception);
final ErrorMessage errorMessage = new ErrorMessage(new ClientErr
or(
ERROR_FAILURE, exception.getMessage(), StringUtilities.E
MPTY));
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<Object>(errorMessage, headers, respons
eStatus);
}
/**
* Handler method for {@link UserAuthenticationException}.
*
* @param exception
* the {@link UserAuthenticationException}.s
* @param request
* the current {@link WebRequest}.
* @return a {@link ResponseEntity} instance.
*/
@ExceptionHandler(value = UserAuthenticationException.class)
public ResponseEntity<Object> handleUserAuthenticationException(
final Exception exception, final WebRequest request) {
final HttpStatus responseStatus = HttpStatus.NETWORK_AUTHENTICAT
ION_REQUIRED;
LOGGER.error(
"Received the following UserAuthenticationException and
returning '"
+ responseStatus + LOG_MESSAGE_EXCEPTION_CAUGHT_
SEPARATOR,
exception);
return buildResponseEntity(exception.getMessage(), responseStatu
s);
}
private ResponseEntity<Object> buildResponseEntity(
final String exceptionMessage, final HttpStatus responseStatus)
{
final ErrorMessage errorMessage = new ErrorMessage(new ClientErr
or(
ERROR_FAILURE, exceptionMessage, StringUtilities.EMPTY))
;
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<Object>(errorMessage, headers, respons
eStatus);
}
@Override
protected ResponseEntity<Object> handleMissingServletRequestParameter(
final MissingServletRequestParameterException exception,
final HttpHeaders headers, final HttpStatus status,
final WebRequest request) {
final HttpStatus responseStatus = HttpStatus.BAD_REQUEST;
LOGGER.error(
"Received the following MissingServletRequestParameterEx
ception and returning '"
+ responseStatus + LOG_MESSAGE_EXCEPTION_CAUGHT_
SEPARATOR,
exception);
final ErrorMessage errorMessage = buildErrorMessageFromMissingSe
rvletRequestParameterException(exception);
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<Object>(errorMessage, headers, respons
eStatus);
}
private ErrorMessage buildErrorMessageFromMissingServletRequestParameter
Exception(
final MissingServletRequestParameterException exception) {
final StringBuilder error = new StringBuilder();
error.append(exception.getMessage());
error.append("(");
error.append(exception.getParameterName());
error.append(" : ");
error.append(exception.getParameterType());
return new ErrorMessage(new ClientError(ERROR_FAILURE,
error.toString(), StringUtilities.EMPTY));
}
@Override
protected ResponseEntity<Object> handleBindException(
final BindException exception, final HttpHeaders headers,
final HttpStatus status, final WebRequest request) {
final HttpStatus responseStatus = HttpStatus.BAD_REQUEST;
LOGGER.error("Received the following BindException and returning
'"
+ responseStatus + LOG_MESSAGE_EXCEPTION_CAUGHT_SEPARATO
R,
exception);
final ErrorMessage errorMessage = buildErrorMessageFromBindExcep
tion(exception);
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<Object>(errorMessage, headers, respons
eStatus);
}
private ErrorMessage buildErrorMessageFromBindException(
final BindException exception) {
final List<FieldError> fieldErrors = exception.getFieldErrors();
final List<ClientError> errors;
if (CollectionUtilities.isEmpty(fieldErrors)) {
errors = Collections.singletonList(new ClientError(ERROR
_FAILURE,
exception.getMessage(), StringUtilities.EMPTY));
}
else {
errors = new ArrayList<ClientError>(fieldErrors.size());
String error;
for (final FieldError fieldError : fieldErrors) {
error = fieldError.getField() + " : "
+ fieldError.getDefaultMessage();
errors.add(new ClientError(ERROR_FAILURE, error,
StringUtilities.EMPTY));
}
}
return new ErrorMessage(errors);
}
@Override
protected ResponseEntity<Object> handleServletRequestBindingException(
final ServletRequestBindingException exception,
final HttpHeaders headers, final HttpStatus status,
final WebRequest request) {
final HttpStatus responseStatus = HttpStatus.BAD_REQUEST;
LOGGER.error(
"Received the following ServletRequestBindingException a
nd returning '"
+ responseStatus + LOG_MESSAGE_EXCEPTION_CAUGHT_
SEPARATOR,
exception);
final ErrorMessage errorMessage = new ErrorMessage(new ClientErr
or(
ERROR_FAILURE, exception.getMessage(), StringUtilities.E
MPTY));
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<Object>(errorMessage, headers, respons
eStatus);
}
/**
* Handler method for {@link NotValidException}.
*
* @param exception
* the {@link NotValidException}
* @param request
* the current {@link WebRequest}.
* @return a {@link ResponseEntity} instance.
*/
@ExceptionHandler(value = NotValidException.class)
public ResponseEntity<Object> handleNotValidException(
final Exception exception, final WebRequest request) {
final HttpStatus responseStatus = HttpStatus.BAD_REQUEST;
final NotValidException notValidException = (NotValidException)
exception;
final List<ClientError> errors = notValidException.getErrors();
final ErrorMessage errorMessage = new ErrorMessage(errors);
LOGGER.error(
"RequestNotValidException raised! Sending HTTP status '{
}' along {}",
responseStatus, errorMessage);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<Object>(errorMessage, headers, respons
eStatus);
}
}

También podría gustarte