こんにちは。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]
