Closed oooooooz closed 4 months ago
Wrong repo, will transfer.
Ok, there are quite a few challenges for reproduction here.
For starters, when testing, PLEASE NEVER DISABLE DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
. Doing so will regularly hide real problems. You can disable that for production code, but for testing, don't.
Second: although use of Lombok is fine with Jackson, and should work, test reproductions should not use Lombok since its bytecode post-processing makes it difficult to know what is happening. None of test in Jackson repos can use Lombok as a consequence. I assume it is possible to change reproductions to avoid it, either by getting processed class definitions, or convert manually.
Third: Jackson does not actually support deserialization for all kinds of XML representations: it specifically aims to support use case of "reading what it writes": so, if you start with Java objects, serialize as XML, it should also be able to read XML back into same Java objects. So to troubleshoot deserialization problems, it is usually best to start by creating Java objects, serializing as XML, and looking at how this differs from XML you'd like to read. If you can change annotations or class definitions to produce that XML structure, you should be able to read it back. If not, you most likely cannot.
Fourth: your attempt to read XML as Map
, then convert to Java object is very unlikely to work, at all.
XML as a data format is challenging to map to/from Java Objects, and requires class definitions -- so trying to read as java.util.Map
will lose information and not allow conversion. This is different from JSON, one difference being that JSON has native Array and Object type difference; XML does not (it only has Elements, which are more similar to. JSON Objects than Arrays). To support Array/Collection types, readValue()
has to bind to actual Java class, not JDK container types like Map
s or Collection
s.
So for things to work, you will need to try to make XmlMapper.readValue()
do all the work: mapper.convertValue()
is not likely to work (but I am also not sure it is even being attempted: I am not sure I follow intended logic).
I hope this helps.
OK ,thank you very much, let me know more about jackson 👍 i here there some historical items burden, use Lombok , the XML format ,etc.. just like dancing in fetters. I just test on them and not being conscious of some problems you describe.
It look like that the encoding
of XML declaration is UTF-8
, with hard code when serialization , and ToXmlGenerator
cannot be overrided in 2.12.3 , but i need another encoding declaration more than UTF-8, how could i do ? Is jackson use this encoding when serialize? @cowtowncoder
If you want to use some other encoding, you will need to create XMLStreamWriter
from Stax implementation (like Woodstox), call its writeStartDocument()
(version that takes encoding
argument), and then use XmlMapper.writeValue(XMLStreamWriter, Object)
to serialize using that XMLStreamWriter
.
@cowtowncoder OK, What's up with [#355 ] and [#324 ] now , Is there any solution? only root element need namespace and xsi:type ,thank you
What do issues say? If there is progress, solution, there will be comments. Absence of that, no progress.
So perhaps something could be figured for some kind of namespace defaulting... I am open to suggestions.
@JsonTypeInfo
).Although... perhaps, just perhaps, there could be a feature to force simple name of "xsi:type"
to be automatically converted into qualified name with proper namespace. This would have to be ToXmlGenerator.Feature
.
Actually, it should probably be a feature that would handle all "xsi:*"
cases by splitting property name into local name, namespace URI; and would then handle xsi:type
.
I'll add a note there.
Added my notes on #324: maybe I'll play with that later tonight.
Ok did fix #324 but also filed a follow-up for deserialization side (#634) now that generation of xsi:type
is possible with 2.17.
Search before asking
Describe the bug
I use jackson-dataformat-xml to deserialize XML , but it throws exception : Exception in thread "main" java.lang.IllegalArgumentException: Cannot deserialize value of type
java.util.ArrayList<RetInfArryDTO>
from Object value (tokenJsonToken.START_OBJECT
) at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: AnRspDTO["SysHead"]->SysHeadRspDTO["RetInfArry"])It look like thak jackson unrecognize this type of XML format data , could not treat the array in XML as real array to deserialize , but I think it is a kind of common XML data which contain array type, isn't it ?
I tried annotation like @JsonDeserialize(contentAs = AddrInfArryDTO.class), @JsonAlias({ "IdInfArry", "IdInfArry.array" }), but it did not work for me !
Q1: Is anyone know how to solve this problem? Q2: If I must use custom JsonDeserializer to solve , how can I get the
elementType
below ?could not get it from both jsonParser and deserializationContext, and i don't want to write hard code , give exactly elementType here, because too must DTO to be deserialized , write a general custom JsonDeserializer is very necessary!Here below is my XML data to be deserialized and its DTO object :
(1)XML data like this :
(2)Here is my DTO , XML deserialize object :
Version Information
pom dependency , current steady version 2.16.0 could not solve the problem too
Reproduction
<-- Any of the following
public static T decode(String msg, Class entityType) {
ObjectMapper objectMapper = getObjectMapper();
try {
return objectMapper.readValue(msg, entityType);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static T convert(Object src, Class dstType) {
ObjectMapper objectMapper = getObjectMapper();
return objectMapper.convertValue(src, dstType);
}
public static ObjectMapper getObjectMapper(){
return builder.build();
}
public static void main(String[] args) { String xmldata=getXml()// Map map =decode(xmldata,Map.class); AnRspDTO dtoObj = convert(map,RspBodyDTO.class); Assert.notNull(dtoObj) }