Enum类返回值不符预期,如何实现指定JSON格式返回?
解决枚举类多@JsonValue注解报错及返回指定JSON格式的问题
问题根源
@JsonValue注解的作用是告诉Jackson序列化枚举时,只输出该注解标记的属性/方法返回值作为整个枚举的代表值,一个枚举类只能有一个这样的标记——多个的话Jackson无法确定用哪个值序列化,所以抛出Multiple 'as-value' properties defined错误。
两种可行解决方案
方案一:直接在Controller中转换为目标格式(简单快捷)
不需要修改枚举类的序列化配置,直接在Controller里把枚举项转换成你需要的键值对结构:
- 先定义正常的枚举类(去掉多余的
@JsonValue):
public enum AssociationStatus { A("Associated"), D("Disassociated"); private final String value; AssociationStatus(String value) { this.value = value; } public String getValue() { return value; } }
- 在Controller中编写接口,将枚举转换为
List<Map<String, String>>:
import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class StatusController { @GetMapping("/association-statuses") public List<Map<String, String>> getAllAssociationStatuses() { return Arrays.stream(AssociationStatus.values()) .map(status -> { Map<String, String> statusMap = new HashMap<>(); statusMap.put("key", status.name()); // 枚举的name()就是"A"、"D" statusMap.put("value", status.getValue()); return statusMap; }) .collect(Collectors.toList()); } }
这种方式不需要额外配置,代码直观,适合快速实现需求。
方案二:自定义枚举序列化器(优雅通用)
如果希望枚举在任何地方序列化时都输出指定的键值对格式,可以自定义Jackson序列化器:
- 定义枚举类,并添加
@JsonSerialize指定自定义序列化器:
import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize(using = AssociationStatusSerializer.class) public enum AssociationStatus { A("Associated"), D("Disassociated"); private final String value; AssociationStatus(String value) { this.value = value; } public String getValue() { return value; } }
- 编写自定义序列化器:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.io.IOException; public class AssociationStatusSerializer extends StdSerializer<AssociationStatus> { public AssociationStatusSerializer() { super(AssociationStatus.class); } @Override public void serialize(AssociationStatus status, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartObject(); gen.writeStringField("key", status.name()); gen.writeStringField("value", status.getValue()); gen.writeEndObject(); } }
- Controller中直接返回枚举数组即可:
import java.util.Arrays; import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class StatusController { @GetMapping("/association-statuses") public List<AssociationStatus> getAllAssociationStatuses() { return Arrays.asList(AssociationStatus.values()); } }
两种方案都能返回你期望的JSON格式:
[{"key":"A","value":"Associated"},{"key":"D","value":"Disassociated"}]
内容的提问来源于stack exchange,提问作者Talenel
相关产品推荐
相关产品推荐

