no id
no id

Reputation: 1672

Server-side schema validation with JAX-WS

I have JAX-WS container-less service (published via Endpoint.publish() right from main() method). I want my service to validate input messages. I have tried following annotation: @SchemaValidation(handler=MyErrorHandler.class) and implemented an appropriate class. When I start the service, I get the following:

Exception in thread "main" javax.xml.ws.WebServiceException: 
Annotation @com.sun.xml.internal.ws.developer.SchemaValidation(outbound=true,
inbound=true, handler=class mypackage.MyErrorHandler) is not recognizable, 
atleast one constructor of class 
com.sun.xml.internal.ws.developer.SchemaValidationFeature 
should be marked with @FeatureConstructor

I have found few solutions on the internet, all of them imply the use of WebLogic container. I can't use container in my case, I need embedded service. Can I still use schema validation?

Upvotes: 1

Views: 12724

Answers (2)

Evandro Pomatti
Evandro Pomatti

Reputation: 15174

Old question, but I solved the problem using the correct package and minimal configuration, as well using only provided services from WebLogic. I was hitting the same problem as you.

Just make sure you use correct java type as I described here.

As I am planning to expand to a tracking mechanism I also implemented the custom error handler.

Web Service with custom validation handler

import com.sun.xml.ws.developer.SchemaValidation;

@Stateless
@WebService(portName="ValidatedService")
@SchemaValidation(handler=MyValidator.class)
public class ValidatedService {

    public ValidatedResponse operation(@WebParam(name = "ValidatedRequest") ValidatedRequest request) {

        /* do business logic */

        return response;
    }
}

Custom Handler to log and store error in database

public class MyValidator extends ValidationErrorHandler{

    private static java.util.logging.Logger log = LoggingHelper.getServerLogger();

    @Override
    public void warning(SAXParseException exception) throws SAXException {
        handleException(exception);
    }

    @Override
    public void error(SAXParseException exception) throws SAXException {
        handleException(exception);
    }

    @Override
    public void fatalError(SAXParseException exception) throws SAXException {
        handleException(exception);
    }

    private void handleException(SAXParseException e) throws SAXException {
        log.log(Level.SEVERE, "Validation error", e);
        // Record in database for tracking etc
        throw e;
    }
}

Upvotes: 3

joergl
joergl

Reputation: 2866

The @SchemaValidation annotation is not defined in the JAX-WS spec, but validation is left open. This means you need something more than only the classes in the jdk.

As long as you are able to add some jars to your classpath, you can set this up pretty easily using metro (which is also included in WebLogic. This is why you find solutions that use WebLogic as container.). To be more precise, you need to add two jars to your classpath. I'd suggest to

  1. download the most recent metro release.
  2. Unzip it somewhere.
  3. Add the jaxb-api.jar and jaxws-api.jar to your classpath. You can do this for example by putting them into the JAVA_HOME/lib/endorsed or by manually adding them to your project. This largely depends on the IDE or whatever you are using.

Once you have done this, your MyErrorHandler should work even if it is deployed via Endpoint.publish(). At least I have this setup locally and it compiles and works.

If you are not able to modify your classpath and need validation, you will have to validate the request manually using JAXB.

Upvotes: 4

Related Questions