我们希望使用 JAX-RS 和 JAXB 实现 RESTful Web 服务。我们有一个使用 xml 的 PUT 方法,如下所示:
<mailAccount>
<id>-1</id>
<name>test</name>
<mailaddress><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="126677616652757f6a3c7677" rel="noreferrer noopener nofollow">[email protected]</a></mailaddress>
<password>1234</password>
<servertype>IMAP</servertype>
<host>hallo</host>
<port>5678</port>
<encryption>SSL/TLS</encryption>
<authentication>true</authentication>
<interval>12</interval>
</mailAccount>
我们还有一个映射到 xml 的 MailAccount.class。
@XmlRootElement
public class MailAccount {
private String name;
private String mailaddress;
private String password;
private String servertype;
private String host;
private int port;
private String encryption;
private boolean authentication;
private int interval;
private int id;
getter + setter...
}
PUT 方法如下所示:
@PUT()
@Path("/addMailAccount")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.TEXT_HTML)
public Response addMailAccount(JAXBElement<MailAccount> mail) throws Exception{
MailAccount mailAccounts = mail.getValue();
StringWriter sw = new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(MailAccount.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(mailAccounts, sw);
String xmlConsume = sw.toString();
Source source = new StreamSource(new StringReader(xmlConsume));
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(MailAccountService.class.getResource("/emailAddresses.xsd"));
Validator validator = schema.newValidator();
//validator.validate(source);
return Response.status(200).entity(xmlConsume +"..."+ mailAccounts.getMailadress()).build();
}
我们的目标是编码 JAXB 元素以根据 XML 模式对其进行验证。但问题在于编码:首先,元素的顺序不正确。使用 propOrder 标签每次都会导致内部服务器错误。
第二个问题是元素“mailaddress”为空。它不是编码,当我将其放入此方法的响应中时,该值为 null。
以下是 PUT 方法返回的内容:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mailAccount>
<authentication>true</authentication>
<encryption>SSL/TLS</encryption>
<host>hallo</host>
<id>-1</id>
<interval>12</interval>
<name>test</name>
<password>1234</password>
<port>5678</port>
<servertype>IMAP</servertype>
</mailAccount>
...null
最佳答案
以下几项应该会有所帮助:
propOrder
下面是将 propOrder
应用于您的类的示例。请务必记住,您需要在 propOrder
中包含映射到 XML 元素的所有映射字段/属性。
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlType(propOrder={"id", "name", "mailaddress", "password", "servertype", "host", "port", "encryption", "authentication", "interval"})
@XmlAccessorType(XmlAccessType.FIELD)
public class MailAccount {
private String name;
private String mailaddress;
private String password;
private String servertype;
private String host;
private int port;
private String encryption;
private boolean authentication;
private int interval;
private int id;
}
将架构验证作为编码(marshal)操作的一部分
下面是一个独立的示例,演示了如何利用架构验证作为编码操作的一部分,而不是将其作为单独的操作进行(请参阅:http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html)。
import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.validation.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(MailAccount.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum20699078/input.xml");
MailAccount mailAccount = (MailAccount) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(MailAccountService.class.getResource("/emailAddresses.xsd"));
marshaller.setSchema(schema);
marshaller.marshal(mailAccount, System.out);
}
}
关于java - JAXB:JAXB 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20699078/