首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@XmlPath(".")与@XmlAdapter冲突

@XmlPath(".")与@XmlAdapter冲突
EN

Stack Overflow用户
提问于 2015-01-04 11:36:11
回答 2查看 503关注 0票数 3

有了这个Jaxb定义之后,我尝试通过添加@XmlPath(".")来删除Map元素包装器,但是它会在取消标记过程中导致异常

代码语言:javascript
复制
@XmlRootElement
public abstract class ViewElement{
    @XmlJavaTypeAdapter(value=EventAdapter.class)   
    public Map<Event, String> getEvents() {     
    }
    private transient Class entityType;
    public Class getEntityType() {
        return entityType;
    }
}

而EventAdapter是

代码语言:javascript
复制
public class EventAdapter extends XmlAdapter<EventAdapter.AdaptedMap, Map<Event, String>> { 
    public static class AdaptedMap {
        @XmlVariableNode("key")
        List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
    }
    public static class AdaptedEntry {
        @XmlTransient
        public String key;
        @XmlValue
        public String value;
    }
    .....       
}

我的产出是

代码语言:javascript
复制
<element>
   <events>
      <onCellEdit>do some thing<onCellEdit>
   </events>
   <entityType>com.agitech.erp.model.erp.ErpFolder</entityType>
<element>

我试图通过添加<events>来删除@XmlPath(".")标记

代码语言:javascript
复制
@XmlPath(".")
@XmlJavaTypeAdapter(value=EventAdapter.class)   
public Map<Event, String> getEvents() {     
}

产量很好

代码语言:javascript
复制
<element>
   <onCellEdit>do some thing<onCellEdit>       
   <entityType>com.agitech.erp.model.erp.ErpFolder</entityType>
<element>

但是那些不受限制的失败

代码语言:javascript
复制
Caused by: Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.6.0.v20140809-296a69f): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[entityType-->view.entityType/text()]] with descriptor [XMLDescriptor(com.agitech.erp.view.BeanView --> [DatabaseTable(view), DatabaseTable(viewFrame), DatabaseTable(viewElement)])], could not be converted to [class java.lang.Class].
Internal Exception: java.lang.ClassNotFoundException: 
    at org.eclipse.persistence.exceptions.ConversionException.couldNotBeConvertedToClass(ConversionException.java:95)
    at org.eclipse.persistence.internal.helper.ConversionManager.convertObjectToClass(ConversionManager.java:446)

把Jaxb调试器带我去排队

代码语言:javascript
复制
org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue

public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
    ...
    line 205 unmarshalRecord.setAttributeValue(convertedValue, xmlDirectMapping);
}

在entityType值的取消标记过程中,UnmarshalRecordImpl.currentObj包含EventAdapter而不是父元素。

我修改org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl

代码语言:javascript
复制
public XPathNode getNonAttributeXPathNode(String namespaceURI, String localName, String qName, Attributes attributes) {
....
    if(null == resultNode && null == nonPredicateNode) {
        // ANY MAPPING
        resultNode = xPathNode.getAnyNode();
// by default it return the EventAdapter, changing it to NULL fix my problem
    }
....
}

不是一个安全的解决方案

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-09 21:12:01

我已经能够复制你看到的问题,但还没有找到原因。您可以使用以下bug跟踪此问题的进展情况:

  • http://bugs.eclipse.org/457169
票数 1
EN

Stack Overflow用户

发布于 2021-06-10 17:54:59

在尝试了很多事情之后,我找到了一个解决这个问题的方法。我也想在这里发同样的帖子,这样对将来的其他人是有帮助的。领导已经证实了问题大约5年前,但似乎他们没有解决它,我正面临着一个类似的问题。

基本上,我们可以使用beforeMarshalafterUnmarshal方法来更改字段中的值。

  1. 您需要使用List<Object>@XmlAnyElement(lax=true)以及Map<String,Object>创建字段Map<String,Object>
  2. 删除@XmlPath(".")XMLAdapter类。
  3. Map<String, Object>标记字段@XmlTransient

现在,在beforeMarshalafterMarshal字段中,您可以交换数据。在unmarshal in beforeunmarshal,期间,所有未知字段值都将出现在其上的List<Object>循环中,并将其添加到Map<String, Object>中。

类似地,在marshaling期间,您可以通过创建DOM元素将值Map<String, Object>移动到List<Object>

Marshaling所有的值都被添加到root中,因为DOM Elements是存在的,并且在Unmarshaling期间,已知值首先被读取,然后由于@XmlAnyElement而在List<Object>中存储-未知的值。

我已经使用Customer类创建了一个示例,您可以根据需要相应地修改它。

代码语言:javascript
复制
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement(name = "Customer")
@XmlType(name = "Customer", propOrder = {"name", "age", "otherElements"})
@XmlAccessorType(XmlAccessType.FIELD)
@Getter
@Setter
@AllArgsConstructor
@ToString
@NoArgsConstructor
public class Customer {
    @XmlTransient
    private String isA;
    private String name;
    private String age;

    @XmlAnyElement(lax = true)
    @JsonIgnore
    private List<Object> otherElements = new ArrayList<>();


    @JsonIgnore
    @XmlTransient
    private Map<String, Object> userExtensions = new HashMap<>();

    @JsonAnyGetter
    @JsonSerialize(using = CustomExtensionsSerializer.class)
    public Map<String, Object> getUserExtensions() {
        return userExtensions;
    }

    @JsonAnySetter
    public void setUserExtensions(String key, Object value) {
        userExtensions.put(key, value);
    }

    private void beforeMarshal(Marshaller m) throws ParserConfigurationException {
        System.out.println("Before Marshalling User Extension: " + userExtensions);
        ExtensionsModifier extensionsModifier = new ExtensionsModifier();
        otherElements = extensionsModifier.Marshalling(userExtensions);
        System.out.println("Before Marshalling Final Other Elements " + otherElements);
        userExtensions = new HashMap<>();
    }

    private void afterUnmarshal(Unmarshaller m, Object parent) throws ParserConfigurationException {
        System.out.println("After Unmarshalling : " + otherElements);
        ExtensionsModifier extensionsModifier = new ExtensionsModifier();
        userExtensions = extensionsModifier.Unmarshalling(otherElements);
        otherElements = new ArrayList();
    }
}

您可以在这里参考DOM ELEMENTS的创建:https://stackoverflow.com/a/24239105/7584240

你可以参考我的完整答案:https://stackoverflow.com/a/67923216/7584240

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27765087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档