0

I've a generic field in User.java. I want to use the value of T in json.

public class User<T> {

public enum Gender {MALE, FEMALE};


private T field;
private Gender _gender;
private boolean _isVerified;
private byte[] _userImage;

public T getField() { return field; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }

public void setField(T f) { field = f; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }
}

and mapper class is:

public class App 
{
public static void main( String[] args ) throws JsonParseException, JsonMappingException, IOException
{
    ObjectMapper mapper = new ObjectMapper();
    Name n = new Name();
    n.setFirst("Harry");
    n.setLast("Potter");
    User<Name> user = new User<Name>();
    user.setField(n);
    user.setGender(Gender.MALE);
    user.setVerified(false);

    mapper.writeValue(new File("user1.json"), user);
}
}

and the json output is :

{"field":{"first":"Harry","last":"Potter"},"gender":"MALE","verified":false,"userImage":null}

In the output, i want Name to be appeared in place of field. How do i do that. Any help?

user2122853
  • 73
  • 1
  • 9

3 Answers3

0

I think what u ask is not JSON's default behavior. Field name is the "key" of the json map, not the variable name. U should rename the field or make some String process to do it.

Neron
  • 1,500
  • 7
  • 30
  • 52
0
private T field;

change the above to this:

private T name;
cyber_rookie
  • 665
  • 5
  • 9
0

You need a custom serializer to do that. That's a runtime data transformation and Jackson has no support for data transformation other than with a custom serializer (well, there's wrapping/unwrapping of value, but let's not go there). Also, you will need to know in advance every type of transformation you want to apply inside your serializer. The following works:

public class UserSerializer extends JsonSerializer<User<?>> {
    private static final String USER_IMAGE_FIELD = "userImage";
    private static final String VERIFIED_FIELD = "verified";
    private static final String FIELD_FIELD = "field";
    private static final String NAME_FIELD = "name";
    @Override
    public void serialize(User<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
            JsonProcessingException {
        jgen.writeStartObject();
        if (value.field instanceof Name) {
            jgen.writeFieldName(NAME_FIELD);
        } else {
            jgen.writeFieldName(FIELD_FIELD);
        }
        jgen.writeObject(value.field);
        jgen.writeStringField("gender", value._gender.name());
        jgen.writeBooleanField(VERIFIED_FIELD, value._isVerified);
        if (value._userImage == null) {
            jgen.writeNullField(USER_IMAGE_FIELD);
        } else {
            jgen.writeBinaryField(USER_IMAGE_FIELD, value._userImage);
        }
        jgen.writeEndObject();
    }
}
Pascal Gélinas
  • 2,744
  • 19
  • 20
  • if (value.field instanceof Name) { jgen.writeFieldName(NAME_FIELD); } else { jgen.writeFieldName(FIELD_FIELD); } in the above snippet , u'r just checking for Name class, what if i set some other class let's say "Person". It will set field as json tag. How can i achieve same for generic type – user2122853 May 15 '13 at 04:09
  • There's no magic in life. You'll need to add an instanceof check for every class you wish to change the field name. Or, if you want the field name to always be the name of the class, instead of the if-else construct you could do something like: `jgen.writeFieldName(value.field.getClass().geName()`. Or maybe a pluggable mechanism to determine what field name a class maps to. You've got plenty of choice. – Pascal Gélinas May 15 '13 at 13:55