有了这个Jaxb定义之后,我尝试通过添加@XmlPath(".")来删除Map元素包装器,但是它会在取消标记过程中导致异常
@XmlRootElement
public abstract class ViewElement{
@XmlJavaTypeAdapter(value=EventAdapter.class)
public Map<Event, String> getEvents() {
}
private transient Class entityType;
public Class getEntityType() {
return entityType;
}
}而EventAdapter是
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;
}
.....
}我的产出是
<element>
<events>
<onCellEdit>do some thing<onCellEdit>
</events>
<entityType>com.agitech.erp.model.erp.ErpFolder</entityType>
<element>我试图通过添加<events>来删除@XmlPath(".")标记
@XmlPath(".")
@XmlJavaTypeAdapter(value=EventAdapter.class)
public Map<Event, String> getEvents() {
}产量很好
<element>
<onCellEdit>do some thing<onCellEdit>
<entityType>com.agitech.erp.model.erp.ErpFolder</entityType>
<element>但是那些不受限制的失败
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调试器带我去排队
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
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
}
....
}不是一个安全的解决方案
发布于 2015-01-09 21:12:01
我已经能够复制你看到的问题,但还没有找到原因。您可以使用以下bug跟踪此问题的进展情况:
发布于 2021-06-10 17:54:59
在尝试了很多事情之后,我找到了一个解决这个问题的方法。我也想在这里发同样的帖子,这样对将来的其他人是有帮助的。领导已经证实了问题大约5年前,但似乎他们没有解决它,我正面临着一个类似的问题。
基本上,我们可以使用beforeMarshal和afterUnmarshal方法来更改字段中的值。
List<Object>和@XmlAnyElement(lax=true)以及Map<String,Object>创建字段Map<String,Object>。@XmlPath(".")和XMLAdapter类。Map<String, Object>标记字段@XmlTransient。现在,在beforeMarshal和afterMarshal字段中,您可以交换数据。在unmarshal in beforeunmarshal,期间,所有未知字段值都将出现在其上的List<Object>循环中,并将其添加到Map<String, Object>中。
类似地,在marshaling期间,您可以通过创建DOM元素将值Map<String, Object>移动到List<Object>。
Marshaling所有的值都被添加到root中,因为DOM Elements是存在的,并且在Unmarshaling期间,已知值首先被读取,然后由于@XmlAnyElement而在List<Object>中存储-未知的值。
我已经使用Customer类创建了一个示例,您可以根据需要相应地修改它。
@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
https://stackoverflow.com/questions/27765087
复制相似问题