0

I'am trying to deserialize xml that contains a base64 encoded tag into an object

This is an example of the api response data :

<WebResponse>
    <RequestId>6541635537</RequestId>
    <Items>
        <Item>
            <Id>1aSd</Id>
            <Name>spider</Name>
        </Item>
        <Item>
            <Id>2sze</Id>
            <Name>catman</Name>
        </Item>
    </Items> <Customer>PEN1c3RvbWVyPg0KIDxOYW1lPk5pY288L05hbWU+DQogPEFjY291bnRzPg0KICA8QWNjb3VudD4NCiAgIDxUeXBlPlBSTzwvVHlwZT4NCiAgPC9BY2NvdW50Pg0KICA8QWNjb3VudD4NCiAgIDxUeXBlPlBST01BWDwvVHlwZT4NCiAgPC9BY2NvdW50Pg0KIDwvQWNjb3VudHM+DQo8L0N1c3RvbWVyPg==</Customer>
</WebResponse>

If you decode the Customer block, you will get :

<Customer>
 <Name>Nico</Name>
 <Accounts>
  <Account>
   <Type>PRO</Type>
  </Account>
  <Account>
   <Type>PROMAX</Type>
  </Account>
 </Accounts>
</Customer>

What i want to do, is to decode the Customer block first before serialization.

this is what i have tried to do so fare :

ObjectMapper MAPPER = new XmlMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
WebResponse result = MAPPER.readerFor(WebResponse.class).readValue(webResponse);

I have got this excepting while giving a try : Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of org.Customer (although at least one Creator exists): no String-argument

Any hints are welcome. This is the classes : link => MainMapper.class has the main method to launch the test.

Thank you

  • 1
    One way is to give `Customer` a constructor which takes a Base64 string, converts it to XML and parses it. But better to use a custom deserializer, see https://stackoverflow.com/questions/19158345/custom-json-deserialization-with-jackson – tgdavies Jul 14 '23 at 10:56
  • hi @tgdavies, thank you for your answer. this is what i did : public class CustomerDeserializer extends JsonDeserializer { Override public Customer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException { String decodedCustomer = new String(Base64.getDecoder().decode(p.getText())); // How to delegate parsing & deserialization to the Super/Default implementation return null; } }. =>. But How to delegate parsing & deserialization to the Super/Default implementation after i decode the text – user22210101 Jul 14 '23 at 20:52

1 Answers1

0

You use JsonDeserialiser. But you have XML. A custom JsonDeserializer is set on the property with the @JsonDeserialize annotation. In my opinion there is no annotation for jackson-dataformat-xml or you cannot set a custom deserialiser with the XmlMapper. But maybe there is a possible.

Here's what I would do:

  • Read response with SAXParser
  • Decode base64 string in .
  • Replace with decoded XML with SAXParser
<WebResponse>
    <RequestId>6541635537</RequestId>
    <Items>
        <Item>
            <Id>1aSd</Id>
            <Name>spider</Name>
        </Item>
        <Item>
            <Id>2sze</Id>
            <Name>catman</Name>
        </Item>
    </Items>
    <Customer>
        <Name>Nico</Name>
        <Accounts>
            <Account>
                <Type>PRO</Type>
            </Account>
            <Account>
                <Type>PROMAX</Type>
            </Account>
        </Accounts>
    </Customer>
</WebResponse>

You can then deserialize this XML with Jackson.

Bademeister
  • 389
  • 1
  • 10