我正在尝试使用Moxy的XML元数据扩展来映射以下界面。但是当我尝试加载它时,我收到以下错误。我无法将公共构造函数添加到AddressType
,因为它是枚举。
我的问题是:即使我没有在xml元数据中指定,为什么Moxy会查看AddressType
?
public interface TokenizedUnitedStatesAddress
{
class AddressType extends Enum
{
public static final AddressType STREET = new AddressType("street");
public static final AddressType PO_BOX = new AddressType("poBox");
public static final AddressType RURAL_ROUTE = new AddressType("ruralRoute");
public static AddressType getEnum(final String type)
{
return (AddressType) getEnum(AddressType.class, type);
}
protected AddressType(final String name)
{
super(name);
}
}
String getApartmentNumber();
//removed other getters for brevity
}
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_4.xsd"
version="2.4" package-name="com.abc.ic.domain.country.us">
<java-types>
<java-type name="TokenizedUnitedStatesAddress">
<xml-root-element />
<xml-type
prop-order="StreetPreDirection StreetNumber StreetName StreetType StreetPostDirection UnitDesignator UnitNumber AddressLine1 AddressLine2 City State PostalCode CarrierRoute LengthAtAddress OwnershipStatus" />
<java-attributes>
<xml-element name="StreetPreDirection" java-attribute="preDirectional" />
<xml-element name="StreetNumber" java-attribute="houseNumber" />
<xml-element name="StreetName" java-attribute="streetName" />
<xml-element name="StreetType" java-attribute="streetType" />
<xml-element name="StreetPostDirection" java-attribute="postDirection" />
<xml-element name="UnitNumber" java-attribute="apartmentNumber" />
<xml-element name="AddressLine1" java-attribute="primaryAddress" />
<xml-element name="AddressLine2" java-attribute="secondaryAddress" />
<xml-element name="City" java-attribute="cityName" />
<xml-element name="State" java-attribute="stateAbbreviation" />
<xml-element name="PostalCode" java-attribute="zipCode" />
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
javax.xml.bind.JAXBException:
Exception Description: The class com.abc.ic.domain.country.us.TokenizedUnitedStatesAddress$AddressType requires a zero argument constructor or a specified factory method. Note that non-static inner classes do not have zero argument constructors and are not supported.
- with linked exception:
[Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The class com.abc.ic.domain.country.us.TokenizedUnitedStatesAddress$AddressType requires a zero argument constructor or a specified factory method. Note that non-static inner classes do not have zero argument constructors and are not supported.]
at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:908)
at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:157)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:170)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:157)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:117)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:107)
答案 0 :(得分:1)
即使使用XML来提供元数据,Mxoy impl仍会对该类进行内省。这是因为,根据设计,外部映射文件用于增加注释提供的元数据。
然而问题是,commons-land Enum抽象要求我们为枚举设置一个非公共的单个参数构造函数。我通过添加一个初始化默认枚举的公共no-arg构造函数来修复此问题。这对我的申请来说已经足够了。然而,我创建了一个可以遵循here的错误。
注意:我还查看了foctory-method option of Moxy,但它需要一个空的arg方法作为工厂方法,而不是Enum的情况。
答案 1 :(得分:0)
我是EclipseLink MOXy团队的开发人员,我一直在研究这个问题。你是否正确地考虑了AddressType类的原因是正确的,我发现你有一个解决方法。
另一种解决方案是创建一个可以在Apache Enum类及其XML(字符串)表示形式之间进行转换的XmlAdapter,如下所示:
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.apache.commons.lang.enums.Enum;
import enumbindings.TokenizedUnitedStatesAddress.AddressType;
public class ApacheEnumAdapter extends XmlAdapter<String, Enum> {
public ApacheEnumAdapter() {
}
@Override
public Enum unmarshal(String s) throws Exception {
return AddressType.getEnum(s);
}
@Override
public String marshal(Enum e) throws Exception {
if (null == e) {
return null;
}
return e.getName();
}
}
然后在你的绑定文件中连接适配器,如下所示:
...
<xml-element name="StreetType" java-attribute="streetType">
<xml-java-type-adapter value="enumbindings.ApacheEnumAdapter" />
</xml-element>
...
就您输入的错误而言,EclipseLink实际上在这种情况下表现正常,我们不对Apache Commons类进行任何特殊处理,因此仍然需要默认的无参数构造函数(或其他一些处理机制)。但是,我会更新您的错误并将其更改为增强请求以支持开箱即用的Apache Enums,我们将对其进行评估。
谢谢,
瑞克