LoginSignup
8
8

More than 5 years have passed since last update.

Spring-bootでRequestBodyのEnumをデシリアライズする

Posted at

概要

EnumをメンバーにもったJavaBeanをRequestBodyとして送り
Controllerでデシリアライズされるところまでを試しました。

環境

※ Thymeleafが少し古いです

Module Version
spring-boot 1.5.1.RELEASE
thymeleaf 3.0.1.RELEASE
thymeleaf-layout-dialect 2.0.1

どうやったか

Enumを作る

今回はOFF/ON定数を持ったFlagというEnumを作ります。
それぞれ数値フィールド0/1を定義しています。
また、数値フィールドの値から定数を判別メソッドも用意しています。

public enum Flag {
    OFF(0),
    ON(1);

    private int value;

    Flag(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public static Flag parse(int value) {
        return Arrays.stream(Flag.values())
                .filter(flag -> flag.getValue() == value)
                .findFirst()
                .orElseGet(() -> Flag.OFF);
    }
}

Modelを作る

前述のEnumをメンバーにもったModelです。

public class Sample {
    private String hoge;
    private Long fuga;
    private Flag flag;

    // アクセサメソッドは省略
}

Controllerを作る

作成したModelをRequestBodyとして受け取るControllerです。
/にGETアクセスすると後述のテンプレートを表示し、
/logにPOSTアクセスすると、RequestBodyの値をSystem.outしています。

@Controller
@RequestMapping("/")
public class SampleController {
    @GetMapping
    public String index() {
        return "sample";
    }

    @PostMapping("log")
    public String log(@RequestBody Sample sample) {
        System.out.println("hoge = " + sample.getHoge());
        System.out.println("fuga = " + sample.getFuga());
        System.out.println("flag = " + sample.getFlag());

        return "redirect:sample";
    }
}

Deserializerを作る

今回のメイン。Requestで受け取った値からObjectにデシリアライズする処理を書くところです。
受け取った値を実際にデシリアライズする処理をcom.fasterxml.jackson.databind.JsonDeserializerを継承して作成します。

class FlagDeserializer extends JsonDeserializer<Flag> {

    @Override
    public Flag deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {
        final int jsonValue = jsonParser.getIntValue();
        return Flag.parse(jsonValue);
    }
}

そして作成したDeserializerをBeanとして定義します。

@Configuration
public class JsonConfiguration {
    /**
     * JSON<->Enum間の変換Moduleを登録します
     * @return {@link ObjectMapper}
     */
    @Bean
    public ObjectMapper jsonObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(generateFlagModule());
        return mapper;
    }

    private Module generateFlagModule() {
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addDeserializer(Flag.class, new FlagDeserializer());
        return simpleModule;
    }
}

テンプレートを作る

Requestを送るためだけのThymeleafテンプレートです。
ブラウザにはsendボタンだけ表示されます。

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xml:lang="ja" lang="ja">
<head>
</head>
<body>
<input type="button" value="send" id="send" name="send">
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        $('#send').on('click', function () {
            $.ajax({
                type: 'post',
                url: '/log',
                data: JSON.stringify(
                        {
                            "hoge": "hoge",
                            "fuga": 123,
                            "flag": 1
                        }
                ),
                dataType: 'json',
                contentType: 'application/JSON',
                scriptCharset: 'utf-8'
            }).done(function (data) {
                console.log(data);
            });
        })
    });
</script>
</body>
</html>

結果

アプリを起動してブラウザでsendボタンを押すと、コンソールに次のように表示されます。

hoge = hoge
fuga = 123
flag = ON

サンプルコード

ここに今回作成したサンプルを置いています。
https://github.com/panage/enum-serialize-demo

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8