gpt4 book ai didi

java - 如何使用 MessageBodyReader 读取对象集合

转载 作者:太空宇宙 更新时间:2023-11-04 06:25:52 26 4
gpt4 key购买 nike

我有某种类型的 XSD 架构,我们将其命名为 A。

然后我尝试使用 XSD 架构验证编写 MessageBodyReader - 如果我在那里传递单个对象,它就可以工作。但我怎样才能让它读取这些类型的集合呢?

我稍后使用该读取器作为 REST 服务的输入参数,并将其注册到 javax.ws.rs.core.Application 中。

@Provider
@Produces(MediaType.APPLICATION_XML)
public class AReader implements MessageBodyReader < A >
{
private static final String XSD = "/a.xsd";

@Override
public boolean isReadable(Class < ? > type, Type genericType, Annotation[] arg2, MediaType mediaType)
{
return MediaType.APPLICATION_XML_TYPE.equals(mediaType) && A.class.isAssignableFrom(type);
}

@Override
public AreadFrom(Class < A> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap < String, String > httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException
{

try
{
JAXBContext jaxbContext = JAXBContext.newInstance(A.class);
try
{
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

unmarshaller.setSchema(getSchema());

try
{
return (A) unmarshaller.unmarshal(entityStream);
}
catch (JAXBException e)
{
throw new RuntimeException(e);
}
}
catch (SAXException e)
{
throw new RuntimeException(e);
}

}
catch (JAXBException e)
{
throw new RuntimeException(e);
}

}

private Schema getSchema() throws SAXException
{
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

Schema schema = schemaFactory.newSchema(A.class.getResource(XSD));
return schema;
}

最佳答案

所以事情是这样的。 XML 文档必须有一个根元素,因此您不能只发送类似

<domain></domain>
<domain></domain>

您需要将其包装在另一个根元素中,例如

<domains>
<domain></domain>
<domain></domain>
</domains>

话虽这么说,xsd 架构还需要反射(reflect)其他根元素。你不能只拥有 <domain>已定义元素并期望根据 <domains> 进行验证.

一旦你把它放在你的xsd中,就像这样

<xsd:element name="domains">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="domain" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="domain">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:int"/>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

然后我们就可以制作 Domains包装类,以及 Domain

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Domain {

@XmlElement
private int id;
@XmlElement
private String name;
// Getters and Setters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Domains {

@XmlElementRef(name = "domain")
private List<Domain> domains;
// Getter and Setters
}

然后我们可以创建MessageBodyReader接受 DomainsDomain类型。类似的东西

@Provider
@Consumes(MediaType.APPLICATION_XML)
public class DomainMessageBodyReader implements MessageBodyReader {
private static final String XSD_PATH = "path/to/domains.xsd";

@Context
private Providers providers;
private Schema schema;

public DomainMessageBodyReader() {
try {
initSchema();
} catch (Exception ex) {
Logger.getLogger(DomainMessageBodyReader.class.getName())
.log(Level.SEVERE, null, ex);
throw new InternalServerErrorException();
}
}

private void initSchema() throws Exception {
SchemaFactory factory
= SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
schema = factory.newSchema(new File(XSD_PATH));
}

@Override
public boolean isReadable(Class type, Type type1,
Annotation[] antns, MediaType mt) {
return type == Domain.class || type == Domains.class;
}

@Override
public Object readFrom(Class type, Type type1, Annotation[] antns,
MediaType mt, MultivaluedMap mm, InputStream in)
throws IOException, WebApplicationException {
try {

JAXBContext context = JAXBContext.newInstance(Domains.class,
Domain.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(schema);
return unmarshaller.unmarshal(in);
} catch (JAXBException ex) {
throw new InternalServerErrorException();
}
}
}

注意Providers我没有使用它,但您可能想检查Providers中已存在的上下文。在跳转创建一个新的之前。如果没有,那么您可以创建一个新的。

所以有了这个MessageBodyReader ,您的 JAX-RS 资源方法是否接受 Domains ( <domains> ) 或 Domain ( <domain> ),它将通过此​​读取器,并将其发送到正确的资源方法。

关于java - 如何使用 MessageBodyReader 读取对象集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26800314/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com