简体   繁体   English

不能Marshal java.lang.String

[英]Can't Marshal java.lang.String

Here is my dilemma: 这是我的困境:

I have a dto class for marshaling back and forth from/to XML. 我有一个dto类,用于从/向XML来回编组。

Here is the trick: Because of the number of dto classes our project deals with that are collections with a plural outter tag, I decided to create a delegate collection that allows me to take one of these classes and effortlessly turn them into a Collection and get the convenience that comes with it (iteration, add, etc.). 这是诀窍:由于我们的项目处理的dto类的数量是具有复数outter标记的集合,我决定创建一个委托集合,允许我从其中一个类中轻松地将它们转换为Collection并获取随之而来的便利(迭代,添加等)。

In our project we have marshaling tests to flush out annotation errors and such. 在我们的项目中,我们有编组测试来清除注释错误等。 Below is my trouble code. 以下是我的故障代码。

Problem: Depending on the marshaler, if I extend this QuickCollection I get the below error. 问题:根据封送程序,如果我扩展此QuickCollection,我会收到以下错误。 When the object is unmarshaled to xml using CXF as a response to a webservice request, it fails. 当使用CXF将对象解组为x​​ml作为对Web服务请求的响应时,它将失败。 Exact error: com.sun.istack.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation 确切错误:com.sun.istack.SAXException2:无法封装类型“java.lang.String”作为元素,因为它缺少@XmlRootElement注释

When it's marshaled/unmarshaled with JAXB in test it's fine. 当它在测试中用JAXB进行编组/解组时它很好。 When This same QuickCollection is used to marshal in results from 3rd parties using spring RestOperations and works fine 当使用相同的QuickCollection来编组第三方使用spring RestOperations的结果并且工作正常

the mind screw: When I remove the inheritance and manage the collection as a private member it all just works! 心灵螺丝:当我删除继承并将集合作为私人成员管理时,一切正常!

This makes not a stitch of sense to me as I am literally returning the exact data type in both situations. 这对我来说不是一种感觉,因为我在两种情况下都会返回确切的数据类型。

Below is all relevant code. 以下是所有相关代码。

This is the Inherited delegate class. 这是Inherited委托类。

    public class QuickCollection<T> implements Collection<T> {
    // to be set if needed after instantiation. To behave like a normal collection, we set it to something safe
    protected Collection<T> delegate = Collections.emptySet();

    public QuickCollection() {
    }

    public QuickCollection(Collection<T> delegate) {
        this.delegate = delegate;
    }

    @Override
    public int size() {
        return delegate.size();
    }

    @Override
    public boolean isEmpty() {
        return delegate.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return delegate.contains(o);
    }

    @Override
    public Iterator<T> iterator() {
        return delegate.iterator();
    }

    @Override
    public Object[] toArray() {
        return delegate.toArray();
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return delegate.toArray(a);
    }

    @Override
    public boolean add(T t) {
        return delegate.add(t);
    }

    @Override
    public boolean remove(Object o) {
        return delegate.remove(o);
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return delegate.containsAll(c);
    }

    @Override
    public boolean addAll(Collection<? extends T> c) {
        return delegate.addAll(c);
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        return delegate.removeAll(c);
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return delegate.retainAll(c);
    }

    @Override
    public void clear() {
        delegate.clear();
    }

    @Override
    public String toString() {
        return "" + delegate.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        QuickCollection that = (QuickCollection) o;

        if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return delegate != null ? delegate.hashCode() : 0;
    }
}

Here is the child DTO class 这是儿童DTO课程

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "BuddyCodes")
@XmlRootElement(name = "BuddyCodes")
public class BuddyCodes extends QuickCollection<String> implements Xml {

    private Long accountId;

    private Date expirationDate;

    public BuddyCodes() {
        super.delegate = new HashSet<String>();
    }

    public BuddyCodes(Long accountId, Set<String> codes, Date expirationDate) {
        super(codes);
        this.accountId = accountId;
        this.expirationDate = expirationDate;
        super.delegate = new HashSet<String>();

    }

    public BuddyCodes(Long accountId, Date expirationDate) {
        this.accountId = accountId;
        this.expirationDate = expirationDate;
        super.delegate = new HashSet<String>();
    }

    @Override
    public String toXml() {
        String retVal;
        try {
            retVal = StringUtils.toXml(this);
        }
        catch (JAXBException e) {
            retVal = e.toString();
        }
        return retVal;

    }

    public Long getAccountId() {
        return accountId;
    }

    public void setAccountId(Long accountId) {
        this.accountId = accountId;
    }

    public Set<String> getCodes() {
        return (Set<String>) super.delegate;
    }

    @XmlElement(name = "code")
    public void setCodes(Set<String> codes) {
        super.delegate = codes;
    }

    public Date getExpirationDate() {
        return expirationDate;
    }

    public void setExpirationDate(Date expirationDate) {
        this.expirationDate = expirationDate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        BuddyCodes that = (BuddyCodes) o;

        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) return false;
        if (delegate != null ? !super.delegate.equals(that.delegate) : that.delegate != null) return false;
        if (expirationDate != null ? !expirationDate.equals(that.expirationDate) : that.expirationDate != null)
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = accountId != null ? accountId.hashCode() : 0;
        result = 31 * result + (expirationDate != null ? expirationDate.hashCode() : 0);
        result = 31 * result + (super.delegate != null ? super.delegate.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "BuddyCodes{" +
                "accountId=" + accountId +
                "codes=" + super.delegate +
                ", expirationDate=" + expirationDate +
                '}';
    }
}

