package org.springside.examples.bootapi.api.support;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
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.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springside.examples.bootapi.service.exception.ServiceException;
import org.springside.modules.utils.mapper.JsonMapper;
import org.springside.modules.web.MediaTypes;
import com.google.common.collect.Maps;
@ControllerAdvice(annotations = { RestController.class })
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
private Logger logger = LoggerFactory.getLogger(CustomExceptionHandler.class);
private JsonMapper jsonMapper = new JsonMapper();
@ExceptionHandler(value = { ServiceException.class })
public final ResponseEntity<ErrorResult> handleServiceException(ServiceException ex, HttpServletRequest request) {
// 注入servletRequest,用于出错时打印请求URL与来源地址
logError(ex, request);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType(MediaTypes.JSON_UTF_8));
ErrorResult result = new ErrorResult(ex.errorCode.code, ex.getMessage());
return new ResponseEntity<ErrorResult>(result, headers, HttpStatus.valueOf(ex.errorCode.httpStatus));
}
@ExceptionHandler(value = { Exception.class })
public final ResponseEntity<ErrorResult> handleGeneralException(Exception ex, HttpServletRequest request) {
logError(ex, request);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType(MediaTypes.JSON_UTF_8));
ErrorResult result = new ErrorResult(HttpStatus.INTERNAL_SERVER_ERROR.value(),
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
return new ResponseEntity<ErrorResult>(result, headers, HttpStatus.INTERNAL_SERVER_ERROR);
}
/**
* 重载ResponseEntityExceptionHandler的方法,加入日志
*/
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
HttpStatus status, WebRequest request) {
logError(ex);
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
request.setAttribute("javax.servlet.error.exception", ex, WebRequest.SCOPE_REQUEST);
}
return new ResponseEntity<Object>(body, headers, status);
}
public void logError(Exception ex) {
Map<String, String> map = Maps.newHashMap();
map.put("message", ex.getMessage());
logger.error(jsonMapper.toJson(map), ex);
}
public void logError(Exception ex, HttpServletRequest request) {
Map<String, String> map = Maps.newHashMap();
map.put("message", ex.getMessage());
map.put("from", request.getRemoteAddr());
String queryString = request.getQueryString();
map.put("path", queryString != null ? (request.getRequestURI() + "?" + queryString) : request.getRequestURI());
logger.error(jsonMapper.toJson(map), ex);
}
}