Home > Mobile >  How to convert String to Enum using both Jackson and Spring bindings without code duplication
How to convert String to Enum using both Jackson and Spring bindings without code duplication

Time:11-04

I have an enum defined as:

public static enum State {
    
    @JsonProperty("At Rest")
    AT_REST,
    
    @JsonProperty("In Motion")
    IN_MOTION, 
    
    @JsonProperty("Stalled")
    STALLED;        
} 

So, the server produces "At Rest" when Jackson serializes the AT_REST enum into JSON. Similarly, Jackson deserializes "At Rest" into AT_REST when the client passes JSON to the server. For example:

@GetMapping()
public State[] getAllStates() {
 return State.values(); //returns JSON ["At Rest", "In Motion", "Stalled"]
}

@PostMapping()
public void saveState(@ResponseBody State state /*when client sends "At Rest", it gets converted into Enum*/) { 
 //save state
}

I also have a search GET endpoint. The client calls it with a "state" query parameter such https://localhost/search?state=At Rest. Since the query parameter value is not JSON, I have a Spring converter:

@Component
public class StringToStateConverter implements Converter<String, State> {
    
    @Override
    public State convert(String description) {
        if ("At Rest".equals(description)) {
            return State.AT_REST;
        } else if ("In Motion".equals(description)) {
            return State.IN_MOTION;
        } else if ("Stalled".equals(description)) {
            return State.STALLED;
        } else {
            return null;
        }
    }
    
}

Is it possible to have Spring use JsonProperty when deserializing a query param? If not, how can I avoid having the String description in multiple places in my code? I prefer not to make a description field in the enum since this is really just for client display.

CodePudding user response:

Is it possible to have Spring use JsonProperty when deserializing a query param?

Yes.

@Component
@RequiredArgsConstructor
public class StringToStateConverter implements Converter<String, State> {
    
    private final ObjectMapper mapper;
    
    @Override
    public State convert(String description) {
        
        try {
            return mapper.readValue("\""   description   "\"", State.class);
        } catch (JsonProcessingException e) {
            // code to return error to client
        }
}
  • Related