こんにちは。ITです。
今回は、JSONのレスポンスをenum列挙型にマッピングする方法です。
Jackson JSON Processorで、下記のようにJSONのレスポンスをResponseJsonクラスにマッピングしてみます。
・JSONのレスポンスbody内容
[code] {"stringParameter":"HOGE","enumParameter":"1"} [/code]
・JSONのレスポンスbodyをResponseJsonクラスにマッピング
[code] CloseableHttpResponse response = httpClient.execute(request); HttpEntity entity = response.getEntity(); byte[] body = EntityUtils.toByteArray(entity); ResponseJson responseJson = OBJECT_MAPPER.readValue(body, ResponseJson.class); [/code]
・ResponseJsonクラス
[code] @JsonIgnoreProperties(ignoreUnknown = true) public class ResponseJson implements Serializable { private static final long serialVersionUID = 3030664960834078285L; private String stringParameter; private EnumParameter enumParameter; public String getStringParameter() { return stringParameter; } public void setStringParameter(String stringParameter) { this.stringParameter = stringParameter; } public EnumParameter getEnumParameter() { return enumParameter; } public void setEnumParameter(EnumParameter enumParameter) { this.enumParameter = enumParameter; } [/code]
・enum列挙型
[code] public enum EnumParameter { TOKYO("東京", "1"), OSAKA("大阪", "2"); private String name; private String code; CouponRewardCode(String name, String code) { this.name = name; this.code = code; } public String getName() { return name; } public String getCode() { return code; } public static EnumParameter get(String code) { for (EnumParameter enumCode : EnumParameter.values()) { if (StringUtils.equals(enumCode.getCode(), code)) { return enumCode; } } return null; } } [/code]
意図としてはレスポンスの「”enumParameter”:”1″」がResponseJsonのenumParameterに「TOKYO(“東京”, “1”)」と設定されてほしいのですが
[code] Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.globalrelay.gas.appsjson.authportal.Event from String value 'enumParameter': value not one of declared Enum instance names [/code]
というエラーが発生します。
その場合、下記の通りDeserializerを定義し、enumクラスに「@JsonDeserialize(using = EnumParameterDeserializer.class)」アノテーションを設定することで、
code(”1″)が来たら、enumValue(TOKYO(“東京”, “1”))が設定されるようにできます。
[code] public class EnumParameterDeserializer extends JsonDeserializer<Object> { @Override public EnumParameter deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { final String jsonValue = jp.getText(); for (final EnumParameter enumValue : EnumParameter.values()) { if (enumValue.getCode().equals(jsonValue)) { return enumValue; } } return null; } } [/code]
逆にSerializerも可能です。
[code] public class EnumParameterSerializer extends JsonSerializer<CouponRewardCode> { @Override public void serialize(EnumParameter value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeString(value.getCode()); } } [/code]