Last active
February 12, 2017 07:18
-
-
Save cmicat/18843ce2e36740256e02b30494a39685 to your computer and use it in GitHub Desktop.
Spring MVC log uncaught Throwable and return error message json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cmicat.lanVideoServer.spring; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.web.servlet.view.json.MappingJackson2JsonView; | |
/** | |
* Created by cmicat on 2017/2/12. | |
*/ | |
@Configuration | |
public class BeanConfig { | |
@Bean | |
public MappingJackson2JsonView mappingJackson2JsonView() { | |
return new MappingJackson2JsonView(); | |
} | |
@Bean | |
public ObjectMapper jackson2ObjectMapper() { | |
return new ObjectMapper(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cmicat.lanVideoServer.dto | |
/** | |
* Created by cmicat on 2017/2/11. | |
*/ | |
data class ErrorInfoDto( | |
val errorCode: Int, | |
val message: String | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cmicat.lanVideoServer.filter; | |
import com.cmicat.lanVideoServer.dto.ErrorInfoDto; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.web.context.support.SpringBeanAutowiringSupport; | |
import javax.servlet.DispatcherType; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.annotation.WebFilter; | |
import javax.servlet.http.HttpServletResponse; | |
import java.io.IOException; | |
/** | |
* Created by cmicat on 2017/2/10. | |
*/ | |
@WebFilter( | |
filterName = "ExceptionLogFilter", | |
urlPatterns = "/*", | |
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR} | |
) | |
public class ExceptionLogFilter implements Filter { | |
private static final Logger logger = LoggerFactory.getLogger("global_filter_exception_logger"); | |
@Autowired | |
private ObjectMapper mapper; | |
@Override | |
public void init(FilterConfig filterConfig) throws ServletException { | |
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); | |
} | |
@Override | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | |
throws IOException, ServletException { | |
try { | |
chain.doFilter(request, response); | |
} catch (IOException | ServletException e) { | |
logger.error("bad thing happened during doFilter", e); | |
ErrorInfoDto dto = new ErrorInfoDto(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()); | |
String result = mapper.writeValueAsString(dto); | |
HttpServletResponse res = (HttpServletResponse) response; | |
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); | |
res.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
response.getOutputStream().print(result); | |
} | |
} | |
@Override | |
public void destroy() { | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cmicat.lanVideoServer.spring; | |
import com.cmicat.lanVideoServer.dto.ErrorInfoDto; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.core.annotation.AnnotationUtils; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.web.bind.MissingServletRequestParameterException; | |
import org.springframework.web.bind.annotation.ExceptionHandler; | |
import org.springframework.web.bind.annotation.ResponseStatus; | |
import org.springframework.web.bind.annotation.RestControllerAdvice; | |
import javax.servlet.http.HttpServletRequest; | |
/** | |
* | |
* @author cmicat | |
*/ | |
@RestControllerAdvice | |
public class GlobalDefaultExceptionHandler { | |
private static final Logger logger = LoggerFactory.getLogger("global_controller_exception_logger"); | |
/** | |
* 在异常没有被其它东西捕捉的情况下,由它来打印日志 | |
* | |
* @throws Throwable | |
*/ | |
@ExceptionHandler(value = Throwable.class) | |
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) | |
public ErrorInfoDto defaultErrorHandler(Throwable e) throws Throwable { | |
// If the exception is annotated with @ResponseStatus rethrow it and let | |
// the framework handle it. | |
// AnnotationUtils is a Spring Framework utility class. | |
if (AnnotationUtils.findAnnotation | |
(e.getClass(), ResponseStatus.class) != null) { | |
throw e; | |
} | |
logger.error("global controller default exception handler", e); | |
return new ErrorInfoDto(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()); | |
} | |
@ExceptionHandler(MissingServletRequestParameterException.class) | |
@ResponseStatus(HttpStatus.BAD_REQUEST) | |
public ErrorInfoDto httpBadRequest(Exception e, HttpServletRequest request) { | |
StringBuffer requestURL = request.getRequestURL(); | |
logger.warn("url: '{}' HTTP Status 400 - {}", requestURL, e.getMessage()); | |
return new ErrorInfoDto(HttpStatus.BAD_REQUEST.value(), e.getMessage()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@file:JvmName("HttpServletRequestUtil") | |
package com.cmicat.lanVideoServer.util | |
import javax.servlet.http.HttpServletRequest | |
/** | |
* Created by cmicat on 2017/2/12. | |
*/ | |
fun HttpServletRequest.getFullUrl(): StringBuffer { | |
val url = this.requestURL | |
if (!this.queryString.isNullOrEmpty()) { | |
url.append("?").append(this.queryString) | |
} | |
return url | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<configuration> | |
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/> | |
<appender name="FILE" class="ch.qos.logback.core.FileAppender"> | |
<file>${user.home}/log/lan_video_server/log-${bySecond}.log</file> | |
<append>true</append> | |
<!-- encoders are assigned the type | |
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> | |
<encoder> | |
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger - %msg%n</pattern> | |
</encoder> | |
</appender> | |
<logger name="com.cmicat.lanVideoServer" level="DEBUG"/> | |
<logger name="global_controller_exception_logger" level="info"/> | |
<logger name="global_filter_exception_logger" level="info"/> | |
<root level="warn"> | |
<appender-ref ref="FILE"/> | |
</root> | |
<!-- 3rdparty Loggers --> | |
<logger name="org.springframework.core"> | |
<level value="info"/> | |
</logger> | |
<logger name="org.springframework.beans"> | |
<level value="info"/> | |
</logger> | |
<logger name="org.springframework.context"> | |
<level value="info"/> | |
</logger> | |
<logger name="org.springframework.web"> | |
<level value="info"/> | |
</logger> | |
</configuration> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cmicat.lanVideoServer.spring; | |
import com.cmicat.lanVideoServer.dto.ErrorInfoDto; | |
import com.cmicat.lanVideoServer.util.HttpServletRequestUtil; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.BeanFactoryUtils; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.context.MessageSource; | |
import org.springframework.context.MessageSourceAware; | |
import org.springframework.context.i18n.LocaleContextHolder; | |
import org.springframework.core.Ordered; | |
import org.springframework.core.annotation.AnnotatedElementUtils; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.stereotype.Component; | |
import org.springframework.web.bind.annotation.ResponseStatus; | |
import org.springframework.web.servlet.DispatcherServlet; | |
import org.springframework.web.servlet.ModelAndView; | |
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver; | |
import org.springframework.web.servlet.view.json.MappingJackson2JsonView; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import java.util.Map; | |
/** | |
* A {@link org.springframework.web.servlet.HandlerExceptionResolver | |
* HandlerExceptionResolver} that uses the {@link ResponseStatus @ResponseStatus} | |
* annotation to map exceptions to HTTP status codes. | |
* <br> | |
* This bean will hide {@link org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver}. | |
* <p> | |
* <p>This exception resolver is enabled by default in the | |
* {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet} | |
* and the MVC Java config and the MVC namespace. | |
* <p> | |
* This resolver also looks recursively for {@code @ResponseStatus} | |
* present on cause exceptions, and supports attribute overrides for | |
* {@code @ResponseStatus} in custom composed annotations. | |
* | |
* @author cmicat | |
* @see AnnotatedElementUtils#findMergedAnnotation | |
* @see org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver | |
*/ | |
@Component | |
public class ResponseStatusExceptionResolver | |
extends AbstractHandlerExceptionResolver implements MessageSourceAware { | |
private static final Logger logger = LoggerFactory.getLogger(ResponseStatusExceptionResolver.class); | |
@Autowired | |
private MappingJackson2JsonView view; | |
@Autowired | |
private ObjectMapper mapper; | |
private MessageSource messageSource; | |
@Override | |
public void setMessageSource(MessageSource messageSource) { | |
this.messageSource = messageSource; | |
} | |
/** | |
* The default <tt>ResponseStatusExceptionResolver</tt> has order MAX_INT | |
* (lowest priority - see {@link Ordered#LOWEST_PRECEDENCE}). The constructor | |
* gives this slightly higher precedence so it runs first. It will hide spring's | |
* default ExceptionHandlerExceptionResolver. see | |
* {@link DispatcherServlet#initHandlerExceptionResolvers} | |
* and {@link BeanFactoryUtils#beansOfTypeIncludingAncestors } | |
*/ | |
public ResponseStatusExceptionResolver() { | |
// Make sure this handler runs before the default | |
// ResponseStatusExceptionResolver | |
setOrder(0); | |
} | |
@Override | |
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, | |
Object handler, Exception ex) { | |
ResponseStatus responseStatus = AnnotatedElementUtils.findMergedAnnotation(ex.getClass(), ResponseStatus.class); | |
if (responseStatus != null) { | |
try { | |
int statusCode = responseStatus.value().value(); | |
String reason = responseStatus.reason(); | |
if (this.messageSource != null) { | |
reason = this.messageSource.getMessage(reason, null, reason, LocaleContextHolder.getLocale()); | |
} | |
StringBuffer requestURL = HttpServletRequestUtil.getFullUrl(request); | |
HttpStatus httpStatus = responseStatus.value(); | |
if (httpStatus.is4xxClientError()) { | |
logger.warn("url: '{}' HTTP Status {} - {}", requestURL, statusCode, reason); | |
return getErrorModelAndView(httpStatus, reason); | |
} else if (httpStatus.is5xxServerError()) { | |
logger.error("url: '{}' HTTP Status {} - {}", requestURL, statusCode, reason); | |
return getErrorModelAndView(httpStatus, reason); | |
} | |
return new ModelAndView(); | |
} catch (Exception resolveEx) { | |
logger.warn("Handling of @ResponseStatus resulted in Exception", resolveEx); | |
} | |
} else if (ex.getCause() instanceof Exception) { | |
ex = (Exception) ex.getCause(); | |
return doResolveException(request, response, handler, ex); | |
} | |
return null; | |
} | |
private ModelAndView getErrorModelAndView(HttpStatus httpStatus, String reason) { | |
ErrorInfoDto dto = new ErrorInfoDto(httpStatus.value(), reason); | |
Map map = mapper.convertValue(dto, Map.class); | |
ModelAndView modelAndView = new ModelAndView(view, map); | |
modelAndView.setStatus(httpStatus); | |
return modelAndView; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cmicat.lanVideoServer.spring; | |
import com.cmicat.lanVideoServer.dto.ErrorInfoDto; | |
import com.cmicat.lanVideoServer.util.HttpServletRequestUtil; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.ConversionNotSupportedException; | |
import org.springframework.beans.TypeMismatchException; | |
import org.springframework.core.Ordered; | |
import org.springframework.core.annotation.Order; | |
import org.springframework.http.HttpHeaders; | |
import org.springframework.http.HttpMethod; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.MediaType; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.http.converter.HttpMessageNotReadableException; | |
import org.springframework.http.converter.HttpMessageNotWritableException; | |
import org.springframework.util.CollectionUtils; | |
import org.springframework.validation.BindException; | |
import org.springframework.web.HttpMediaTypeNotAcceptableException; | |
import org.springframework.web.HttpMediaTypeNotSupportedException; | |
import org.springframework.web.HttpRequestMethodNotSupportedException; | |
import org.springframework.web.bind.MethodArgumentNotValidException; | |
import org.springframework.web.bind.MissingPathVariableException; | |
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.ServletWebRequest; | |
import org.springframework.web.context.request.async.AsyncRequestTimeoutException; | |
import org.springframework.web.multipart.support.MissingServletRequestPartException; | |
import org.springframework.web.servlet.NoHandlerFoundException; | |
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; | |
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; | |
import org.springframework.web.util.WebUtils; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import java.util.List; | |
import java.util.Set; | |
/** | |
* Provides an {@code @ExceptionHandler} method for handling internal Spring MVC exceptions. | |
* <p> | |
* <p>Note that in order for this class to be detected, {@link ExceptionHandlerExceptionResolver} | |
* must be configured. | |
* <p> | |
* This Class use {@link Order} to make sure this ControllerAdvice run before {@link GlobalDefaultExceptionHandler} | |
* </p> | |
* | |
* @author cmicat | |
* @see #handleException(Exception, HttpServletRequest) | |
* @see org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver | |
* @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler | |
*/ | |
@ControllerAdvice | |
@Order(Ordered.HIGHEST_PRECEDENCE) | |
public class SpringStandardWebMvcExceptionHandler { | |
private static final Logger logger = LoggerFactory.getLogger("global_controller_exception_logger"); | |
/** | |
* Provides handling for standard Spring MVC exceptions. | |
* | |
* @param ex the target exception | |
* @param request the current request | |
*/ | |
@SuppressWarnings("deprecation") | |
@ExceptionHandler({ | |
NoSuchRequestHandlingMethodException.class, | |
HttpRequestMethodNotSupportedException.class, | |
HttpMediaTypeNotSupportedException.class, | |
HttpMediaTypeNotAcceptableException.class, | |
MissingPathVariableException.class, | |
MissingServletRequestParameterException.class, | |
ServletRequestBindingException.class, | |
ConversionNotSupportedException.class, | |
TypeMismatchException.class, | |
HttpMessageNotReadableException.class, | |
HttpMessageNotWritableException.class, | |
MethodArgumentNotValidException.class, | |
MissingServletRequestPartException.class, | |
BindException.class, | |
NoHandlerFoundException.class, | |
AsyncRequestTimeoutException.class | |
}) | |
public final ResponseEntity<Object> handleException(Exception ex, HttpServletRequest request) { | |
HttpHeaders headers = new HttpHeaders(); | |
if (ex instanceof NoSuchRequestHandlingMethodException) { | |
HttpStatus status = HttpStatus.NOT_FOUND; | |
return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, headers, status, request); | |
} else if (ex instanceof HttpRequestMethodNotSupportedException) { | |
HttpStatus status = HttpStatus.METHOD_NOT_ALLOWED; | |
return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, headers, status, request); | |
} else if (ex instanceof HttpMediaTypeNotSupportedException) { | |
HttpStatus status = HttpStatus.UNSUPPORTED_MEDIA_TYPE; | |
return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, headers, status, request); | |
} else if (ex instanceof HttpMediaTypeNotAcceptableException) { | |
HttpStatus status = HttpStatus.NOT_ACCEPTABLE; | |
return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, headers, status, request); | |
} else if (ex instanceof MissingPathVariableException) { | |
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; | |
return handleMissingPathVariable((MissingPathVariableException) ex, headers, status, request); | |
} else if (ex instanceof MissingServletRequestParameterException) { | |
HttpStatus status = HttpStatus.BAD_REQUEST; | |
return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, headers, status, request); | |
} else if (ex instanceof ServletRequestBindingException) { | |
HttpStatus status = HttpStatus.BAD_REQUEST; | |
return handleServletRequestBindingException((ServletRequestBindingException) ex, headers, status, request); | |
} else if (ex instanceof ConversionNotSupportedException) { | |
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; | |
return handleConversionNotSupported((ConversionNotSupportedException) ex, headers, status, request); | |
} else if (ex instanceof TypeMismatchException) { | |
HttpStatus status = HttpStatus.BAD_REQUEST; | |
return handleTypeMismatch((TypeMismatchException) ex, headers, status, request); | |
} else if (ex instanceof HttpMessageNotReadableException) { | |
HttpStatus status = HttpStatus.BAD_REQUEST; | |
return handleHttpMessageNotReadable((HttpMessageNotReadableException) ex, headers, status, request); | |
} else if (ex instanceof HttpMessageNotWritableException) { | |
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; | |
return handleHttpMessageNotWritable((HttpMessageNotWritableException) ex, headers, status, request); | |
} else if (ex instanceof MethodArgumentNotValidException) { | |
HttpStatus status = HttpStatus.BAD_REQUEST; | |
return handleMethodArgumentNotValid((MethodArgumentNotValidException) ex, headers, status, request); | |
} else if (ex instanceof MissingServletRequestPartException) { | |
HttpStatus status = HttpStatus.BAD_REQUEST; | |
return handleMissingServletRequestPart((MissingServletRequestPartException) ex, headers, status, request); | |
} else if (ex instanceof BindException) { | |
HttpStatus status = HttpStatus.BAD_REQUEST; | |
return handleBindException((BindException) ex, headers, status, request); | |
} else if (ex instanceof NoHandlerFoundException) { | |
HttpStatus status = HttpStatus.NOT_FOUND; | |
return handleNoHandlerFoundException((NoHandlerFoundException) ex, headers, status, request); | |
} else if (ex instanceof AsyncRequestTimeoutException) { | |
HttpStatus status = HttpStatus.SERVICE_UNAVAILABLE; | |
return handleAsyncRequestTimeoutException( | |
(AsyncRequestTimeoutException) ex, headers, status, request); | |
} else { | |
if (logger.isWarnEnabled()) { | |
logger.warn("Unknown exception type: " + ex.getClass().getName()); | |
} | |
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
} | |
/** | |
* A single place to customize the response body of all Exception types. | |
* <p>The default implementation sets the {@link WebUtils#ERROR_EXCEPTION_ATTRIBUTE} | |
* request attribute and creates a {@link ResponseEntity} from the given | |
* body, headers, and status. | |
* | |
* @param ex the exception | |
* @param headers the headers for the response | |
* @param status the response status | |
* @param request the current request | |
*/ | |
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
StringBuffer url = HttpServletRequestUtil.getFullUrl(request); | |
if (status.is4xxClientError()) { | |
logger.warn("url: '{}' HTTP Status {} - {}", url, status, ex.getMessage()); | |
} else if (status.is5xxServerError()) { | |
logger.error("url: '{}' HTTP Status {} - {}", url, status, ex.getMessage()); | |
} | |
ErrorInfoDto dto = new ErrorInfoDto(status.value(), ex.getMessage()); | |
return new ResponseEntity<Object>(dto, headers, status); | |
} | |
/** | |
* Customize the response for NoSuchRequestHandlingMethodException. | |
* <p>This method logs a warning and delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
* @deprecated as of 4.3, along with {@link NoSuchRequestHandlingMethodException} | |
*/ | |
@Deprecated | |
protected ResponseEntity<Object> handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for HttpRequestMethodNotSupportedException. | |
* <p>This method logs a warning, sets the "Allow" header, and delegates to | |
* {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
Set<HttpMethod> supportedMethods = ex.getSupportedHttpMethods(); | |
if (!supportedMethods.isEmpty()) { | |
headers.setAllow(supportedMethods); | |
} | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for HttpMediaTypeNotSupportedException. | |
* <p>This method sets the "Accept" header and delegates to | |
* {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
List<MediaType> mediaTypes = ex.getSupportedMediaTypes(); | |
if (!CollectionUtils.isEmpty(mediaTypes)) { | |
headers.setAccept(mediaTypes); | |
} | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for HttpMediaTypeNotAcceptableException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(HttpMediaTypeNotAcceptableException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for MissingPathVariableException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
* @since 4.2 | |
*/ | |
protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for MissingServletRequestParameterException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for ServletRequestBindingException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleServletRequestBindingException(ServletRequestBindingException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for ConversionNotSupportedException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleConversionNotSupported(ConversionNotSupportedException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for TypeMismatchException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, | |
HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for HttpMessageNotReadableException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for HttpMessageNotWritableException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleHttpMessageNotWritable(HttpMessageNotWritableException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for MethodArgumentNotValidException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for MissingServletRequestPartException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleMissingServletRequestPart(MissingServletRequestPartException ex, | |
HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for BindException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
*/ | |
protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, | |
HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for NoHandlerFoundException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param request the current request | |
* @return a {@code ResponseEntity} instance | |
* @since 4.0 | |
*/ | |
protected ResponseEntity<Object> handleNoHandlerFoundException( | |
NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, HttpServletRequest request) { | |
return handleExceptionInternal(ex, headers, status, request); | |
} | |
/** | |
* Customize the response for NoHandlerFoundException. | |
* <p>This method delegates to {@link #handleExceptionInternal}. | |
* | |
* @param ex the exception | |
* @param headers the headers to be written to the response | |
* @param status the selected response status | |
* @param webRequest the current request | |
* @return a {@code ResponseEntity} instance | |
* @since 4.2.8 | |
*/ | |
protected ResponseEntity<Object> handleAsyncRequestTimeoutException( | |
AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, HttpServletRequest webRequest) { | |
if (webRequest instanceof ServletWebRequest) { | |
ServletWebRequest servletRequest = (ServletWebRequest) webRequest; | |
HttpServletRequest request = servletRequest.getNativeRequest(HttpServletRequest.class); | |
HttpServletResponse response = servletRequest.getNativeResponse(HttpServletResponse.class); | |
if (response.isCommitted()) { | |
logger.error("Async timeout for " + request.getMethod() + " [" + request.getRequestURI() + "]"); | |
return null; | |
} | |
} | |
return handleExceptionInternal(ex, headers, status, webRequest); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment