I'm trying to use BeanValidation feature of Apache CXF. And stuck now cause don't have any clue how to handle and parse exceptions thrown by validator. I have web-service interface:
@WebService
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT, use=SOAPBinding.Use.LITERAL, parameterStyle=SOAPBinding.ParameterStyle.BARE)
public interface TestWSInterface {
@WebMethod
@WebResult(name = "helloResponse")
@Valid
public Hello.Response hello(@WebParam(name = "helloRequest") @Valid Hello.Request request) throws TestWSException;
}
Hello.Request is annotated:
@XmlType(name = "HelloRequest")
public static class Request extends Command.Request {
@NotNull(message = "not null required")
@Size(min = 1, max = 5, message = "[1..5] characters")
public String name;
}
And following configuration in cfx-servlet.xml:
<jaxws:endpoint id="testWS" implementor="#test" address="/TestWS">
<jaxws:features>
<ref bean="commonValidationFeature"/>
</jaxws:features>
</jaxws:endpoint>
<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature"/>
So, then I run my request with SoapUI and pass name containing for example 6 characters, I have following response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Fault occurred while processing.</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
So my main question is - How can I catch ConstraintViolationException and extend resulting fault response with detailed messages from annotation constraint? Documentation from Apache CXF - Bean Validation Feature looks not very helpful for me. So I really in need for example.
I am facing the same issue and I fixed it using AbstractSoapInterceptor. To register your Custom Interceptor you have to add the following annotation to your web service.
@OutFaultInterceptors(interceptors = { "com.saqi.config.FaultInterceptor" })
After that, you have to write your custom FaultInterceptor as follows.
public class FaultInterceptor extends AbstractSoapInterceptor {
public FaultInterceptor() {
super(Phase.MARSHAL);
}
@Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
Fault fault = (Fault) soapMessage.getContent(Exception.class);
if (fault.getCause() != null && fault.getCause() instanceof ConstraintViolationException) {
ConstraintViolationException constraintViolationException = (ConstraintViolationException) fault.getCause();
if (!constraintViolationException.getConstraintViolations().isEmpty()) {
Set<ConstraintViolation<?>> constraintViolations = constraintViolationException
.getConstraintViolations();
for (ConstraintViolation constraintViolation : constraintViolations) {
fault.setMessage(constraintViolation.getMessage());
}
}
}
}
}
This will show your ConstraintViolationException messages as follows.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Id should follow the pattern!</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Note: I am using cxf version 3.1.6