根据值的枚举类型从 HashMap 中删除条目
remove an entry from HashMap depending on the Enum type of the value
我需要从一个对象创建一个 json。 Object 包含一个 Name 类型的 List 成员变量。名称是一个 class,其中包含一个枚举名称类型。下面是 class:
public final class Person { private final List<Name> names; }
public class Name {
private final String first;
private final String last;
private final String middle;
private final NameType type;
}
public enum NameType {
X,
Y,
Z
}
为 class Person 生成的 json 不应包含 NameType 为 Y 和 Z 的名称。下面是我尝试生成 json 的简单方法:
Map<String, Object> personMap = mapper.readValue(person!=null ? mapper.writeValueAsString(person) : "{}", typeReference);
我需要从 personMap 中删除键“names”。我已经搜索了几种在序列化之前将其删除的方法,但这对我没有用。我遵循了本教程:https://www.baeldung.com/jackson-ignore-properties-on-serialization
并尝试使用类型和过滤器删除它,但因为这是一个枚举所以对我不起作用。所以,我有 2 个问题:
- 有没有办法不将名称 属性 作为基于 NameType 的序列化的一部分包含在内。
- 如果序列化完成后有什么方法可以删除。
下面是为地图生成的结构。
提前致谢!!
免责声明:我以前从未使用过Jackson,这是我第一次接触。我只是想在喝早茶的时候寻找一个小谜题来解决,这也能让我学到一些东西。所以我不确定是否有更好或更优雅的方法来做到这一点。
为了展示一个每个人都可以轻松编译和执行的 MCVE,这里是我的示例的更完整版本(包括 getter)类:
package de.scrum_master.Whosebug.q71358052;
public enum NameType {
REAL,
ARTIST,
ONLINE
}
package de.scrum_master.Whosebug.q71358052;
public class Name {
private final String first;
private final String last;
private final String middle;
private final NameType type;
public Name(String first, String last, String middle, NameType type) {
this.first = first;
this.last = last;
this.middle = middle;
this.type = type;
}
public String getFirst() {
return first;
}
public String getLast() {
return last;
}
public String getMiddle() {
return middle;
}
public NameType getType() {
return type;
}
}
package de.scrum_master.Whosebug.q71358052;
import java.util.List;
public final class Person {
private final List<Name> names;
public Person(List<Name> names) {
this.names = names;
}
public List<Name> getNames() {
return names;
}
}
如 this tutorial 中类似案例所述,我们可以将自定义 JsonSerializer<Name>
与 BeanSerializerModifier
结合使用,将它们注册到 ObjectMapper
中的 SimpleModule
:
package de.scrum_master.Whosebug.q71358052;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class NameSerializer extends JsonSerializer<Name> {
private final JsonSerializer<Object> defaultSerializer;
public NameSerializer(JsonSerializer<Object> serializer) {
defaultSerializer = serializer;
}
@Override
public void serialize(Name value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value.getType() != NameType.REAL)
return;
defaultSerializer.serialize(value, gen, serializers);
}
@Override
public boolean isEmpty(SerializerProvider provider, Name value) {
return value == null || value.getType() != NameType.REAL;
}
}
package de.scrum_master.Whosebug.q71358052;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.util.List;
public class JacksonDemo {
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person(List.of(
new Name("Edward", "Robinson", "G.", NameType.ARTIST),
new Name("Emanuel", "Goldenberg", null, NameType.REAL),
new Name("Эмануэль", "Голденберг", null, NameType.REAL),
new Name("Eddie", "The Gangster", null, NameType.ONLINE)
));
ObjectMapper objectMapper = getObjectMapper();
String personJson = objectMapper.writeValueAsString(person);
System.out.println(personJson.contains("ARTIST")); // false
System.out.println(personJson.contains("ONLINE")); // false
System.out.println(personJson.contains("Goldenberg")); // true
System.out.println(personJson.contains("Голденберг")); // true
System.out.println(personJson);
}
private static ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
objectMapper.registerModule(
new SimpleModule() {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addBeanSerializerModifier(
new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if (Name.class.isAssignableFrom(beanDesc.getBeanClass()))
return new NameSerializer((JsonSerializer<Object>) serializer);
return serializer;
}
}
);
}
}
);
return objectMapper;
}
}
控制台日志应该是:
false
false
true
true
{"names":[{"first":"Emanuel","last":"Goldenberg","type":"REAL"},{"first":"Эмануэль","last":"Голденберг","type":"REAL"}]}
哦,顺便说一句,以防万一不是每个人都知道 Edward G. Robinson 是谁...
我需要从一个对象创建一个 json。 Object 包含一个 Name 类型的 List 成员变量。名称是一个 class,其中包含一个枚举名称类型。下面是 class:
public final class Person { private final List<Name> names; }
public class Name {
private final String first;
private final String last;
private final String middle;
private final NameType type;
}
public enum NameType {
X,
Y,
Z
}
为 class Person 生成的 json 不应包含 NameType 为 Y 和 Z 的名称。下面是我尝试生成 json 的简单方法:
Map<String, Object> personMap = mapper.readValue(person!=null ? mapper.writeValueAsString(person) : "{}", typeReference);
我需要从 personMap 中删除键“names”。我已经搜索了几种在序列化之前将其删除的方法,但这对我没有用。我遵循了本教程:https://www.baeldung.com/jackson-ignore-properties-on-serialization 并尝试使用类型和过滤器删除它,但因为这是一个枚举所以对我不起作用。所以,我有 2 个问题:
- 有没有办法不将名称 属性 作为基于 NameType 的序列化的一部分包含在内。
- 如果序列化完成后有什么方法可以删除。
下面是为地图生成的结构。
提前致谢!!
免责声明:我以前从未使用过Jackson,这是我第一次接触。我只是想在喝早茶的时候寻找一个小谜题来解决,这也能让我学到一些东西。所以我不确定是否有更好或更优雅的方法来做到这一点。
为了展示一个每个人都可以轻松编译和执行的 MCVE,这里是我的示例的更完整版本(包括 getter)类:
package de.scrum_master.Whosebug.q71358052;
public enum NameType {
REAL,
ARTIST,
ONLINE
}
package de.scrum_master.Whosebug.q71358052;
public class Name {
private final String first;
private final String last;
private final String middle;
private final NameType type;
public Name(String first, String last, String middle, NameType type) {
this.first = first;
this.last = last;
this.middle = middle;
this.type = type;
}
public String getFirst() {
return first;
}
public String getLast() {
return last;
}
public String getMiddle() {
return middle;
}
public NameType getType() {
return type;
}
}
package de.scrum_master.Whosebug.q71358052;
import java.util.List;
public final class Person {
private final List<Name> names;
public Person(List<Name> names) {
this.names = names;
}
public List<Name> getNames() {
return names;
}
}
如 this tutorial 中类似案例所述,我们可以将自定义 JsonSerializer<Name>
与 BeanSerializerModifier
结合使用,将它们注册到 ObjectMapper
中的 SimpleModule
:
package de.scrum_master.Whosebug.q71358052;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class NameSerializer extends JsonSerializer<Name> {
private final JsonSerializer<Object> defaultSerializer;
public NameSerializer(JsonSerializer<Object> serializer) {
defaultSerializer = serializer;
}
@Override
public void serialize(Name value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value.getType() != NameType.REAL)
return;
defaultSerializer.serialize(value, gen, serializers);
}
@Override
public boolean isEmpty(SerializerProvider provider, Name value) {
return value == null || value.getType() != NameType.REAL;
}
}
package de.scrum_master.Whosebug.q71358052;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.util.List;
public class JacksonDemo {
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person(List.of(
new Name("Edward", "Robinson", "G.", NameType.ARTIST),
new Name("Emanuel", "Goldenberg", null, NameType.REAL),
new Name("Эмануэль", "Голденберг", null, NameType.REAL),
new Name("Eddie", "The Gangster", null, NameType.ONLINE)
));
ObjectMapper objectMapper = getObjectMapper();
String personJson = objectMapper.writeValueAsString(person);
System.out.println(personJson.contains("ARTIST")); // false
System.out.println(personJson.contains("ONLINE")); // false
System.out.println(personJson.contains("Goldenberg")); // true
System.out.println(personJson.contains("Голденберг")); // true
System.out.println(personJson);
}
private static ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
objectMapper.registerModule(
new SimpleModule() {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.addBeanSerializerModifier(
new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if (Name.class.isAssignableFrom(beanDesc.getBeanClass()))
return new NameSerializer((JsonSerializer<Object>) serializer);
return serializer;
}
}
);
}
}
);
return objectMapper;
}
}
控制台日志应该是:
false
false
true
true
{"names":[{"first":"Emanuel","last":"Goldenberg","type":"REAL"},{"first":"Эмануэль","last":"Голденберг","type":"REAL"}]}
哦,顺便说一句,以防万一不是每个人都知道 Edward G. Robinson 是谁...