添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

'interface' is a reserved word in Java, making it a poor choice for an XML element name.

However, the existing code was using the 'interface' naming, and it was necessary to develop in accordance with the same 'interface' naming to maintain backward compatibility.

Therefore, I first attached the @XmlElement annotation to the field to be bound, specifying the name as 'interface' like below.

In attempting to find 'interface' within _beanProperties, no result appears, leading to the prop becoming null.
Consequently, an error occurs in handleUnknownVanilla with com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "interface" .

Another solution to this problem is utilizing the _caseInsensitive attribute found in _beanProperties.

By adding the configuration objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) , it becomes possible to find in _beanProperties without distinguishing between uppercase and lowercase, thereby finding the properties correctly.

Additionally, using @JacksonXmlProperty instead of @XmlElement results in 'interface' being registered in _beanProperties, making it discoverable.

import javax.xml.bind.annotation.XmlElement ; import javax.xml.bind.annotation.XmlRootElement ; import com.fasterxml.jackson.annotation.JsonMerge ; import com.fasterxml.jackson.core.JsonProcessingException ; import com.fasterxml.jackson.dataformat.xml.XmlMapper ; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData ; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper ; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty ; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement ; public class ListTest { public static void main ( String [] args ) throws JsonProcessingException { String xml = "" + "<Data>" + " <product>a</product>" + " <product>b</product>" + " <backUrl>www.naver.com</backUrl>" + " <product>c</product>" + " <product>d</product>" + " <backUrl>www.naver.com</backUrl>" + " <product>e</product>" + "</Data>" ; XmlMapper m = new XmlMapper (); // m.setDefaultMergeable(true); Data data = m . readValue ( xml , Data . class ); System . out . println ( data . getProduct ()); @JacksonXmlRootElement ( localName = "data" ) class Data { @JacksonXmlCData @JacksonXmlElementWrapper ( useWrapping = false ) @JacksonXmlProperty private List < String > product ; @JacksonXmlCData @JacksonXmlElementWrapper ( useWrapping = false ) @JacksonXmlProperty private String backUrl ; public List < String > getProduct () { return product ; public void setProduct ( List < String > product ) { this . product = product ; public String getBackUrl () { return backUrl ; public void setBackUrl ( String backUrl ) { this . backUrl = backUrl ;

Multiple 'product' tags are supposed to be bound to a List object, but when actually calling getProduct, only 'e' appears. Although the XML request format was not standard, proper List object binding occurred with the older jaxb-api(2.1) , necessitating a solution for this issue within jackson-dataformat-xml as well.

The first thing we can do is modify the setProduct method as follows. Changing it to add the product instead of overwriting it will yield the desired result.

public void setProduct ( List < String > product ) { if ( this . product == null ) { this . product = product ; } else { this . product . addAll ( product );

Another method exists as well. From jackson-dataformat-xml(2.9) onwards, you can use the provided setDefaultMergeable.

Result without setDefaultMergeable true setting: [e]
Result with setDefaultMergeable true setting: [a, b, c, d, e]

However, there's one point of caution when using setDefaultMergeable. If the getter for the product is implemented as below to defend against null, then since the initial this.product is null, the result of the getProduct method becomes EMPTY_LIST.

public List < String > getProduct () { return Objects . isNull ( this . product ) ? Collections . emptyList () : Collections . unmodifiableList ( this . product );

Internally, when merging, the getProduct method is called, but since it initially receives EMPTY_LIST as a result, addition doesn't occur. This leads to an error: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: (was java.lang.UnsupportedOperationException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.UnsupportedOperationException) , even when using @JsonMerge .

Therefore, either implement getProduct in its basic form or

public List < String > getProduct () { if ( this . product == null ) { this . product = new ArrayList <>(); return this . product ;

Built on Forem — the open source software that powers DEV and other inclusive communities.

Made with love and Ruby on Rails . DEV Community © 2016 - 2024.