将枚举名称和字符串值作为 api 响应返回
Posted
技术标签:
【中文标题】将枚举名称和字符串值作为 api 响应返回【英文标题】:Returning both enum name and string value as api response 【发布时间】:2020-08-17 14:08:40 【问题描述】:这是我的枚举类
public enum Status
OPEN("Open"),
IN_PROCESS("In Process"),
ON_HOLD("On Hold"),
RESOLVED("Resolved");
private String status;
Status(String status)
this.status = status;
@JsonValue
public String getStatus()
return status;
我的 api 目前正在将 Status
的值作为字符串返回,这是返回的 json 响应的一部分。 "id":1,"name":"John","subject":"Help","status":"Open"
如何让我的回复类似于"status": "id": "ON_HOLD", "value": "On Hold"
这是使用枚举状态的模型,部分省略。
public class Ticket
private @Id @GeneratedValue(strategy=GenerationType.IDENTITY) Long id;
private String name;
private String subject;
@Enumerated(EnumType.STRING)
private Status status;
//getters, setters, etc.
我的票控制器
@RestController
public class TicketController
private final TicketRepository repository;
private final TicketResourceAssembler assembler;
TicketController(TicketRepository repository, TicketResourceAssembler assembler)
this.repository = repository;
this.assembler = assembler;
@GetMapping("/tickets/id")
public EntityModel<Ticket> one(@PathVariable Long id)
Ticket ticket = repository.findById(id).orElseThrow(() -> new EntityNotFoundException(Ticket.class, "id", id.toString()));
return assembler.toModel(ticket);
汇编器
@Component
public class TicketResourceAssembler implements RepresentationModelAssembler<Ticket, EntityModel<Ticket>>
@Override
public EntityModel<Ticket> toModel(Ticket ticket)
EntityModel<Ticket> ticketResource = new EntityModel<>(ticket,
linkTo(methodOn(TicketController.class).one(ticket.getId())).withSelfRel(),
linkTo(methodOn(TicketController.class).all()).withRel("tickets"));
return ticketResource;
存储库只是一个扩展至JpaRepository
的接口。
【问题讨论】:
你想如何在 api 请求中传递枚举? @GolamMazidSajib 使用名称 (IN_PROCESS, ON_HOLD
)
那么你只能使用@JsonGetter注解。在机票类...@JsonGetter public JsonNode getStatus() return JsonNodeFactory.instance.objectNode().put("id",status.getName()).put("value",status.getValue());
【参考方案1】:
需要添加getName()
方法枚举类:
public enum Status
OPEN("Open"),
IN_PROCESS("In Process"),
ON_HOLD("On Hold"),
RESOLVED("Resolved");
private String status;
Status(String status)
this.status = status;
public String getName()
return this.name();
@JsonValue
public String getStatus()
return status;
现在您需要在 Ticket 类中为状态添加 @JsonGetter 方法:
@JsonGetter
public JsonNode getStatus()
return JsonNodeFactory.instance.objectNode().put("id",status.getName()).put("value",status.getValue());
【讨论】:
添加后,如何使用getStatus()
比较值?我的一些代码现在显示错误Incompatible operand types JsonNode and Status
,这些是比较代码,如if (ticket.getStatus() == Status.RESOLVED)
我明白了...所以我将有 2 个字段,一个只是一个枚举值,另一个返回一个带有 id
和 value
的 json 对象?
在序列化jackson期间找到@JsonGetter方法...如果没有找到则搜索默认getter方法...所以你需要设置getter方法...或者你可以使用自定义序列化【参考方案2】:
我建议的一个不错的解决方案是使用@JsonProperty
。
public enum Status
@JsonProperty("LORA/TRACK_RFID")
IN_PROCESS("In Process");
通过使用这个注解,我们只是告诉 Jackson 将 @JsonProperty
的值映射到使用这个值注解的对象。
由于上述声明,将有字符串:"In Process"
【讨论】:
以上是关于将枚举名称和字符串值作为 api 响应返回的主要内容,如果未能解决你的问题,请参考以下文章