Custom serializer for serializing a List<User> in List<String>
Solution 1
I suggest that you look into Jackson's Converter
interface, which seems more suited to the task than creating a custom serializer.
One approach it to create a Converter
instance and add it to the ObjectMapper
, so that it will be used for the serialization of all User
instances.
public class UserConverter extends StdConverter<User, String> {
@Override
public String convert(User user) {
return user.getTitle();
}
}
Register it on your ObjectMapper
like this:
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(User.class, new StdDelegatingSerializer(new UserConverter()));
ObjectMapper om = new ObjectMapper().registerModule(simpleModule);
Another approach, in case you don't want to convert all User
instances to String
, is to annotate selected properties with a converter like this:
public class Group {
String title;
@JsonSerialize(converter = ListUserConverter.class)
List<User> members;
String createdBy;
}
And have a corresponding converter that looks something like this:
public class ListUserConverter extends StdConverter<List<User>, List<String>> {
@Override
public List<String> convert(List<User> users) {
return users.stream().map(User::getTitle).collect(Collectors.toList());
}
}
Solution 2
Try like below :
Group:
@JsonIgnoreProperties(ignoreUnknown=true)
public class Group {
@JsonSerialize(using= TitleSerializer.class)
List<User> members;
//getters and setters
}
User:
public class User {
private String title;
//getters and setters
}
Custom Serializer :
public class TitleSerializer extends StdSerializer<List<User>> {
private static List<User> users=new ArrayList<User>();
protected TitleSerializer(Class<List<User>> t) {
super(t);
// TODO Auto-generated constructor stub
}
@SuppressWarnings("unchecked")
public TitleSerializer(){
this((Class<List<User>>) users.getClass());
}
@Override
public void serialize(List<User> users, JsonGenerator paramJsonGenerator,
SerializerProvider paramSerializerProvider) throws IOException {
paramJsonGenerator.writeStartObject();
List<String> titles=new ArrayList<String>(users.size());
for(User user: users){
titles.add(user.getTitle());
}
paramJsonGenerator.writeObjectField("members", titles);
paramJsonGenerator.writeEndObject();
}
}
Test :
Group group=new Group(Arrays.asList(new User("a"),new User("b"),new User("c")));
ObjectMapper mapper = new ObjectMapper();
String serialized = mapper.writeValueAsString(group);
System.out.println("output "+serialized);
Output:
{"members":["a","b","c"]}
crysis
Updated on July 29, 2022Comments
-
crysis over 1 year
I've a Model object Group
public class Group { String title; List<User> members; String createdBy; }
I'm using Jackson to serialize this Object. Instead of serializing the whole User object in list "members" I want to serializer just the
user.getTitle()
field. Basically I want a HashMap to be something like{ "title" : "sometitle" "members" : [user1.getTitle(), user2.getTitle()] }
I've written a custom serializer for this
public class GroupSerializer extends JsonSerializer<Circle> { @Override public void serialize(Group value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { if(value != null) { gen.writeStartObject(); gen.writeStringField("title", value.getTitle()); gen.writeStringField("createdBy", value.getCreatedBy()); gen.writeFieldName("members"); gen.writeStartArray(); for(User user : value.getMembers()) { gen.writeString(user.getEmail()); } gen.writeEndArray(); gen.writeEndObject() } } }
But it's not working. How do I serialize only a field of List instead of whole User Object?
-
crysis over 7 yearsThis is what im looking for. Thanks. But what is that stream() function?
-
Henrik Aasted Sørensen over 7 yearsGood to hear it! :) The stream() thing is a Java 8 thing (Read more), and is not mandatory. Feel free to convert the list the way you usually would.
-
crysis over 7 yearsIt's similar to RxJava Observable. Thanks dude. Your solution worked.
-
Andrew T Finnell over 5 yearsI'm curious why this isn't the Accepted Answer, or at the very least why it was down voted. This appears to be exactly what is needed.
-
mzl over 5 yearsBecause this is not working. Don't waste your time on this answer. The output is: output {"members":{"members":["a","b","c"]}}
-
tete over 4 yearsI used this to filter a list using an element's property (isHidden()) since Jackson 2.8 doesn't have JsonInclude.Include.CUSTOM feature, it's incorporated in 2.9.
-
Alessandro Scarlatti over 2 yearsSince Jackson 2.2 you can also use
@JsonSerialize(contentConverter=UserConverter.class)
for aList<User>
field. This way, you can use a single converter class for aUser
field orList<User>
field.