返回枚举名称和字符串值作为 API 响应。

huangapple go评论115阅读模式
英文:

Returning both enum name and string value as api response

问题

这是我的枚举类:

  1. public enum Status {
  2. OPEN("Open"),
  3. IN_PROCESS("In Process"),
  4. ON_HOLD("On Hold"),
  5. RESOLVED("Resolved");
  6. private String status;
  7. Status(String status) {
  8. this.status = status;
  9. }
  10. @JsonValue
  11. public String getStatus() {
  12. return status;
  13. }
  14. }

我的 API 目前将 Status 的值作为字符串返回,以下是部分 JSON 响应示例:{"id":1,"name":"John","subject":"Help","status":"Open"}

我希望响应的格式变成类似这样:{"status": {"id": "ON_HOLD", "value": "On Hold"}}

使用枚举状态的模型,省略了部分内容:

  1. public class Ticket {
  2. private @Id @GeneratedValue(strategy=GenerationType.IDENTITY) Long id;
  3. private String name;
  4. private String subject;
  5. @Enumerated(EnumType.STRING)
  6. private Status status;
  7. //getters, setters, 等等
  8. }

我的 TicketController:

  1. @RestController
  2. public class TicketController {
  3. private final TicketRepository repository;
  4. private final TicketResourceAssembler assembler;
  5. TicketController(TicketRepository repository, TicketResourceAssembler assembler) {
  6. this.repository = repository;
  7. this.assembler = assembler;
  8. }
  9. @GetMapping("/tickets/{id}")
  10. public EntityModel<Ticket> one(@PathVariable Long id) {
  11. Ticket ticket = repository.findById(id).orElseThrow(() -> new EntityNotFoundException(Ticket.class, "id", id.toString()));
  12. return assembler.toModel(ticket);
  13. }
  14. }

装配器:

  1. @Component
  2. public class TicketResourceAssembler implements RepresentationModelAssembler<Ticket, EntityModel<Ticket>> {
  3. @Override
  4. public EntityModel<Ticket> toModel(Ticket ticket) {
  5. EntityModel<Ticket> ticketResource = new EntityModel<>(ticket,
  6. linkTo(methodOn(TicketController.class).one(ticket.getId())).withSelfRel(),
  7. linkTo(methodOn(TicketController.class).all()).withRel("tickets"));
  8. return ticketResource;
  9. }
  10. }

Repository 只是一个继承自 JpaRepository 的接口。

英文:

This is my enum class

  1. public enum Status {
  2. OPEN(&quot;Open&quot;),
  3. IN_PROCESS(&quot;In Process&quot;),
  4. ON_HOLD(&quot;On Hold&quot;),
  5. RESOLVED(&quot;Resolved&quot;);
  6. private String status;
  7. Status(String status) {
  8. this.status = status;
  9. }
  10. @JsonValue
  11. public String getStatus() {
  12. return status;
  13. }
  14. }

My api is currently returning the value of Status as a string, here's a part of the json response returned. {&quot;id&quot;:1,&quot;name&quot;:&quot;John&quot;,&quot;subject&quot;:&quot;Help&quot;,&quot;status&quot;:&quot;Open&quot;}

How do i make my response something like {&quot;status&quot;: {&quot;id&quot;: &quot;ON_HOLD&quot;, &quot;value&quot;: &quot;On Hold&quot;}}

This is the model using the enum status, some parts omitted.

  1. public class Ticket {
  2. private @Id @GeneratedValue(strategy=GenerationType.IDENTITY) Long id;
  3. private String name;
  4. private String subject;
  5. @Enumerated(EnumType.STRING)
  6. private Status status;
  7. //getters, setters, etc.
  8. }

My TicketController

  1. @RestController
  2. public class TicketController {
  3. private final TicketRepository repository;
  4. private final TicketResourceAssembler assembler;
  5. TicketController(TicketRepository repository, TicketResourceAssembler assembler) {
  6. this.repository = repository;
  7. this.assembler = assembler;
  8. }
  9. @GetMapping(&quot;/tickets/{id}&quot;)
  10. public EntityModel&lt;Ticket&gt; one(@PathVariable Long id) {
  11. Ticket ticket = repository.findById(id).orElseThrow(() -&gt; new EntityNotFoundException(Ticket.class, &quot;id&quot;, id.toString()));
  12. return assembler.toModel(ticket);
  13. }
  14. }

The assembler

  1. @Component
  2. public class TicketResourceAssembler implements RepresentationModelAssembler&lt;Ticket, EntityModel&lt;Ticket&gt;&gt; {
  3. @Override
  4. public EntityModel&lt;Ticket&gt; toModel(Ticket ticket) {
  5. EntityModel&lt;Ticket&gt; ticketResource = new EntityModel&lt;&gt;(ticket,
  6. linkTo(methodOn(TicketController.class).one(ticket.getId())).withSelfRel(),
  7. linkTo(methodOn(TicketController.class).all()).withRel(&quot;tickets&quot;));
  8. return ticketResource;
  9. }
  10. }

The repository is just an interface that extends to JpaRepository.

答案1

得分: 1

你需要在枚举类中添加 getName() 方法:

  1. public enum Status {
  2. OPEN("Open"),
  3. IN_PROCESS("In Process"),
  4. ON_HOLD("On Hold"),
  5. RESOLVED("Resolved");
  6. private String status;
  7. Status(String status) {
  8. this.status = status;
  9. }
  10. public String getName() {
  11. return this.name();
  12. }
  13. @JsonValue
  14. public String getStatus() {
  15. return status;
  16. }
  17. }

然后,在 Ticket 类中添加 @JsonGetter 方法用于获取状态:

  1. @JsonGetter
  2. public JsonNode getStatus() {
  3. return JsonNodeFactory.instance.objectNode()
  4. .put("id", status.getName())
  5. .put("value", status.getStatus());
  6. }
英文:

You need to add getName() method enum class:

  1. public enum Status {
  2. OPEN(&quot;Open&quot;),
  3. IN_PROCESS(&quot;In Process&quot;),
  4. ON_HOLD(&quot;On Hold&quot;),
  5. RESOLVED(&quot;Resolved&quot;);
  6. private String status;
  7. Status(String status) {
  8. this.status = status;
  9. }
  10. public String getName() {
  11. return this.name();
  12. }
  13. @JsonValue
  14. public String getStatus() {
  15. return status;
  16. }
  17. }

Now you need to add @JsonGetter method for status in Ticket class:

  1. @JsonGetter
  2. public JsonNode getStatus() {
  3. return JsonNodeFactory.instance.objectNode().put(&quot;id&quot;,status.getName()).put(&quot;value&quot;,status.getValue());
  4. }

答案2

得分: 0

一个不错的解决方案是使用@JsonProperty

  1. public enum Status {
  2. @JsonProperty("LORA/TRACK_RFID")
  3. IN_PROCESS("In Process");
  4. }

通过使用这个注解,我们只需告诉Jackson将@JsonProperty的值映射到带有此值注释的对象。

由于上述声明的结果,将得到字符串:"In Process"

英文:

A nice solution I suggest is using @JsonProperty.

  1. public enum Status {
  2. @JsonProperty(&quot;LORA/TRACK_RFID&quot;)
  3. IN_PROCESS(&quot;In Process&quot;);
  4. }

By using this annotation, we are simply telling Jackson to map the value of the @JsonProperty to the object annotated with this value.

As a result of the above declaration, will have the string: &quot;In Process&quot;

huangapple
  • 本文由 发表于 2020年5月3日 14:16:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/61570375.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定