2013-05-08 2 views
4

У меня есть небольшая проблема с JAXB, но, к сожалению, я не смог найти ответ.JAXB, как проверить допустимое и требуемое поле при разборке

У меня есть класс клиента, с 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> 

я буду получать экземпляр клиента с обоими полями, установленными в нуль.

Не должно быть исключения для проверки или мне что-то не хватает в сопоставлении?

Чтобы распаковать я использую:

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(); 
    } 
} 
Смежные вопросы