And it doesn't work. 它不起作用。 I get the error. 我收到了错误。

Now, here is the child class after removing the inheritance and it works!!! 现在,这是删除继承后的子类,它的工作原理!

import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.*;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * @author christian.bongiorno
 *         Date: 10/3/11
 *         Time: 6:11 PM
 */
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "BuddyCodes")
@XmlRootElement(name = "BuddyCodes")
public class BuddyCodes implements Xml {

    private Long accountId;

    private Date expirationDate;
    private Set<String> delegate;
    public BuddyCodes() {
        delegate = new HashSet<String>();
    }

    public BuddyCodes(Long accountId, Set<String> codes, Date expirationDate) {
        this.accountId = accountId;
        this.expirationDate = expirationDate;
        delegate = new HashSet<String>();

    }

    public BuddyCodes(Long accountId, Date expirationDate) {
        this.accountId = accountId;
        this.expirationDate = expirationDate;
        delegate = new HashSet<String>();
    }

    @Override
    public String toXml() {
        String retVal;
        try {
            retVal = StringUtils.toXml(this);
        }
        catch (JAXBException e) {
            retVal = e.toString();
        }
        return retVal;

    }

    public Long getAccountId() {
        return accountId;
    }

    public void setAccountId(Long accountId) {
        this.accountId = accountId;
    }

    public Set<String> getCodes() {
        return delegate;
    }

    @XmlElement(name = "code")
    public void setCodes(Set<String> codes) {
        delegate = codes;
    }

    public Date getExpirationDate() {
        return expirationDate;
    }

    public void setExpirationDate(Date expirationDate) {
        this.expirationDate = expirationDate;
    }

    public boolean add(String s) {
        return delegate.add(s);
    }

    public int size() {
        return delegate.size();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        BuddyCodes that = (BuddyCodes) o;

        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) return false;
        if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;
        if (expirationDate != null ? !expirationDate.equals(that.expirationDate) : that.expirationDate != null)
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = accountId != null ? accountId.hashCode() : 0;
        result = 31 * result + (expirationDate != null ? expirationDate.hashCode() : 0);
        result = 31 * result + (delegate != null ? delegate.hashCode() : 0);
        return result;
    }


}

Why does the inheritance matter at all??? 为什么继承很重要?

I haven't figured this out but, I have another DTO in a similar layout (BuddyTypes BuddyType). 我没有想到这一点,但我有一个类似布局的另一个DTO(BuddyTypes BuddyType)。 BuddyType has 2 members: Long and String. BuddyType有2个成员:Long和String。 Both are annoted as XmlElement. 两者都被注释为XmlElement。 This one works just fine. 这个工作得很好。

It seems the problem that the members of the set making up the delegate are not annotated in my problem case and I don't know how to annotate a parent member. 似乎问题是组成委托的集合成员在我的问题案例中没有注释,我不知道如何注释父成员。 As an inherited class, it wouldn't make sense to have some sort of default name/annotation. 作为继承类,使用某种默认名称/注释是没有意义的。 But, I tried this madness and the annotation is ignored -- I have seen parent member annotations ignored before so this isn't new. 但是,我尝试了这种疯狂并且注释被忽略了 - 我之前看到父成员注释被忽略了所以这不是新的。

I don't know if it's possible, but I need to annotate a parent member. 我不知道是否可能,但我需要注释一个父成员。

A bit out of the box: try Simple XML library instead of JAXB. 开箱即用:尝试使用Simple XML库而不是JAXB。 My experience with it is the best. 我的经验是最好的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JAXB,Marshal的问题-无法封送类型“ java.lang.String” - Problems with JAXB, Marshal, - unable to marshal type “java.lang.String” JAXB,Marshal的问题, - 无法编组类型“java.lang.String” - Problems with JAXB, Marshal, - unable to marshal type “java.lang.String” 无法解析构造函数'SlideModel(java.lang.String, java.lang.String)'? - Can't Cannot resolve constructor 'SlideModel(java.lang.String, java.lang.String)'? DatabaseException:无法将java.Lang.String对象转换为类型 - DatabaseException: can't convert object of java.Lang.String to type java.lang.String无法转换为JSONObject - java.lang.String can't be converted to JSONObject JMS消息,由于缺少@XmlRootElement批注,因此无法将类型“ java.lang.String”作为元素封送 - JMS message, unable to marshal type “java.lang.String” as an element because it is missing an @XmlRootElement annotation 无法将java.lang.String字段设置为java.lang.String - Can not set java.lang.String field to java.lang.String 方法返回的Java类型不正确:无法将void值分配给java.lang.String - Java Incorrect type returned from method: Can't assign void value to java.lang.String java:不兼容的类型:T 无法转换为 java.lang.String - java: incompatible types: T cannot be converted to java.lang.String 在Gradle中使用Proguard - 找不到引用的类java.lang.String - Using Proguard in Gradle - can't find referenced class java.lang.String
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM