Practical validation of JAXB data using JAX-RS?

We use the JAX-RS with some pretty basic POJO objects and have several annotated methods @GETand @POSTthat @Produceand @Consume MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML. Nothing impressive.

Question: how much better should I check the incoming data?

We do not have an XML schema, although I can create one. I would need to tie it in one way or another that doesn't look terribly attractive, and I have not yet found a brief example.

We could use bean validation, but again I'm not sure how I can connect it and call it.

Finally, I think that we could add some methods isValidForXXX()for the POJO object and call them whenever we have an instance passed to us.

Recommendations to anyone?

+5
source share
3 answers

If you have an XML schema, you can use JAXB validation internally MessageBodyReader. For a specific example, see My answer to a similar question.

ValidatingReader

Below is the implementation of the MessageBodyReaderbare bone, which performs four functions: 1) Create a JAXBContext, 2) Creates an instance Schema, 3) Sets the scheme to Unmarshaller4) Cancels the sign InputStream.

package org.example;

import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URL;

import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.*;
import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.validation.*;

@Provider
@Consumes("application/xml")
public class ValidatingReader implements MessageBodyReader<Customer> {

    @Context
    protected Providers providers;

    private Schema schema;
    private JAXBContext jaxbContext;

    public ValidatingReader() {
        try {
            JAXBContext jc = JAXBContext.newInstance(Customer.class);
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            URL schemaURL = null; // URL for your XML schema
            schema = sf.newSchema(schemaURL);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2, MediaType arg3) {
        return arg0 == Customer.class;
    }

    public Customer readFrom(Class<Customer> arg0, Type arg1, Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
            throws IOException, WebApplicationException {
        try {
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            unmarshaller.setSchema(schema);
            return (Customer) unmarshaller.unmarshal(arg5);
        } catch(JAXBException e) {
            throw new RuntimeException(e);
        }
    }

}
+2
source

, , . , , MessageBodyReader, , , HttpServletRequest , getInputStream .

@POST
@Path("/myPath")
@Consumes(MediaType.APPLICATION_XML)
public Response saveCustomerInteraction(@Context HttpServletRequest httpRequest) {

    Response response = null;
    try {
        CustomerInteraction ci = this.handleCustomerInteractionRequest(httpRequest);
        if (ci!=null){
            // save your data or whatever your app does
        }
        else {
            response = Response.status(Status.BAD_REQUEST).entity("invalid XML").build();               
        }
    }
    catch(Exception e){
        log.error(e.getMessage(),e);
        response = Response.serverError().entity(e.getMessage()).build();
    }
    return response;
}

handleCustomerInteractionRequest XML

protected CustomerInteraction handleCustomerInteractionRequest(HttpServletRequest request){

    CustomerInteraction ci = null;
    try {
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = sf.newSchema(schemaUrl);
        JAXBContext jaxbContext = JAXBContext.newInstance(CustomerInteraction.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        unmarshaller.setSchema(schema);
        ci = (CustomerInteraction) unmarshaller.unmarshal(request.getInputStream());    
    }
    catch (Exception e){
        // log error and return a null (or whatever you want to do with the error)
    }

    return ci;
} 
+1

MessageBodyReader @Blaise Doughan . , @Consumes Annotation JAXB- , , .

. , XML-, JAXB , ( ).

I would personally consider writing this XML schema, especially if your validation rules are easy to express. This can be a good investment for your project: you can automatically generate JAXB classes from now on and automatically receive confirmation so that you have the best maintainability in the future.

0
source

All Articles