前言
Spring Boot的全局拦截器@ControllerAdvice + @ExceptionHandle
无法捕获404
异常。默认返回/error
接口的内容.
默认实现
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
xxx
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections
.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
}
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
return new ResponseEntity<>(status);
}
Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
return new ResponseEntity<>(body, status);
}
xxx
}
解决方案
自定义异常处理类实现ErrorController
覆盖默认的实现即可。
@RestController
@Slf4j
public class DefaultUncaughtErrorControllor implements ErrorController {
@RequestMapping("/error")
public Response error(HttpServletRequest request, HttpServletResponse response) {
HttpStatus statusCode = getHttpStatusCode(request);
String uri = (String) request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI);
log.error("error,code:{},uri:{}", statusCode.value(), uri);
return Response.error(statusCode.value(), "未找到接口", uri);
}
private HttpStatus getHttpStatusCode(HttpServletRequest request) {
try {
Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
} catch (Exception e) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
}
@Override
public String getErrorPath() {
return null;
}
}
结果:
{
code: 404,
msg: "未找到接口",
data: "/do35"
}
参考:
- https://segmentfault.com/a/1190000021259215