1、配置时增加
1、定义异常处理器、
@Provider
public class InvokeFaultExceptionMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable ex) {
int code;
String msg;
if (ex instanceof NotFoundException) {
//没有找到资源路径
code = 404;
msg = "404";
} else if (ex instanceof JsonParseException) {
code = 400;
msg = "json转换异常";
} else if (ex instanceof UnrecognizedPropertyException) {
code = 400;
msg = "";
} else {
code = 500;
msg = ex.getMessage();
}
ResponseData date = ResponseData.build().setStatusCode(code).setMessage(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON).entity(date).build();
}
}
2、注册到Server
@Bean
public Server jaxRsServer(ApplicationContext ctx) {
List<Object> providers = new LinkedList<Object>();
providers.add(new ApiRestJsonProvider());
providers.add(new TokenCheckRequestFilter());
providers.add(new TokenCleanResponseFilter());
providers.add(new InvokeFaultExceptionMapper());
// providers.add(new SessionContainerRequestFilter());
// providers.add(new ApiServiceContainerResponseFilter());
// zipkin filter
if (Objects.nonNull(tracingContainerFilter)) {
providers.add(tracingContainerFilter);
}
LinkedList<ResourceProvider> resourceProviders = new LinkedList<>();
for (String beanName : ctx.getBeanDefinitionNames()) {
if (ctx.findAnnotationOnBean(beanName, Path.class) != null) {
SpringResourceFactory factory = new SpringResourceFactory(beanName);
factory.setApplicationContext(ctx);
resourceProviders.add(factory);
}
}
if (resourceProviders.size() == 0) {
LOGGER.error("未找到API接口实现,请仔细检查api包下的接口定义。");
System.exit(0);
}
List<Feature> features = new LinkedList<Feature>();
if (ContextUtil.isDevEnv()) {
features.add(swagger2Feature());
}
//拦截器
// List<Interceptor<? extends Message>> interceptorsIn = new ArrayList<Interceptor<? extends Message>>();
// interceptorsIn.add(tokenCheckInterceptor());
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
factory.setBus(springBus());
factory.setProviders(providers);
factory.setResourceProviders(resourceProviders);
factory.setFeatures(features);
// factory.setInInterceptors(interceptorsIn);
return factory.create();
}
2、运行时通过反射增加
1、定义异常处理器。
@Provider
private static class InvokeFailExceptionMapper implements ExceptionMapper<ValidFailException> {
@Override
public Response toResponse(ValidFailException ex) {
ResponseData<?> data = ResponseData.builder()
.statusCode(Response.Status.EXPECTATION_FAILED.getStatusCode())
.status("FAILURE")
.success(false)
.message(ex.getMessage())
.data(null)
.build();
return Response
.status(Response.Status.EXPECTATION_FAILED)
.type(MediaType.APPLICATION_JSON)
.entity(data)
.build();
}
}
@Getter
@Builder
@SuppressWarnings("all")
static class ResponseData<T> implements Serializable {
private static final long serialVersionUID = 652732203000606893L;
String status;
Boolean success = Boolean.TRUE;
Integer statusCode = 200;
String message;
T data;
}
2、通过反射注册到Server。
@Component
public static class FailExceptionHandlerConfig implements InitializingBean {
@Resource
private ServerImpl jaxRsServer;
@Override
public void afterPropertiesSet() throws Exception {
Endpoint endpoint = jaxRsServer.getEndpoint();
ServerProviderFactory serverProviderFactory = (ServerProviderFactory) endpoint.get("org.apache.cxf.jaxrs.provider.ServerProviderFactory");
if (serverProviderFactory != null) {
Field exceptionMappersField = ServerProviderFactory.class.getDeclaredField("exceptionMappers");
exceptionMappersField.setAccessible(true);
@SuppressWarnings("unchecked")
List<ProviderInfo<? extends ExceptionMapper<?>>> providerInfoList = (List<ProviderInfo<? extends ExceptionMapper<?>>>) exceptionMappersField.get(serverProviderFactory);
ProviderInfo<InvokeFailExceptionMapper> providerInfo = new ProviderInfo<>(new InvokeFailExceptionMapper(), serverProviderFactory.getBus(), true);
providerInfoList.add(providerInfo);
}
}
}
原理说明
1、多个异常处理器的决策。
org.apache.cxf.jaxrs.provider.ServerProviderFactory#createExceptionMapper
当发生异常时,会通过遍历exceptionMappers找出ExceptionMapper进行异常处理,同时会根据ExceptionMapper的实现类上的异常类型,根据业务方法抛出的异常找到最适合处理异常的ExceptionMapper的实现类,取第一个进行执行。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/180251.html