0

JBOSS 7.x has the possibility to activate schema validation on the server side by means of using an @SchemaValidation annotation on the SEI.

However I would like to customize my errors as well. Moreover I would like to change the exception into a report (result).

I've found the following question / answer on Stack Overflow. Which explains how to setup a customized ValidationEventHanlder with CXF. However, JBOSS uses it own way deployment descriptors overriding the CXF ones. It is possible to achieve the same result as with the @Schemavalidation by means of the JBOSS web service deployment descriptor. However, I was not able yet to activate my own event handler.

I'm thinking about not throwing an exception, but storing the validation result in a HTTP header or in a ThreadLocal, in order to create my own result.

Questions:

1) Is it possible to setup a ValidationEventHander in JBOSS 7.x.x (or in JBOSS 6.x.x EAP)?

2) Is it possible to override the default exception (not throwing an exception on non-fatal errors, like ranges, formats etc?) and returning a result?

Thanks!

Community
  • 1
  • 1
Sjaak
  • 3,602
  • 17
  • 29

1 Answers1

0

JBOSS 7.x uses a concept called 'interceptors'. By defining an interceptor one can access the message context. There are 2 flavours of messsage contexts:

  1. The WebService Context that is available via the @Resource annotation in the Servlet or EJB
  2. The CXF WebService Context that is avialable to 'later interceptors' in the chain.

The latter one is available by menas of the setContextualProperty.

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.ValidationEvent;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class ValidatingInterceptor extends AbstractPhaseInterceptor<Message> {

    public static String CTX_KEY_VALIDATOR_EVENTS = "event_key";

    public ValidatingInterceptor() {
        super(Phase.READ);
    }

    @Override
    public void handleMessage(Message message) throws Fault {
        List<ValidationEvent> validationRes = new ArrayList<ValidationEvent>();
        message.put(CTX_KEY_VALIDATOR_EVENTS, validationRes);
        message.setContextualProperty("jaxb-validation-event-handler", new XmlValidationHandler(validationRes));
    }
}

Here is the validator that is inserted:

import java.util.List;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

public class XmlValidationHandler implements ValidationEventHandler {
    private final List<ValidationEvent> results;

    public XmlValidationHandler(List<ValidationEvent> results) {
        this.results = results;
    }

    @Override
    public boolean handleEvent(ValidationEvent event) {
        results.add(event);
        return true;
    }
}

The validator adds a List to the context described in 1. and is now available for further processing in the EJB or Servlet. The SEI then looks like this:

@SchemaValidation 
@InInterceptors(classes = {ValidatingInterceptor.class})
@Stateless
public class LogicBean implements SEI

Note: the @SchemaValidation is still required as annotation, since that triggers the annotation in the first place.

Sjaak
  • 3,602
  • 17
  • 29