带有自定义注释的 Jaxb 编组 [英] Jaxb marshalling with custom annotations

查看:36
本文介绍了带有自定义注释的 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;

如果我在 jaxb 中转换时传递 version="v1" 参数,我只想用 v1 编组字段.如果我通过 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 也可以在包级别指定,但您必须指定它适用于哪些类型.如果不指定 @XmlJavaTypeAdapter,就不能使用 XmlAdapter.

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.

示例适配器(完整代码可在此处):

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天全站免登陆