2013-08-26 42 views
4

我在服務器端使用Jersey 1.17來處理REST請求,JAXB 2解組XML請求內容。指定Jersey中的JAXB 2上下文1.17

語境

這是新澤西方法我用。 MyDTO類使用@XmlRootElement註釋(否則,我需要使用JAXBElement類型定義參數)。

@Path("/myService") 
@POST 
@Consumes(MediaType.APPLICATION_XML) 
public void myService(MyDTO dto) throws Exception 
{    
    // Shouldn't get this far if the XML content in the request was invalid 
    System.out.println(dto); 
} 

要求

默認情況下,當XML的內容有錯誤了Sun/Oracle的JAXB實現不拋出異常。例如,爲一個Integer屬性提供一個字符串值,比如說ABC,只會將該值保留爲空值而不是拋出異常。

在JAXB 2中可以定義ValidationEvenHandler。使用以下處理程序處理程序,使得XML解組以特定方式拋出異常。

public class UnmarshallerValidationEventHandler implements ValidationEventHandler { 

     @Override 
     public boolean handleEvent(ValidationEvent event) { 
      // This indicates JAXB that it should continue processing only if the 
      // severity level is less than error. NOTE: validation event constants 
      // go in ascending order in level of severity(i.e., 0 WARNING, 1: ERROR, 2 :FATAL_ERROR) 
      return event.getSeverity() < ValidationEvent.ERROR; 
     } 

    } 

問題

我怎樣才能澤西島,以使用解組與我自定義的驗證事件處理程序使用特定的JAXBContext實例?

另外,由於我的應用程序只在Jersey方法中使用JAXB,因此爲JVM實例全局定義特定的JAXBContext將是一個不錯的選擇。這怎麼可能完成?

回答

3

Jersey用戶指南涵蓋了Using custom JAXBContext一章。基本上你需要提供ContextResolver<T>,如:

@Provider 
public class PlanetJAXBContextProvider implements ContextResolver<JAXBContext> { 
    private JAXBContext context = null; 

    public JAXBContext getContext(Class<?> type) { 
     if(type != Planet.class) 
      return null; // we don't support nothing else than Planet 

     if(context == null) { 
      try { 
       context = JAXBContext.newInstance(Planet.class); 
      } catch (JAXBException e) { 
       // log warning/error; null will be returned which indicates that this 
       // provider won't/can't be used. 
      } 
     } 
     return context; 
    } 
} 

你可以看到storage-service樣本項目(見JAXBContextResolver)樣本使用。

注:相反ContextResolver<JAXBContext>你也可以提供ContextResolver<Marshaller>和/或ContextResolver<Unmarshaller>