异常拦截器ExceptionMapper
在JAX-RS(Java API for RESTful Web Services)中,ExceptionMapper接口用于将Java异常映射到HTTP响应。通过实现ExceptionMapper接口,你可以自定义如何处理特定类型的异常,并生成相应的HTTP响应。
优先级和选择
当有多个ExceptionMapper可用于处理同一类型的异常时,JAX-RS会选择最具体的那个。例如,如果你有一个处理RuntimeException的ExceptionMapper和一个处理NullPointerException的ExceptionMapper,那么当抛出NullPointerException时,会选择处理NullPointerException的ExceptionMapper。
定义自定义异常
public class UniqueException extends RuntimeException {public UniqueException(Throwable cause) {super(cause);}public UniqueException(String message) {super(message);}public UniqueException(String message, Throwable cause) {super(message, cause);}}
实现ExceptionMapper
/*** 数据表约束异常处理器.** @author lind* @date 2024/6/4 10:45* @since 1.0.0*/
@Provider
public class DbViolationExceptionMapper implements ExceptionMapper<UniqueException> {@Overridepublic Response toResponse(UniqueException exception) {return Response.status(Response.Status.BAD_REQUEST).entity(MapUtil.builder().put("error", exception.getMessage()).build()).type(MediaType.APPLICATION_JSON).encoding("utf-8").build();// 非200的请求,这个type无效,一直是text/plain/** return Response.status(Response.Status.OK)* .entity(MapUtil.builder().put("error", exception.getMessage()).build())* .type("application/json; charset=UTF-8").build();//* 200的请求,是可以使用application/json的**/}}
注册ExceptionMapper
在文件resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
添加内容
com.xx.exception.handler.DbViolationExceptionMapper
业务代码直接抛出异常
if (getCurrentUserId() == null || !getCurrentUserId().equals(userId)) {throw new UniqueException("权限不足");}
相关问题
- 当在ExceptionMapper中返回的Response对象,状态码为200时,可以响应为application/json
- 当Response对象状态码非200时,响应一直是text/plain
经过调试与排查,发现当非200时,在这个过滤器里,它出现了两个content-type,text/plain
不知道是什么时间被加进去的,如图
方法执行到这里时,为响应头添加了text/plain
setStatus()方法如下
public void setStatus(int status) {if (status > 200) {this.addOutputHeaders(RestHeaderEnum.CONTENT_TYPE.getHeader(), MediaType.TEXT_PLAIN.value);}this.status = status;}
这也是业务代码中,直接报出自定义异常,在ExceptionMapper捕获返回json没有生效的原因,这块感觉dubbo设计的不太好。