0

I have a class hierarchy that is somewhat like below, with a custom Converter

The FieldValueConverter#deserialize is NOT being called in my JerseyTest. Instead, it uses the default GensonJsonConverter which complains it can't find the appropriate constructor. (Caused by: com.owlike.genson.JsonBindingException: No constructor has been found for type class com.searchdata.actions.api.FieldValue)

How do I get it to be used?

Registration

The converter for the FieldValues (see below), which I register in a Jersey Application like this:

    Genson genson = new GensonBuilder()
            .withBundle(new JAXBBundle())
            .withConverter(new FieldValueConverter(), FieldValue.class)
            .setSkipNull(true)
            .create();



    register(new GensonJaxRSFeature().use(genson));

FieldValueConverter

public class FieldValueConverter implements Converter<FieldValue> {

    private static final Logger LOG = LoggerFactory.getLogger(FieldValueConverter.class);


    public void serialize(FieldValue fieldValue, ObjectWriter writer, Context ctx) throws Exception {

        LOG.info("Serializing fieldValue:{}", fieldValue);
        writer.beginObject();
        writer.writeString("type", fieldValue.getType().name())
                .writeString("value", fieldValue.getValue().toString())
                .writeString("field", fieldValue.getField());
        writer.endObject();
        LOG.info("..Done!", fieldValue);
    }

    /* You don't have to worry for the object being null here, if it is null Genson will
    handle it for you. */
    public FieldValue deserialize(ObjectReader reader, Context ctx) throws Exception {

        LOG.info("Deserializing fieldValue...");

        reader.beginObject();

        String stringValue=null;
        FieldType type= FieldType.STRING;
        String fieldKey= null;

        while (reader.hasNext()) {
            reader.next();
            if ("type".equals(reader.name())) {
                type = FieldType.valueOf(reader.valueAsString());
            } else if ("field".equals(reader.name())) {
                fieldKey = reader.valueAsString();
            } else if ("value".equals(reader.name())) {
                stringValue = reader.valueAsString();
            } else {
                reader.skipValue();
            }
        }

Item

public class Item
{
    @Schema(name = "id", description = "The id of an item")
    private String id;

    @Schema(name = "values", description = "The fields with values for this action")
    private List<FieldValue> values;

}

FieldValue

@Schema(name = "FieldValue")
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class FieldValue {

    @Schema(name = "field", description = "The technical name of the field")
    private String field;

    @Schema(name = "type", description = "The type of the field")
    private FieldType type;

    @Schema(name = "value", description = "The value of a field", oneOf = {Integer.class, String.class, Date.class, Double.class})
    private Serializable value;


    public FieldValue(final String field, final String string) {
        setField(field);
        setValue(string);
        setType(FieldType.STRING);
    }

    public FieldValue(final String field, final Long number) {
        setField(field);
        setValue(number);
        setType(FieldType.LONG);
    }
Rob Audenaerde
  • 19,195
  • 10
  • 76
  • 121
  • Did you check if your custom Genson instance is being picked up at all? Here is how the jax-rs/jersey integration is done https://github.com/owlike/genson/tree/master/genson/src/main/java/com/owlike/genson/ext/jaxrs – eugen Aug 04 '21 at 07:58
  • Hi @eugen, it seems the `JerseyTest` does not pick up the Genson instance when using the `target()` method. If I `register` the `GensonCustomResolver` *after* the `target()` call, it works. Does that make sense? – Rob Audenaerde Aug 04 '21 at 14:10

0 Answers0