Reputation: 49
i use jaxws:client tag and spring for consuming webservices. In the above process, i want to use cxf interceptors before and after calling a webservice.
iam able to work with cxf interceptors with webservice returning proper soap fault and success response, but the inFaultInterceptor is not getting invoked in case of Http Status Code : 404 and also when the service is down...connect exception..
after analysing the error.. i found that exception is being thrown from the https://cxf.apache.org/javadoc/latest/org/apache/cxf/interceptor/MessageSenderInterceptor.MessageSenderEndingInterceptor.html
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.interceptor;
import java.io.IOException;
import java.util.ResourceBundle;
import org.apache.cxf.common.i18n.BundleUtils;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.transport.Conduit;
/**
* Takes the Conduit from the exchange and sends the message through it.
*/
public class MessageSenderInterceptor extends AbstractPhaseInterceptor<Message> {
private static final ResourceBundle BUNDLE = BundleUtils.getBundle(MessageSenderInterceptor.class);
private MessageSenderEndingInterceptor ending = new MessageSenderEndingInterceptor();
public MessageSenderInterceptor() {
super(Phase.PREPARE_SEND);
}
public void handleMessage(Message message) {
try {
getConduit(message).prepare(message);
} catch (IOException ex) {
throw new Fault(new org.apache.cxf.common.i18n.Message("COULD_NOT_SEND", BUNDLE), ex);
}
// Add a final interceptor to close the conduit
message.getInterceptorChain().add(ending);
}
public class MessageSenderEndingInterceptor extends AbstractPhaseInterceptor<Message> {
public MessageSenderEndingInterceptor() {
super(Phase.PREPARE_SEND_ENDING);
}
public void handleMessage(Message message) throws Fault {
try {
getConduit(message).close(message);
} catch (IOException e) {
throw new Fault(new org.apache.cxf.common.i18n.Message("COULD_NOT_SEND", BUNDLE), e);
}
}
}
private Conduit getConduit(Message message) {
Exchange exchange = message.getExchange();
Conduit conduit = exchange.getConduit(message);
if (conduit == null
&& (exchange.getOutMessage() != null
|| exchange.getOutFaultMessage() != null)) {
conduit = OutgoingChainInterceptor.getBackChannelConduit(message);
}
return conduit;
}
}
My Question: How to override this class in our project so that handleMessage of inner class can be customised ? i have to get control in the fault interceptor before cxf fault with could not send message is thrown...
Upvotes: 0
Views: 2795
Reputation: 39271
You can use a FaultListener added to CXF Bus. The listener will capture also the http exceptions (404 by example) allowing you to execute your code before they are raised to invoking method.
For example
public class CxfFaultListenerImpl implements FaultListener{
public boolean faultOccurred(final Exception exception,final String description,final Message message) {
//return false to avoid standard CXF logging of exception
return false;
}
}
Spring CXF configuration
<cxf:bus>
<cxf:properties>
<entry key="org.apache.cxf.logging.FaultListener">
<bean id="cxfFaultListener" class="CxfFaultListenerImpl" />
</entry>
</cxf:properties>
</cxf:bus>
Upvotes: 2