Jaxb使用自定义注释进行编组 [英] Jaxb marshalling with custom annotations

查看:164
本文介绍了Jaxb使用自定义注释进行编组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要求,根据字段上标记的自定义注释来编组/取消编组java pojo的一些元素。
假设我的java pojp中有3个字段

I have a requirement, to marshall/unmarshall some elements of java pojo depending upon a custom annotation marked on the field. suppose there are 3 fields in my java pojp

@CustomVersion("v1")
private String field1;
@CustomVersion("v1","v2")
private String field2;
@CustomVersion("v2")
private String field3;

如果我在转换时传递version =v1参数,我只想用v1编组字段在jaxb。如果我通过v2,所有带v2注释的字段都应该被编组。

i would like to marshall only the fields with v1 if i pass version="v1" parameter while conversion in jaxb. if i pass v2, all fields with v2 annotation should only be marshalled.

甚至可以使用jaxb吗?我确信选择性编组将通过某些图书馆或方式得到支持,经过一番搜索后我仍然无法弄明白。
非常感谢任何帮助或建议或指示。

is that even possible using jaxb? i am sure selective marshalling would be supported through some library or way, am not still able to figure it out after quite some searching. any help or advice or pointers are highly appreciated.

推荐答案

首先,我建议在编组之前进行此类预处理。这会容易得多。但是,如果由于某种原因不可能,那么您可以创建自定义类型适配器。然后,您可以在要启用版本控制的每种类型上放置 @XmlJavaTypeAdapter(VersioningAdapter.class)
@XmlJavaTypeAdapter 也可以在包级别指定,但您必须指定它适用的类型。你不能使用 XmlAdapter 而不指定某处 @XmlJavaTypeAdapter

First of all I would suggest doing such preprocessing before marshalling. It would be much easier. However if it is not possible for some reason then you can create you custom type adapter. Then you can put @XmlJavaTypeAdapter(VersioningAdapter.class) on every type that you want to have versioning enabled. @XmlJavaTypeAdapter can also be specified on package level, but you have to specify to which types it applies. You cannot use XmlAdapter without specifying somewhere @XmlJavaTypeAdapter.

此类解决方案的缺点:


  • 如果您有多个版本化类型,则每个类型必须使用 @进行注释XmlJavaTypeAdapter

  • @XmlJavaTypeAdapter 不适用于根元素,仅适用于子元素。您必须在编组之前在根元素上手动调用适配器

  • if you have multiple versioned types then each of them has to be annotated with @XmlJavaTypeAdapter
  • @XmlJavaTypeAdapter does not work for root element, only on child elements. You have to call adapter manually on root element before marshalling

AFAIK没有其他选项可用于自定义JAXB编组。这就是为什么我认为注释处理应该在编组之前在单独的步骤中执行。除非你能接受上述限制。

AFAIK there is no other option for customizing JAXB marshalling. That's why I think that annotation processing should be performed in separate step before marshalling. Unless you can accept mentioned limitations.

示例适配器(可以找到完整的代码 here ):

Sample adapter (full code can be found here):

public class VersioningAdapter extends XmlAdapter<Object, Object> {

    @Override
    public Object unmarshal(Object v) throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object marshal(Object v) throws Exception {
        if (v == null) {
            return v;
        }
        Field[] fields = v.getClass().getDeclaredFields();
        for (Field field : fields) {
            Annotation[] annotations = field.getDeclaredAnnotations();
            CustomVersion annotation = findCustomVersion(annotations);
            if (annotation != null) {
                if (!contains(annotation, Configuration.getVersion())) {
                    field.setAccessible(true);
                    field.set(v, null);
                }
            }
        }
        return v;
    }

    private CustomVersion findCustomVersion(Annotation[] annotations) {
        for (Annotation annotation : annotations) {
            if (annotation instanceof CustomVersion) {
                return (CustomVersion) annotation;
            }
        }
        return null;
    }

    private boolean contains(CustomVersion annotation, String version) {
        String[] values = annotation.value();
        for (String value : values) {
            if (value.equals(version)) {
                return true;
            }
        }
        return false;
    }

}

这篇关于Jaxb使用自定义注释进行编组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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