gpt4 book ai didi

java - 将异常从 CXF 拦截器传播到异常映射器

转载 作者:搜寻专家 更新时间:2023-11-01 02:04:28 30 4
gpt4 key购买 nike

我有一个流程,在 CXF 客户端上我有 jaxrs-in-interceptor、provider 和 exception mapper。在我的例子中,我通过拦截器捕获了来自客户端的不良响应,然后我想中止 cxf 总线链并抛出错误。不幸的是我做不到,因为在每种情况下都只记录从拦截器抛出的异常,但主要错误(错误的 json 格式)会传播到异常映射器。我想避免异常映射器,但我不知道如何。我正在使用 WebClient 来实现这样的拦截器:

@Component
public class MyInterceptor extends AbstractPhaseInterceptor<Message> {

public MyInterceptor() {
super(POST_STREAM);
}

@Override
public void handleMessage(Message message) throws Fault {
if (message != null) {
//message.getExchange().setOneWay(true);
//message.getExchange().put(Exception.class, new MyException());
//message.getInterceptorChain().abort();
//message.setContent(Exception.class, new MyException());
//Endpoint ep = message.getExchange().get(Endpoint.class);
//message.getInterceptorChain().abort();
//if (ep.getInFaultObserver() != null) {
// ep.getInFaultObserver().onMessage(message);
//}
//throw new WebApplicationException( new MyException());

//message.setContent(Response.class, response);
throw new Fault(new MyException());
}
}

我读到我应该实现 jaxrs-filter,因为拦截器抛出的异常不会传播到异常映射器。由于 WebClient 的实现,是否有任何方法可以在 Java 中做到这一点?

S client = create(url, clazz, list(jsonProvider(), providers));
WebClient.getConfig(client).getInInterceptors().add(new MyInterceptor());

我也尝试过在拦截器上使用不同的阶段,但它也没有用。

最佳答案

我一直在研究和测试您的问题。问题是 CXF 拦截器抛出的异常逃脱了 JAX-RS 流(CXF 团队的 see the answer)

拦截器生成的Fault可以在拦截器本身实现handleFault时被捕获

 public void handleFault(Message message) {
Exception e = message.getContent(Exception.class);
}

或者实现一个FaultListener并在CXF Bus上注册

WebClient.getConfig(client).getBus().getProperties().put("org.apache.cxf.logging.FaultListener",new MyFaultListener());

public class MyFaultListener implements FaultListener{
public boolean faultOccurred(final Exception exception,final String description,final Message message) {
//return false to avoid warning of default CXF logging interceptor
return false;
}
}

但您不能从拦截器返回自定义响应或向客户端响应 Fault。

我发现实现所需行为的解决方法包括将 Response 替换为自定义对象,该对象可以由您通常的方法调用处理,例如 exceptionMapper参见 CXF/ JAX-RS : Return Custom response from interceptor

Interceptor.handleMessage 中检查您需要的条件并创建具有自定义状态和实体的 Response。在此之后,停止链

public class MyInterceptor extends AbstractPhaseInterceptor<Message> {

public MyInterceptor() {
super(Phase.POST_STREAM);
}

@Override
public void handleMessage(Message message) throws Fault {
if (message != null) {
//check the condition to raise the error
//build the custom Response replacing service call
Response response = Response
.status(Response.Status.BAD_REQUEST)
.entity("custom error")
.build();
message.getExchange().put(Response.class, response);

//abort interceptor chain in you want to stop processing or throw a Fault (catched by handleFault)
//message.getInterceptorChain().abort();
//throw new Fault (new MyException());

}

public void handleFault(Message messageParam) {
}
}

在创建 JAXRS 客户端时添加 ResponseExceptionMapper 作为提供者

providers.add(new ResponseExceptionMapper<WebApplicationException>() {

@Override
public WebApplicationException fromResponse(Response r) {
return new WebApplicationException(r);
}

});

YourService proxy = JAXRSClientFactory.create(url, clazz,providers);
Client client = WebClient.client(proxy);
WebClient.getConfig(client).getInInterceptors().add(new MyInterceptor());

在此之后,如果完成拦截器检查,调用 proxy.yourService() 将引发 WebApplicationException。您可以以所需的方式捕获或重新抛出

try{
proxy.yourService();
}catch (WebApplicationException e){
}

希望对你有帮助

关于java - 将异常从 CXF 拦截器传播到异常映射器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37984617/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com