Jersey 将继承的属性序列化两次

发布于 2024-10-21 08:31:33 字数 829 浏览 4 评论 0 原文

我有一个没有任何注释的java bean。我有一个从这个 bean 继承的带有 JAXB 注释的类。

Jersey (JAX-RS) 将第二个类序列化为 JSON。继承的属性在 JSON 中出现两次:名称来自 XmlElement 注释,以及 java-bean 属性的“驼峰式”名称。下面的代码说明了这一点:

class MyBean {

   private Integer beanField;

   public Integer getBeanField() { return beanField; }

   public void setBeanField(Integer value) { this.beanField = value; }

}

@XmlRootElement
class AnnotatedBean extends MyBean {

  @Override
  @XmlElement(name="field")
  public Integer getBeanField() { return super.getBeanField(); }
}

}

序列化后,我得到下一个 JSON:(

{ 
   "field" : 5,
   "beanField" : 5
}

虽然我希望它只包含一个名为 field 的字段)。

我研究了 JAXB 编组器实现,发现它编组了给定类的所有超类的属性(这意味着在我的示例中不可能摆脱奇怪的 beanField 属性)。

但我还是希望我能错过一些东西。有没有办法只序列化带注释的属性?

I have a java bean without any annotations. And I have a class inherited from this bean with JAXB annotations.

Jersey (JAX-RS) serialize the second class to JSON. And inherited properties occur in JSON twice: with name from XmlElement annotation and with 'camel-case' name of java-bean property. Here is a code which illustrates this:

class MyBean {

   private Integer beanField;

   public Integer getBeanField() { return beanField; }

   public void setBeanField(Integer value) { this.beanField = value; }

}

@XmlRootElement
class AnnotatedBean extends MyBean {

  @Override
  @XmlElement(name="field")
  public Integer getBeanField() { return super.getBeanField(); }
}

}

After serialization I get the next JSON:

{ 
   "field" : 5,
   "beanField" : 5
}

(while I want it to contain only one field with name field).

I investigated JAXB marshaller implementation and found that it marshals properties from all superclasses of the given class (and that means that it's impossible to get rid of the odd beanField property in my example).

But I still hope that I could miss something. Is there a way to serialize only annotated properties?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独留℉清风醉 2024-10-28 08:31:33

要仅获取带注释的属性,请使用 XmlAccessType.NONE:

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
class AnnotatedBean extends MyBean {
    ...
}

使用外部化元数据映射第 3 方类

您可以使用 EclipseLink JAXB (MOXy) 中的外部元数据扩展,我是技术主管。它允许您为第三方类提供元数据。对于此示例,元数据如下所示:

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="third.party.package">
    <java-types>
        <java-type name="MyBean" xml-transient="true"/>
    </java-types>
</xml-bindings>

要使用 MOXy,您需要在模型类中添加一个名为 jaxb.properties 的文件,其中包含以下条目:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

以下文章提供了有关配置 MOXy 以与 Jersery 配合使用的说明:

Context Resolver - 利用元数据

您需要使用 ContextResolver 来让您的 JAXBContext 利用外部绑定文件。实例化 JAXBContext 时通过属性指定元数据:

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Produces;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextFactory;

@Provider
@Produces({"application/xml", "application/json"})
public class AnnotatedBeanContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext jaxbContext;

    public PurchaseOrderContextResolver() {
        try {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/blog/bindingfile/binding.xml"));
        jaxbContext = JAXBContext.newInstance(new Class[] {AnnotatedBean.class}, properties);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public JAXBContext getContext(Class<?> clazz) {
        if(AnnotatedBean.class == clazz) {
            return jaxbContext;
        }
        return null;
    }

}

To get only the annotated properties use XmlAccessType.NONE:

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
class AnnotatedBean extends MyBean {
    ...
}

Mapping the 3rd Party Class Using Externalized Metadata

You could use the external metadata extension in EclipseLink JAXB (MOXy), I'm the tech lead. It allows you to provide metadata for 3rd party classes. For this example the metadata will look like:

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="third.party.package">
    <java-types>
        <java-type name="MyBean" xml-transient="true"/>
    </java-types>
</xml-bindings>

To use MOXy you need to add a file named jaxb.properties in with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

The following article has instructions on configuring MOXy to work with Jersery:

Context Resolver - Leveraging the Metadata

You would need to use a ContextResolver to get your JAXBContext to leverage the external bindings file. The metadata is specified through a property when the JAXBContext is instantiated:

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Produces;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContextFactory;

@Provider
@Produces({"application/xml", "application/json"})
public class AnnotatedBeanContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext jaxbContext;

    public PurchaseOrderContextResolver() {
        try {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/blog/bindingfile/binding.xml"));
        jaxbContext = JAXBContext.newInstance(new Class[] {AnnotatedBean.class}, properties);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    public JAXBContext getContext(Class<?> clazz) {
        if(AnnotatedBean.class == clazz) {
            return jaxbContext;
        }
        return null;
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文