如何自定义 Jersey JAXB 序列化的 XML 输出 [英] How to customise the XML output of a Jersey JAXB serialisation

查看:23
本文介绍了如何自定义 Jersey JAXB 序列化的 XML 输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 @javax.xml.bind.annotation.Xml... 带注释的类,用于 REST Web 服务.Jersey 设置在 Spring 管理的 Web 容器中,并且 Web 服务返回格式良好的 xml.我们使用 maven-enunciate-plugin 来记录 Web 服务并为返回的 xml 文档创建 xsd.我现在想将文档 xsd 文件用作返回的 xml 文件中的 schemaLocation,以便 xml 验证不会抱怨缺少定义.如何获得为此配置的 XML 序列化?

I have some @javax.xml.bind.annotation.Xml... annotated classes here intended for a RESt web service. Jersey is setup in a spring managed web container and the web service is returning a well formatted xml. We use the maven-enunciate-plugin to document the web service and create the xsd to the returned xml documents. I now would like to use the documentation xsd file as a schemaLocation within the returned xml file so that the xml validation won't complain about missing definions. How can I get the XML serialisation configured for this?

推荐答案

如果我没记错的话,我必须做一些事情才能将命名空间标识符正确写入生成的 XML.

If I remember correctly, I had to do a few of things to get namespace identifiers properly written into my generated XML.

1) 创建了一个 JaxbFactory,它配置并返回一个自定义编组器(顺便说一句,解组器也是如此).我省略了下面的 getters/and unmarshalling 设置...

1) Created a JaxbFactory that configs and returns a custom marshaller (and unmarshaller, too, BTW). I'm omitting the getters/and unmarshalling setup below...

//constructor
public JaxbFactory() throws Exception {
    context = JAXBContext.newInstance(ResourceDto.class);

    // Setup the marshaller
    marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, XmlMetadataConstants.XML_SCHEMA_LOCATION);  // this schema location is used in generating the schema-location property in the xml
}

2) 该工厂类对泽西岛不可见".为了使其可见,我创建了一个 MarshallerProvider.看起来像这样:

2) That factory class isn't "visible" to Jersey. To make it visible, I create a MarshallerProvider. That looks something like this:

@Provider
public class ResourceJaxbMarshallerProvider implements ContextResolver<Marshaller> {
// injected by Spring
private ResourceJaxbFactory ResourceJaxbFactory;
private ResourceStatusJaxbFactory ResourceStatusJaxbFactory;


/*
 * ----------------------------------------
 * Setters (for Spring injected properties)
 * ----------------------------------------
 */
public void setResourceJaxbFactory(ResourceJaxbFactory ResourceJaxbFactory) {
    this.ResourceJaxbFactory = ResourceJaxbFactory;
}

public void setResourceStatusJaxbFactory(ResourceStatusJaxbFactory ResourceStatusJaxbFactory) {
    this.ResourceStatusJaxbFactory = ResourceStatusJaxbFactory;
}

/*
 * ------------------------
 * Interface Implementation
 * ------------------------
 */
public Marshaller getContext(Class<?> type) {
    if (type == ResourceDto.class)
        return ResourceJaxbFactory.getMarshaller();
    else if (type == ResourceStatusDto.class)
        return ResourceStatusJaxbFactory.getMarshaller();
    else
        return null;
}       
}

我已经使用 Jersey/Spring Servlet 将 Jersey 连接到 Spring,因此由 Spring 创建的任何 @Provider 类都会被 Jersey 自动识别.在我的 Spring applicationContext.xml 中,我所要做的就是实例化资源提供者.反过来,它会从工厂抢走 marshaller.

I've got Jersey wired into Spring using the Jersey/Spring Servlet so any @Provider class that gets created by Spring is automatically recognized by Jersey. In my Spring applicationContext.xml all I have to do is instantiate the resource provider. It will, in turn, go grab the marshaller from the factory.

3) 我发现关键的另一件事是我必须在包含我的资源的根包中创建一个 package-info.java 文件.看起来像这样:

3) The other thing that I found critical was that I had to create a package-info.java file in the root package containing my resource. Looks like this:

/*
 * Note that this file is critical for ensuring that our ResourceDto object is
 * marshalled/unmarshalled with the correct namespace.  Without this, marshalled
 * classes produce XML files without a namespace identifier
 */
@XmlSchema(namespace = XmlMetadataConstants.XML_SCHEMA_NAMESPACE, elementFormDefault = XmlNsForm.QUALIFIED) 
package com.yourcompany.resource;

import javax.xml.bind.annotation.XmlNsForm;

<小时>

至少我认为这是我需要做的所有事情,我不记得每一个片段.我确实记得 package-info.java 是最后一个关键的齿轮,它把它们结合在一起.


At least I think that's everything I needed to do, I can't remember every single piece. I do remember that the package-info.java piece was the last critical cog that made it all come together.

希望对您有所帮助.我花了太多时间来挖掘这一切的信息.在我希望它进行正确的 xml 模式验证(以及对模式无效输入的体面错误报告)之前,Jersey 非常简单.一旦我开始走这条路,泽西就从脑残容易变成了体面的困难.大部分困难是从网上各种帖子中找出所有细节.希望这将帮助您走得更远,更快.:-)

Hope that helps. I spent wayyyy too much time digging for the info on all this. Jersey was seductively simple before I wanted it to do proper xml schema validation (and decent error reporting for schema-invalid input). Once I started down that road Jersey went from brain-dead easy to decently hard. The majority of that difficulty was sussing out all the details from the variety of posts online. Hopefully this will help get you farther, quicker. :-)

这篇关于如何自定义 Jersey JAXB 序列化的 XML 输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