2013-05-08 59 views
4

我有一個JAXB的小問題,但不幸的是我無法找到答案。JAXB,如何驗證nillable和必要的字段解組時

我有一類客戶,有2場城市,映射使用註解來實現,並根據需要,而不是兩者的nillable字段標。

@XmlRootElement(name = "customer") 
public class Customer { 

    enum City { 
     PARIS, LONDON, WARSAW 
    } 

    @XmlElement(name = "name", required = true, nillable = false) 
    public String name; 
    @XmlElement(name = "city", required = true, nillable = false) 
    public City city; 

    @Override 
    public String toString(){ 
     return String.format("Name %s, city %s", name, city); 
    } 
} 

然而,當我提出這樣的XML文件:

<customer> 
    <city>UNKNOWN</city> 
</customer> 

我會收到與設置爲null兩個字段中的客戶實例。

不應該有一個驗證異常,或者我在映射中丟失了什麼?

來解組使用:

JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class); 
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
Customer customer = (Customer) unmarshaller.unmarshal(in); 

回答

4

您需要使用的模式來驗證。 JAXB不能自行進行驗證。

SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); 
Schema schema = sf.newSchema(ClassUtils.getDefaultClassLoader().getResource(schemaPath)); 
unmarshaller.setSchema(schema); 
2

您可以在運行時自動生成模式並將其用於驗證。 這將完成這項工作:

JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class); 
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
generateAndSetSchema(unmarshaller); 
Customer customer = (Customer) unmarshaller.unmarshal(in); 

private void generateAndSetSchema(Unmarshaller unmarshaller) { 

    // generate schema 
    ByteArrayStreamOutputResolver schemaOutput = new ByteArrayStreamOutputResolver(); 
    jaxbContext.generateSchema(schemaOutput); 

    // load schema 
    ByteArrayInputStream schemaInputStream = new ByteArrayInputStream(schemaOutput.getSchemaContent()); 
    SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
    Schema schema = sf.newSchema(new StreamSource(schemaInputStream)); 

    // set schema on unmarshaller 
    unmarshaller.setSchema(schema); 
} 

private class ByteArrayStreamOutputResolver extends SchemaOutputResolver { 

    private ByteArrayOutputStream schemaOutputStream; 

    public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException { 

     schemaOutputStream = new ByteArrayOutputStream(INITIAL_SCHEMA_BUFFER_SIZE); 
     StreamResult result = new StreamResult(schemaOutputStream); 

     // We generate single XSD, so generator will not use systemId property 
     // Nevertheless, it validates if it's not null. 
     result.setSystemId(""); 

     return result; 
    } 

    public byte[] getSchemaContent() { 
     return schemaOutputStream.toByteArray(); 
    } 
}