J'essaie de valider tous les fichiers XML entrants qui surviennent sur mon interface REST (contrat premier) dans une application exécutée dans JBoss AS 7. J'ai écrit un @Decorator pour Pretty- Impression (comme dans l'exemple de la documentation de JBoss RESTeasy) et analogue pour activer la validation de schéma XML pour unmarshaller. Malheureusement, le décorateur pour le unmarshaller n'est jamais appelé.JBoss RESTeasy Validation du schéma JAX-RS JAXB avec Decorator
Voici le code pour le décorateur Jolie:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.xml.bind.Marshaller;
import org.jboss.resteasy.annotations.Decorator;
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Decorator(processor = PrettyProcessor.class, target = Marshaller.class)
public @interface Pretty {}
Et la mise en œuvre:
import java.lang.annotation.Annotation;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import org.apache.log4j.Logger;
import org.jboss.resteasy.annotations.DecorateTypes;
import org.jboss.resteasy.spi.interception.DecoratorProcessor;
@DecorateTypes({ "text/*+xml", "application/*+xml", MediaType.APPLICATION_XML, MediaType.TEXT_XML })
public class PrettyProcessor implements DecoratorProcessor<Marshaller, Pretty> {
private static final Logger LOGGER = Logger.getLogger(PrettyProcessor.class);
@Override
public Marshaller decorate(Marshaller target, Pretty annotation, Class type, Annotation[] annotations, MediaType mediaType) {
LOGGER.debug("Pretty.");
try {
target.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
} catch (PropertyException e) {
}
return target;
}
}
Maintenant, l'annotation pour la validation (qui ne fonctionne pas):
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.xml.bind.Unmarshaller;
import org.jboss.resteasy.annotations.Decorator;
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Decorator(processor = ValidateProcessor.class, target = Unmarshaller.class)
public @interface Validate {}
La mise en œuvre:
import java.lang.annotation.Annotation;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import javax.xml.XMLConstants;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.apache.log4j.Logger;
import org.jboss.resteasy.annotations.DecorateTypes;
import org.jboss.resteasy.spi.interception.DecoratorProcessor;
import org.xml.sax.SAXException;
@DecorateTypes({ "text/*+xml", "application/*+xml", MediaType.APPLICATION_XML, MediaType.TEXT_XML })
public class ValidateProcessor implements DecoratorProcessor<Unmarshaller, Validate> {
private static final Logger LOGGER = Logger.getLogger(ValidateProcessor.class);
@Override
public Unmarshaller decorate(Unmarshaller target, Validate annotation, Class type, Annotation[] annotations, MediaType mediaType) {
target.setSchema(getSchema());
LOGGER.debug("Set validation schema.");
System.out.println("Set validation schema.");
return target;
}
}
Et le code de l'interface REST:
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.xml.ws.WebServiceException;
@Path("/{mdvt}/{ouid}/order")
public interface OrderResource {
@RolesAllowed({ "mpa" })
@POST
@Path("/update")
@Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
@Produces(MediaType.APPLICATION_XML)
@Pretty
public Response update(@Context SecurityContext sec,
@PathParam("ouid") String ouID,
@PathParam("mdvt") long masterDataVersionTag,
@Validate UpdateOrdersRequest uor) throws WebServiceException;
}
Sur la même méthode REST (mise à jour) le décorateur @Pretty est appelé alors que le @Validate ne l'est pas. Qu'est-ce que je fais mal ici?
J'ai trouvé un vieux bug Decorator for Jaxb unmarshaller doesn't work qui est fermé.
Les commentaires là-bas disent que tout fonctionne, et le code ci-dessus est presque exactement celui de là, y compris la solution. Néanmoins, rien ne fonctionne pour le Unmarshaller.
Oui, j'ai vu cette solution au cours de mes recherches pour le problème à portée de main. Pourtant, les décorateurs devraient travailler et apparemment ils ne le font pas. Le rapport de bogue que j'ai lié devrait être rouvert, à mon humble avis. Ecrire un MessageBodyReader fonctionnerait sûrement, mais à mes yeux c'est la mauvaise solution pour mon problème. Merci quand même pour la réponse rapide! – Frank