crimson589
crimson589

Reputation: 1306

Returning both enum name and string value as api response

This is my enum class

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;
    }
}

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

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

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

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.
}

My TicketController

@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);
    }
}

The assembler

@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;
    }
}

The repository is just an interface that extends to JpaRepository.

Upvotes: 2

Views: 6531

Answers (2)

Radu Linu
Radu Linu

Reputation: 1261

A nice solution I suggest is using @JsonProperty.

public enum Status {

    @JsonProperty("LORA/TRACK_RFID")
    IN_PROCESS("In Process");
}

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: "In Process"

Upvotes: 0

GolamMazid Sajib
GolamMazid Sajib

Reputation: 9437

You need to add getName() method enum class:

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;
        }
    }

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

@JsonGetter
    public JsonNode getStatus() {
        return JsonNodeFactory.instance.objectNode().put("id",status.getName()).put("value",status.getValue());
    }

Upvotes: 2

Related Questions