array to object deserialization supported ?

50 views
Skip to first unread message

Guido Rost

unread,
Nov 11, 2019, 6:39:43 PM11/11/19
to jackson-user
Hello jackson-user group,
I am trying to deserialize the following json string:
String json = "{\"actions\":[[\"set-device-id\",[\"radius-avp\",\"nas-identifier\"]]]}";

into the object:
@JsonFormat(shape=JsonFormat.Shape.ARRAY)
@JsonTypeName("set-device-id")
static public class SetDeviceId extends TransformAction {
public RadiusAvp radiusAvp;
public SetDeviceId() {}
...
}

Where TransformAction is this:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ARRAY, property = "name")
@JsonSubTypes({@JsonSubTypes.Type(TransformAction.SetDeviceId.class),...)}
@JsonTypeName("transform-action")
public abstract class TransformAction {
...
}

and RadiusAvp is:
@JsonTypeName("radius-avp")
public class RadiusAvp {

public String attribute;

public RadiusAvp(String attribute) {
this.attribute = attribute;
}
...
}

Doing this jackson errors:

Unexpected token (VALUE_STRING), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class RadiusAvp at [Source: 

Is there any way of deserializing the provided json into SetDeviceId. I understand that Jackson doesn't seem to know about the RadiusAvp type since I provide no assignment to the SetDeviceId.radiusAvp field. Is there some Jackson annotation which is missing or wrong ?



Tatu Saloranta

unread,
Nov 11, 2019, 6:47:04 PM11/11/19
to jackson-user
I think I am missing something: what is the exact main level call to
readValue(): specifically, what is its target type? (I do not see any
class with property "actions" which must exist to match JSON Object)

-+ Tatu +-

Guido Rost

unread,
Nov 11, 2019, 10:11:11 PM11/11/19
to jackson-user

I left out the upper level classes:

@JsonTypeName("transform-rule")
public class TransformRule {

@JsonProperty("condition")
public TransformCondition condition;

@JsonProperty("actions")
public List<TransformAction> actions;
...
}

Guido Rost

unread,
Nov 11, 2019, 10:13:03 PM11/11/19
to jackson-user

I just posted the upper level class which contains the actions. 
The target type is SetDeviceId which contains a field of type RadiusAvp. The construction of that is the actual problem

Tatu Saloranta

unread,
Nov 12, 2019, 6:11:30 PM11/12/19
to jackson-user
On Mon, Nov 11, 2019 at 7:13 PM Guido Rost <guido...@gmail.com> wrote:
>
>
> I just posted the upper level class which contains the actions.
> The target type is SetDeviceId which contains a field of type RadiusAvp. The construction of that is the actual problem

Yes, please do tell me what I really need.

-+ 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 jackson-user...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/e88ec00a-e3f1-453f-8eaf-f3fd83cf8422%40googlegroups.com.

Guido Rost

unread,
Nov 13, 2019, 12:52:29 AM11/13/19
to jackson-user
Hi Tatu,
here is a little runnable file which shows my problem. I can make it work the delegation to the JsonCreator (commented out in SetDeviseId) but I was hoping to avoid this.
Hopefully you can point me to what I am missing or doing wrong. Thanks so much.

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

public class MyProblem {

ObjectMapper mapper;


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ARRAY, property = "name")
    @JsonTypeName("radius-avp")
static public class RadiusAvp {
public String attribute;

public RadiusAvp() {

}

public RadiusAvp(String attribute) {
this.attribute = attribute;
}

        public String toString() {
return "radius-avp = " + attribute;
}
}

@JsonTypeName("transform-rule")
static public class TransformRule {

public TransformRule() {
}

@JsonProperty("actions")
public List<SetDeviceId> actions;

public String toString() {
return "Transform-rule: " + actions.toString();

}
}


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ARRAY, property = "name")
    @JsonTypeName("set-device-id")
static public class SetDeviceId {


public RadiusAvp radiusAvp;

public SetDeviceId() {
}

//         Uncomment this section to make this work (but we don't like this)
//
// @JsonCreator
// public SetDeviceId(Object object) {
// ObjectMapper mapper = new ObjectMapper();
// radiusAvp = mapper.convertValue(object, RadiusAvp.class);
// }

public String toString() {
return "set-device-id: " + radiusAvp.toString();
}
}


public static void main(String[] args) throws Exception {

String json = "{\"actions\":[[\"set-device-id\",[\"radius-avp\",\"nas-identifier\"]]]}";

        ObjectMapper mapper = new ObjectMapper();
TransformRule transformRule = mapper.readValue(json, TransformRule.class);
System.out.println(transformRule.toString());
}
}

On Tuesday, November 12, 2019 at 3:11:30 PM UTC-8, Tatu Saloranta wrote:
On Mon, Nov 11, 2019 at 7:13 PM Guido Rost <guid...@gmail.com> wrote:
>
>
> I just posted the upper level class which contains the actions.
> The target type is SetDeviceId which contains a field of type RadiusAvp. The construction of that is the actual problem

Yes, please do tell me what I really need.

-+ 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 jackso...@googlegroups.com.

Tatu Saloranta

unread,
Nov 14, 2019, 6:18:43 PM11/14/19
to jackson-user
By quick look, would it not work if you declared type of delegated thing as `RadiusAvp`, not Object?

And if serialization needed, adding `@JsonValue` on that RadiusAvp field.

-+ Tatu +-


To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/35ebdc5e-8084-4347-8280-06bd42127877%40googlegroups.com.

Guido Rost

unread,
Nov 14, 2019, 6:41:54 PM11/14/19
to jackson-user
You're right, that works. Now it looks way better. But there is no way of Jackson creating SetDeviceId without the @JsonCreator annotation? 
Thanks  a lot ,
Guido


On Thursday, November 14, 2019 at 3:18:43 PM UTC-8, Tatu Saloranta wrote:
By quick look, would it not work if you declared type of delegated thing as `RadiusAvp`, not Object?

And if serialization needed, adding `@JsonValue` on that RadiusAvp field.

-+ Tatu +-


Tatu Saloranta

unread,
Nov 14, 2019, 7:04:56 PM11/14/19
to jackson-user
On Thu, Nov 14, 2019 at 3:41 PM Guido Rost <guido...@gmail.com> wrote:
You're right, that works. Now it looks way better. But there is no way of Jackson creating SetDeviceId without the @JsonCreator annotation? 

Nope, not as general feature. Leaving that out would open potential security holes, and there is ambiguity in 1-arg case regardless (whether it's for "{ 'name' : value }" or just "value".

Although... your specific case can be covered by custom `AnnotationIntrospector` that claims it totally saw "Creator annotation" in there regardless. So you can add logic in... I forget name of method, you can see that in `JacksonAnnotationIntrospector`.

-+ Tatu +-
 
To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/f3efba48-41d6-4455-980b-e9d75231ed85%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages