2011-09-27 50 views
5

我想驗證所有在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沒有任何作用。

回答

2

最後這個問題就解決了JBoss應用服務器7

問題在於RestEasy的實施是越野車,直到版本2.3.5.Final。

請參閱https://issues.jboss.org/browse/RESTEASY-711但忽略上述解決方法,直到版本2.3.5才能正常工作。

工作的解決方案是下載Restwasy配版2.3.5.Final以上,提取它,尋找resteasy-jboss-modules-2.3.5.Final.zip

提取該文件中的根JBoss AS 7.1.1和resteasy將會更新到新版本。完成這一步之後,上述所有代碼都可以正常工作。

感謝Bill Burke指點我的解決方案,

0

您可以實施MessageBodyReader,在JAXB Unmarshaller上設置Schema以執行驗證。示例代碼檢查出我的回答類似的問題:

+0

是的,我在研究手頭問題時已經看到了這個解決方案。儘管如此,裝飾者應該工作,看起來他們不。我已鏈接的錯誤報告應重新打開,恕我直言。編寫MessageBodyReader肯定會起作用,但在我看來,這是我的問題的錯誤解決方案。無論如何感謝您的快速回答! – Frank