我想驗證所有在JBoss AS 7內部運行的應用程序中通過我的(合同優先)REST接口傳入的XML文件。我寫了一個@Decorator for Pretty-打印(如JBoss RESTeasy文檔中的示例)以及用於切換unmarshaller的XML模式驗證的模擬類。不幸的是,unmarshaller的裝飾器從來沒有被調用過。JBoss RESTeasy使用裝飾器的JAX-RS JAXB架構驗證
下面是漂亮的裝飾代碼:
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 {}
和實現:
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;
}
}
現在標註的驗證(即不工作):
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 {}
實施:
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;
}
}
,其餘接口的代碼:
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;
}
同REST方法,(更新)@Pretty裝飾在@Validate沒有的時候被調用。我在這裏做錯了什麼?
我發現了一個已關閉的老bug Decorator for Jaxb unmarshaller doesn't work。
那裏的評論說,一切正常,上面的代碼幾乎就是那裏的代碼,包括解決方案。儘管如此,Unmarshaller沒有任何作用。
是的,我在研究手頭問題時已經看到了這個解決方案。儘管如此,裝飾者應該工作,看起來他們不。我已鏈接的錯誤報告應重新打開,恕我直言。編寫MessageBodyReader肯定會起作用,但在我看來,這是我的問題的錯誤解決方案。無論如何感謝您的快速回答! – Frank