On Sat, Sep 11, 2021 at 10:28 AM 'Mark Raynsford' via jackson-user
<[email protected]> wrote:
>
> Hello!
>
> I'm trying to use Jackson to serialize/deserialize values in a format
> that has an existing XML schema. I'm having difficulty getting
> serialized values to match the schema, and the rather sparse
> documentation isn't helping matters. Here's a small example (the
> Location and LocationID types are simplified versions of the types
> that appear in the real schema):
>
> ~~~
> import com.fasterxml.jackson.annotation.JsonProperty;
> import com.fasterxml.jackson.dataformat.xml.XmlMapper;
> import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
> import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
>
> import java.io.IOException;
> import java.util.Objects;
> import java.util.UUID;
>
> public final class SerialDemo2
> {
>   private SerialDemo2()
>   {
>
>   }
>
>   record LocationID(UUID id) {
>     LocationID {
>       Objects.requireNonNull(id, "id");
>     }
>   }
>
>   @JacksonXmlRootElement(namespace = "urn:com.io7m.cardant.inventory:1")
>   record Location(
>     @JsonProperty(required = true)
>     @JacksonXmlProperty(isAttribute = true, localName = "id")
>     LocationID id,
>
>     @JsonProperty(required = false)
>     @JacksonXmlProperty(isAttribute = true, localName = "parent")
>     LocationID parent
>   ) {
>     Location {
>       Objects.requireNonNull(id, "id");
>     }
>   }
>
>   public static void main(
>     final String[] args)
>     throws IOException
>   {
>     final var mapper =
>       XmlMapper.builder()
>         .build();
>
>     System.out.println("Expected: ");
>     System.out.println();
>     System.out.println("""
> <Location xmlns="urn:com.io7m.cardant.inventory:1"
>   id="6e3f4213-db36-4ea3-91ba-1ce6917cbcbb"
>   parent="265f34b3-8c86-4a1f-b23a-bb104238bfc6"/>
> """);
>
>     System.out.println("Received: ");
>     System.out.println();
>     mapper.writeValue(
>       System.out,
>       new Location(
>         new LocationID(UUID.randomUUID()),
>         new LocationID(UUID.randomUUID())
>       )
>     );
>     System.out.println();
>   }
> }
> ~~~
>
> The output of the above is:
>
> ~~~
> Expected:
>
> <Location xmlns="urn:com.io7m.cardant.inventory:1"
>   id="6e3f4213-db36-4ea3-91ba-1ce6917cbcbb"
>   parent="265f34b3-8c86-4a1f-b23a-bb104238bfc6"/>
>
> Received:
>
> <Location xmlns="urn:com.io7m.cardant.inventory:1"><id 
> xmlns=""><id>c09fb552-e36c-4213-b56a-7729cd5b7999</id></id><parent 
> xmlns=""><id>58c399ae-0256-4dbd-a00e-0c1c01189559</id></parent></Location>
> ~~~
>
> I've tried various combinations of the XML properties, and it's not
> clear how (or even if) I can use the existing JSON properties to get
> the right input/output mapping.

The main (or initial?) problem here is just that type LocationID is
taken to be a POJO with properties (since Records by definition are),
instead of something behaving like String value. The issue is that
POJOs cannot be serialized as attributes but only as elements.
In theory it is possible to annotate Records to work like Strings,
too, but it might be easier to first try to create equivalent "simple"
pojo with
something like:

static class LocationId {
   private UUID id;

   @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
   public LocationId(UUID id) { this.id = id; }

   @JsonValue // method name can be anything
   protected UUID id() { return id; }
}

which should then serialize as a basic String value, and deserialized
similarly from a String value.

I have not verified above but conceptually this should work.

-+ Tatu +-

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jackson-user/CAL4a10gyXNRBk2-FWYYP05iTQL7u6hBmSm3G0T-RjWZc-uyQzA%40mail.gmail.com.

Reply via email to