user3529850
user3529850

Reputation: 976

Spring map Enum in @RequestBody

In my controller I made an endpoint that allows status change:

@RequestMapping(value = "{ids}" + "/" + "status", method = RequestMethod.PUT)
public ResponseEntity<Void> changeStatus(@PathVariable final List<Integer> ids,
                                         @NotNull @RequestBody final String status) {
    deviceService.updateStatus(ids, status);
    return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

And enum looks like this:

public enum DeviceStatus {
    ACTIVE, INACTIVE, DELETED, ARCHIVED;

    @JsonCreator
    public static DeviceStatus parseWithValidation(String status) {
        final String upperCaseStatus = status.toUpperCase();
        if (exists(upperCaseStatus)) {
            return DeviceStatus.valueOf(upperCaseStatus);
        } else {
            throw new UnsupportedStatusException();
        }
    }

    private static boolean exists(final String upperCaseStatus) {
        return Arrays.stream(values()).anyMatch(c -> c.name().equals(upperCaseStatus));
    }
}

But Device domain object has a field Status of type DeviceStatus, so how should change status:

public void updateStatus(final List<Integer> ids, final String status) {
        getByIds(ids).forEach(device -> {
            device.setStatus(status);
            update(device);
        });
    }

But there is a problem with device.setStatus(status);. I can use parseWithValidation but it doesn't make sense, because it is already done. Someone gives me {"status":"INACTIVE"} How should I parse this enum ?

Upvotes: 0

Views: 8346

Answers (1)

user180100
user180100

Reputation:

EDIT: updated see comments


Your request body is an object with one field named status of type DeviceStatus, so you can probably use your Device class

So:

class Device {
    // will be validated in the controller
    private String status;
    // getter, setter, etc
}

// with:

public enum DeviceStatus {
    ACTIVE, INACTIVE, DELETED, ARCHIVED;
}

and @RequestBody Foo foo in the controller method signature:

public ResponseEntity<Void> changeStatus(@PathVariable final List<Integer> ids, @NotNull @RequestBody final Device device) {
    try {
        deviceService.updateStatus(ids, DeviceStatus.valueOf(device.getStatus()));
    } catch(IllegalArgumentException ex) {
        // throw some custom exception. device.getStatus() was invalid
    } catch(NullPointerException ex) {
        // throw some custom exception. device.getStatus() was null
    }
    // ...

Upvotes: 3

Related Questions