Hi,
Please check out https://issues.apache.org/jira/browse/CXF-6242.
This added the ability to customise the jaxb message that is thrown. By
default jaxb just throws the first event encountered, which may not be the
best one.
You need to implement org.apache.cxf.jaxb.MarshallerEventHandler and/or
org.apache.cxf.jaxb.UnmarshallerEventHandler, and register as message
properties:
JAXBDataBinding.WRITER_VALIDATION_EVENT_HANDLER -> for an Unmarshaller
JAXBDataBinding.READER_VALIDATION_EVENT_HANDLER -> for a marshaller
Here is an example we use in our internal project. Currently we replicate
most of what jaxb does, except we ignore null messages (which is what we
get by default from jaxb when jaxb encounters a invalid decimal). You
could enhance this even more to append all the jaxb events together to
return them.
See these sample jaxb interceptors:
public class JaxbValidationOutInterceptor extends
AbstractPhaseInterceptor<Message> {
public JaxbValidationOutInterceptor() {
super(Phase.MARSHAL);
addBefore(BareOutInterceptor.class.getName());
}
@Override
public void handleMessage(Message m) {
m.put(JAXBDataBinding.WRITER_VALIDATION_EVENT_HANDLER,
new JaxbValidationEventHandler());
}
}
public class JaxbValidationInInterceptor extends
AbstractPhaseInterceptor<Message> {
public JaxbValidationInInterceptor() {
super(Phase.UNMARSHAL);
addBefore(DocLiteralInInterceptor.class.getName());
}
@Override
public void handleMessage(Message m) {
m.put(JAXBDataBinding.READER_VALIDATION_EVENT_HANDLER,
new JaxbValidationEventHandler());
}
}
And the single class which implements both:
public class JaxbValidationEventHandler extends ValidationEventCollector
implements MarshallerEventHandler, UnmarshallerEventHandler {
@Override
public boolean handleEvent(ValidationEvent event) {
if (event.getSeverity() != ValidationEvent.WARNING) {
super.handleEvent(event);
}
return true;
}
@Override
public void onUnmarshalComplete() throws UnmarshalException {
if (hasEvents()) {
StringBuilder builder = getMessage();
throw new UnmarshalException(builder.toString());
}
}
@Override
public void onMarshalComplete() throws MarshalException {
if (hasEvents()) {
StringBuilder builder = getMessage();
throw new MarshalException(builder.toString());
}
}
private StringBuilder getMessage() {
StringBuilder builder = new StringBuilder();
for (ValidationEvent ev : getEvents()) {
if (ev.getMessage() != null) {
builder.append(ev.getMessage());
break; // only first not null message
}
}
return builder;
}
}
On Sat, Mar 21, 2015 at 4:30 AM, jamo <[email protected]> wrote:
> I'm working around this by using the interceptor, below, but all it
> provides
> is the line number and column number. I'm thinking it'd be reasonable to
> submit an enhancement request via the CXF jira.
>
> public class UnmarshallingFaultInterceptor extends FaultOutInterceptor {
> @Override
> public void handleMessage(Message message) throws Fault {
>
> Fault f = (Fault)message.getContent(Exception.class);
> if (f == null) {
> return;
> }
>
> Throwable cause = f.getCause();
> if (cause == null) {
> return;
> }
> String result=cause.toString();
>
> if (cause instanceof UnmarshalException && ((UnmarshalException)
> cause).getLinkedException() != null) {
> UnmarshalException un=(UnmarshalException) cause;
> String error = un.getLinkedException().toString();
> if (error.contains("lineNumber:")) {
> error="lineNumber:" +
> StringUtils.substringAfter(error,
> "lineNumber:");
> }
> result="Unable to parse invalid data: " + error;
> f.setMessage(result);
> }
>
>
> }
>
>
>
>
>
>
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Unmarshalling-error-content-usability-tp5755169p5755313.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>