【问题标题】:Jaxb, Class has two properties of the same nameJaxb, Class 有两个同名属性
【发布时间】:2011-10-09 18:13:02
【问题描述】:

使用 jaxb,我尝试读取 xml 文件 xml 文件中只有几个元素很有趣,所以我想跳过很多元素

xml content

xml 我尝试阅读

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2010 rel. 3 sp1 (http://www.altova.com)-->
<flx:ModeleREP xsi:schemaLocation="urn:test:mod_rep.xsd mod_rep.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flx="urn:test:mod_rep.xsd">
<flx:DocumentHeader>
    <flx:Identification v="04489"/>
</flx:DocumentHeader>
<flx:TimeSeries>
    <flx:Identification v="test1a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="123a"/>
    <flx:ResourceObject codingScheme="N" v="testa"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
<flx:TimeSeries>
    <flx:Identification v="test2a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="a123b"/>
    <flx:ResourceObject codingScheme="N" v="test2"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
        <flx:Pt>
            <flx:P v="2"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
</flx:ModeleREP>

我的班级

@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {

  @XmlElement(name="TimeSeries")
  protected List<TimeSeries> timeSeries;

  public List<TimeSeries> getTimeSeries() {
  if (this.timeSeries == null) {
      this.timeSeries = new ArrayList<TimeSeries>();
  }
  return this.timeSeries;
  }

  public void setTimeSeries(List<TimeSeries> timeSeries) {
  this.timeSeries = timeSeries;
  }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TimeSeries")
public class TimeSeries {

@XmlElement(name="ResourceObject")
protected RessourceObject resourceObject;

@XmlElement(name = "Period")
protected Period period;

public RessourceObject getResourceObject() {
    return this.resourceObject;
}

public void setResourceObject(RessourceObject resourceObject) {
    this.resourceObject = resourceObject;
}

public Period getPeriod() {
    return this.period;
}

public void setPeriod(Period period) {
    this.period = period;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ResourceObject")

public class RessourceObject {
@XmlAttribute(name = "codingScheme")
protected String codingScheme;

@XmlAttribute(name = "v")
protected String v;

public String getCodingScheme() {
    return this.codingScheme;
}

public void setCodingScheme(String codingScheme) {
    this.codingScheme = codingScheme;
}

public String getV() {
    return this.v;
}

public void setV(String v) {
    this.v = v;
}
}

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "Period")
public class Period {

@XmlElement(name = "TimeInterval")
protected TimeInterval timeInterval;

@XmlElement(name = "Pt")
protected List<Pt> pt;

public TimeInterval getTimeInterval() {
    return this.timeInterval;
}

public void setTimeInterval(TimeInterval timeInterval) {
    this.timeInterval = timeInterval;
}

public List<Pt> getPt() {
    if (this.pt == null) {
    this.pt = new ArrayList<Pt>();
    }
    return this.pt;
}

public void setPt(List<Pt> pt) {
    this.pt=pt;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TimeInterval")
public class TimeInterval {

@XmlAttribute(name = "v")
private String timeIntervalPeriod;

public String getTimeIntervalPeriod() {
    return this.timeIntervalPeriod;
}

public void setTimeIntervalPeriod(String timeIntervalPeriod) {
    this.timeIntervalPeriod = timeIntervalPeriod;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Pt")
public class Pt {

@XmlElement(name = "P")
protected P p;

@XmlElement(name = "A")
protected A a;

public P getP() {
    return this.p;
}

public void setP(P p) {
    this.p = p;
}

public A getA() {
    return this.a;
}

public void setA(A a) {
    this.a = a;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "P")
public class P {
@XmlAttribute(name = "v")
protected String position;


public String getPosition(){
    return this.position;
}

public void setPosition(String position){
    this.position=position;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "A")
public class A {
@XmlAttribute(name = "v")
protected String calculatedAmount;

public String getCalculatedAmount() {
    return this.calculatedAmount;
}

public void setCalculatedAmount(String calculatedAmount) {
    this.calculatedAmount = calculatedAmount;
}
}

当我尝试读取我得到的 xlm 文件时 我明白了

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "timeSeries"
    this problem is related to the following location:
        at public java.util.List testjaxp.ModeleREP.getTimeSeries()
        at testjaxp.ModeleREP
    this problem is related to the following location:
        at protected java.util.List testjaxp.ModeleREP.timeSeries
        at testjaxp.ModeleREP

我不明白这个错误

编辑:我使用 jaxb-impl-2.1.12

好的,现在我没有任何错误,但是当我检查我的对象时,timeSeries 为空...

所以也许 jaxb 似乎对 flx 有问题?

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    您的 JAXB 正在查看 getTimeSeries() 方法和成员 timeSeries。你没有说你正在使用哪个 JAXB 实现,或者它的配置,但异常是相当清楚的。

    在公共 java.util.List testjaxp.ModeleREP.getTimeSeries()

    在受保护的 java.util.List testjaxp.ModeleREP.timeSeries

    您需要将 JAXB 配置为使用注释(根据您的 @XmlElement(name="TimeSeries"))并忽略公共方法。

    【讨论】:

    • 我已经这样做了:@XmlElement(name="TimeSeries") protected List timeSeries;
    • 我也将 (XmlAccessType.FIELD) 更改为 (XmlAccessType.NONE),我可以将 XmlElement 保留在成员级别
    • 我还需要将@XmlTransient 添加到变量中
    【解决方案2】:

    您没有指定您使用的是什么 JAXB-IMPL 版本,但是一旦我遇到同样的问题(使用 jaxb-impl 2.0.5)并使用 getter 级别的注释而不是在成员中使用它来解决它水平。

    【讨论】:

    • 这是正确的,我刚刚从成员中删除了注释并将其放在 setter 级别并且它起作用了。
    【解决方案3】:

    这是 JAXB 正在查看的两个属性。

    public java.util.List testjaxp.ModeleREP.getTimeSeries()  
    

    protected java.util.List testjaxp.ModeleREP.timeSeries
    

    这可以通过在 get 方法中使用 JAXB 注释来避免,如下所述。

    @XmlElement(name="TimeSeries"))  
    public java.util.List testjaxp.ModeleREP.getTimeSeries()
    

    【讨论】:

      【解决方案4】:

      您需要像使用 TimeSeries 一样配置 ModeleREP 类以及 @XmlAccessorType(XmlAccessType.FIELD)

      看看OOXS

      【讨论】:

        【解决方案5】:

        我也遇到过这样的问题,我设置了这个。

        @XmlRootElement(name="yourRootElementName")
        @XmlAccessorType(XmlAccessType.FIELD)
        

        这将工作 100%

        【讨论】:

        • 我遇到了同样的问题。甚至当我们只添加 @XmlAccessorType(XmlAccessType.FIELD) 时它也能工作
        • 我通过删除 @XmlAccessorType(XmlAccessType.FIELD) 注释解决了这个问题
        • 听起来很奇怪,但我也通过将注释对 \@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) 减少到只有 \@XmlRootElement 来摆脱这个异常
        • 在 JAXB 注解的内部类中遇到了同样的问题。将 @XmlAccessorType(XmlAccessType.FIELD) 放在内部类上有效!
        • 太棒了,非常感谢。结合龙目岛非常有帮助
        【解决方案6】:

        我刚刚遇到这个问题并解决了。

        问题的根源在于您同时拥有 XmlAccessType.FIELD 和成对的 getter 和 setter。解决方案是删除 setter 并添加一个默认构造函数和一个接受所有字段的构造函数。

        【讨论】:

        • 我遇到了同样的错误,你提到的注释解决了它,谢谢!
        【解决方案7】:

        我也见过一些类似的问题。

        我认为,这是因为我们在地方中使用了“@XMLElement注解 (bean) 类。

        我认为,当我们使用 @XMLElement 注释时,JAXB(注释处理器)将同一字段元素的成员字段和 getter 方法视为不同的属性在 field 级别并抛出 IllegalAnnotationExceptions 异常。

        异常信息:

        类有两个属性 相同 名称 "timeSeries"

        在 Getter 方法中:

            at public java.util.List testjaxp.ModeleREP.getTimeSeries()
        

        在会员领域:

            at protected java.util.List testjaxp.ModeleREP.timeSeries
        

        解决方案: 不要在 field 中使用 @XmlElement,而是在 getter 方法中使用它。

        【讨论】:

          【解决方案8】:

          使用@XmlTransient 进行注释可以解决该问题

          @XmlTransient
          public void setTimeSeries(List<TimeSeries> timeSeries) {
             this.timeSeries = timeSeries;
          }
          

          查看http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html了解更多详情

          【讨论】:

          • 我认为这更像是一种 hack 而不是解决方案。这告诉 jaxb 忽略该方法,而不是让它意识到这是同一件事。
          • Hack or not 这是最好的解决方案来解决不能被描述为任何错误的东西,我使用了@XmlAccessorType(XmlAccessType.FIELD),它大部分被忽略并添加了@XmlTransient到每个属性是修复这个问题的唯一方法。谢谢!
          【解决方案9】:

          我遇到了同样的问题,我添加了

          @XmlRootElement(name="yourRootElementName")
          
          @XmlAccessorType(XmlAccessType.FIELD)
          

          现在它正在工作。

          【讨论】:

            【解决方案10】:

            我有一个签名如下的服务类"

            @WebMethod
            public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {
            

            在运行时,FetchIQAStatusResponseVO 字段出现相同的错误。我刚刚在FetchIQAStatusResponseVO上面加了一行:

            @XmlAccessorType(XmlAccessType.FIELD) //This line added
            public class FetchIQAStatusResponseVO {
            

            这解决了问题。

            【讨论】:

              【解决方案11】:

              如果我们使用下面的注解并删除“@XmlElement”注解,代码应该可以正常工作并且生成的 XML 将具有类似于类成员的元素名称。

              @XmlRootElement(name="<RootElementName>")
              @XmlAccessorType(XmlAccessType.FIELD)
              

              如果确实需要使用“@XmlElement”,请将其定义为字段级别,代码应该可以正常工作。不要在 getter 方法的顶部定义注解。

              已经尝试了上述两种方法并解决了这个问题。

              【讨论】:

                【解决方案12】:

                只需在要转换为 XML 的类中将成员变量声明为私有。 快乐编码

                【讨论】:

                • 这应该是公认的解决方案。如果您将成员变量声明为 public,JABX 将解析它以及 getter/setter 注释方法并吐出异常。这是一个很好的例子,jabx 库设计者在反射上加倍努力,试图创造灵活性,最终促成了无效的配置。我自己解决了这个问题,当时只改了一行代码,回溯到成员变量。
                【解决方案13】:

                解决此问题的一种快速而简单的方法是将变量声明语句protected List&lt;TimeSeries&gt; timeSeries; 顶部的@XmlElement(name="TimeSeries") 删除到它的getter 顶部public List&lt;TimeSeries&gt; getTimeSeries()

                因此您的 ModeleREP 类将如下所示:

                @XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
                public class ModeleREP {
                
                
                  protected List<TimeSeries> timeSeries;
                
                  @XmlElement(name="TimeSeries")
                  public List<TimeSeries> getTimeSeries() {
                    if (this.timeSeries == null) {
                      this.timeSeries = new ArrayList<TimeSeries>();
                    }
                    return this.timeSeries;
                  }
                
                  public void setTimeSeries(List<TimeSeries> timeSeries) {
                    this.timeSeries = timeSeries;
                  }
                }
                

                希望对你有帮助!

                【讨论】:

                • 您提到“一种简单的方法”。很好奇,有没有其他方法可以解决这个问题 - 没有其他可以利用的注释吗?。
                【解决方案14】:

                “类有两个同名的属性异常”当你有一个具有公共访问级别的类成员 x 和一个相同的 getter/setter 时可能发生会员。

                作为 java 的经验法则,不建议将 public 访问级别与 getter 和 setter 一起使用。

                查看更多详情: Public property VS Private property with getter?

                解决这个问题:

                1. 将您成员的访问级别更改为私人并保留您的 getter/setter
                2. 移除成员的getter和setter

                【讨论】:

                  【解决方案15】:

                  刚刚添加到我的班级

                  @XmlAccessorType(XmlAccessType.FIELD)
                  

                  工作得像个混蛋

                  【讨论】:

                  • 也可以与 lombok 的 @Data 注释一起使用。
                  【解决方案16】:

                  当您将注释放在 getter 之前并将其从受保护的属性中删除时,它将起作用:

                  protected String codingScheme;
                  
                  @XmlAttribute(name = "codingScheme")
                  public String getCodingScheme() {
                      return this.codingScheme;
                  }
                  

                  【讨论】:

                  • 我也遇到了同样的问题。我也观察到,当注释被标记在属性上时,我看到了这一点。这是否意味着它应该始终放在 getter 之前?。
                  • @Pavan 是的,我想是的。否则,它会给我带来和你一样的问题
                  【解决方案17】:

                  有多种解决方案,但基本上,如果您在变量声明上进行注释,那么您需要 @XmlAccessorType(XmlAccessType.FIELD),但如果您更喜欢注释 get 或 set 方法,那么您不需要。

                  所以你可以这样做:

                  @XmlRootElement(name="MY_CLASS_A")
                  @XmlAccessorType(XmlAccessType.FIELD)
                  public class MyClassA
                  {
                      @XmlElement(name = "STATUS")   
                      private int status;
                     //.. and so on
                  }
                  

                  或者:

                  @XmlRootElement(name="MY_CLASS_A")
                  public class MyClassA
                  {
                      private int status;
                  
                      @XmlElement(name = "STATUS")         
                      public int getStatus()
                      {
                      }
                  }
                  

                  【讨论】:

                    【解决方案18】:

                    ModeleREP#getTimeSeries() 必须带有 @Transient 注释。这会有所帮助。

                    【讨论】:

                      【解决方案19】:

                      我进行了反复试验,得出的结论是,您只需使用@XMLElement@XmlAccessorType(XmlAccessType.FIELD) 中的任何一个即可。

                      什么时候用哪个?

                      case 1 : 如果你想在 xml 文件中使用的字段名和元素名不同,那么你必须使用@XMLElement(name="elementName")。因为这将绑定具有该元素名称的字段并显示在 XML 文件中。

                      案例 2 : 如果 xml 中的字段名称和相应的元素名称都相同,那么您可以简单地使用 @XmlAccessorType(XmlAccessType.FIELD)

                      【讨论】:

                        【解决方案20】:

                        已经给出了许多解决方案,@Sriram 和@ptomli 也简要介绍了内部结构。我只想添加一些对源代码的引用,以帮助了解幕后发生的事情。

                        默认情况下(即除了根类上的@XmlRootElement 之外,根本不使用额外的注释),JABX 尝试通过两种方式编组公开的内容:

                        1. 公开fields
                        2. getter methodsconvention 命名并具有相应的setter 方法。

                        注意如果一个字段是(或方法返回)null,它不会被写入输出。

                        现在如果使用@XmlElement,非公开的东西(可能是字段或getter方法)也可以编组。

                        但是这两种方式,即字段和getter方法,不能相互冲突。否则你会得到the exception

                        【讨论】:

                          猜你喜欢
                          • 2014-08-13
                          • 1970-01-01
                          • 2012-09-05
                          • 1970-01-01
                          • 2013-02-12
                          • 2015-12-11
                          • 1970-01-01
                          • 2014-08-13
                          • 2018-02-17
                          相关资源
                          最近更新 更多