스프링 jackson enum deserializer
json 메시지를 받는 rest api를 만들때 enum을 사용해 메시지를 받을때 하는법
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package com.github.sejoung.constants;
import static java.util.stream.Collectors.toMap;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import java.util.Map; import java.util.Objects; import java.util.stream.Stream;
public enum BreakerStatus {
RELAY_IN_OPEN("relayInOpen", "입구 열림 릴레이"), RELAY_OUT_OPEN("relayOutOpen", "출구 열림 릴레이"), RELAY_IN_CLOSE("relayInClose", "입구 닫힘 릴레이"), RELAY_OUT_CLOSE("relayOutClose", "출구 닫힘 릴레이");
private static final Map<String, BreakerStatus> stringToEnum = Stream.of(values()).collect(toMap(Objects::toString, e -> e));
private String code;
private String desc;
BreakerStatus(String code, String desc) { this.code = code; this.desc = desc; }
@JsonCreator public static BreakerStatus fromString(String symbol) { return stringToEnum.get(symbol); }
@JsonValue public String getCode() { return code; }
public String getDesc() { return desc; } }
|
위에 enum 객체가 있는데 이부분에서 @JsonCreator
와 @JsonValue
를 사용하여 직렬화와 역직렬화를 하게 된다
컨트롤러를 보면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.github.sejoung.controller;
import com.github.sejoung.model.BreakerMessage; import javax.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;
@RestController public class BreakerAPIController {
private static final Logger log = LoggerFactory.getLogger(BreakerAPIController.class);
@RequestMapping(value = "/parkingBreaker", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) public void parkingBreaker(@RequestBody @Valid BreakerMessage message) { log.debug("parkingBreaker = {}", message); }
}
|
위에 처럼 코딩을 하고 BreakerMessage를 받게 되는데 BreakerMessage 는
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.github.sejoung.model;
import com.github.sejoung.constants.BreakerStatus; import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.ToString;
@ToString @Getter public class BreakerMessage {
@NotNull private BreakerStatus event;
}
|
위에 처럼 BreakerStatus enum으로 구성되있다. 그럼 테스트 코드를 짜서 보면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| package com.github.sejoung.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.github.sejoung.constants.BreakerStatus; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public class BreakerAPIControllerTest {
private final String breakerAPIControllerParkingBreakerUrl = "/parkingBreaker";
@Autowired private MockMvc mockMvc;
@Test public void parkingBreakerIsOk() throws Exception { this.mockMvc.perform(post(breakerAPIControllerParkingBreakerUrl) .content("{\"event\":\"" + BreakerStatus.RELAY_IN_CLOSE.toString() + "\"}") .contentType(MediaType.APPLICATION_JSON_UTF8)) .andDo(print()) .andExpect(status().isOk()); }
@Test public void parkingBreakerNoEvent() throws Exception { this.mockMvc.perform(post(breakerAPIControllerParkingBreakerUrl) .content("{\"event\":\"\"}") .contentType(MediaType.APPLICATION_JSON_UTF8)) .andDo(print()) .andExpect(status().isBadRequest()); }
@Test public void parkingBreakerBadEvent() throws Exception { this.mockMvc.perform(post(breakerAPIControllerParkingBreakerUrl) .content("{\"event\":\"test\"}") .contentType(MediaType.APPLICATION_JSON_UTF8)) .andDo(print()) .andExpect(status().isBadRequest()); } }
|
이렇게 해서 볼수 있는데 잘못된 코드를 넘어 왔을때와 값을 않넣었을때 를 테스트 해서 볼수 있다.
참조