0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SpringBootでWebAPIを作ったら、JSONのキーが大文字の時にパースできない

Last updated at Posted at 2024-04-17

何があったの?

SpringBootでWebAPIを作って、HTTPリクエストでJSONを飛ばしたら、なんかJSONのキーが大文字の時だけControllerの引数にパースできずにNullになってしまったよ。

JSONのキーを小文字にしたらなんか行けた。なんでや。
もう上司に「大文字でやるわ」って仕様書出しちゃったから今から「やっぱり小文字にしたいっす」って言いにくい。なんとかして。

解決策

application.propertiesに下記一行追加するだけ。
大文字小文字関係なくパースしてくれるようになるよ。
やや大味な解決策だけど、まぁ大丈夫でしょ。

application.properties
spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=true

確認

バージョン

SpringBoot: 3.2.4

デフォルトの確認

application.config
spring.application.name=demo
# spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=true 解決策をコメントアウト
Otacon.java
package com.example.demo;

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/OtaAPI")
public class Otacon {
    @PostMapping("/json2api")
    public ResponseEntity<String> json1(@RequestBody Input2 input) {
        return ResponseEntity.ok(enabled() + input.toString());
    }

    private String enabled() {
        ObjectMapper objectMapper = new ObjectMapper();
        boolean accept = objectMapper.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
        String result = "***ACCEPT_CASE_INSENSITIVE_PROPERTIES:" + (accept ? "true": "false") + "*** ";
        return result;
    }

    @Data
    public static class Input2 {
        private Inner key1;
        private String KEY2;
    }

    @Data
    public static class Inner {
        private String key1_1;
        private String KEY1_2;
    }

}
Terminal
>curl http://localhost:8080/OtaAPI/json2api -X POST -d "{\"key1\":{\"key1_1\":\"キー1\",\"key1_2\":\"キー1_2\"},\"key2\":\"キー2\"}" -H "Content-Type: application/json" 
***ACCEPT_CASE_INSENSITIVE_PROPERTIES:false*** Otacon.Input2(key1=Otacon.Inner(key1_1=キー1, KEY1_2=キー1_2), KEY2=キー2)
>curl http://localhost:8080/OtaAPI/json2api -X POST -d "{\"KEY1\":{\"KEY1_1\":\"キー1\",\"KEY1_2\":\"キー1_2\"},\"KEY2\":\"キー2\"}" -H "Content-Type: application/json" 
***ACCEPT_CASE_INSENSITIVE_PROPERTIES:false*** Otacon.Input2(key1=null, KEY2=null)
  • JSONのキーとJavaフィールド名の大文字小文字を合わせないとパースできないよ
  • SpringBootはデフォルトで大文字小文字の区別は無視する設定だから大丈夫だよ

という説明をどこかで見た気がするが、いずれも間違っていることが確認できたよ。

実証結果として、デフォルトでは以下の通りの動きとなった。

  • JSONのキーとJavaフィールド名は、大文字小文字の区別なくパースしてくれるよ。
  • JSONのキーが大文字の時は、Javaフィールド名がどうあろうとパースはしないよ。

application.propertiesに設定した場合の確認

application.config
spring.application.name=demo
spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=true
Otacon.java
// 変更ないので省略するよ
Terminal
>curl http://localhost:8080/OtaAPI/json2api -X POST -d "{\"key1\":{\"key1_1\":\"キー1\",\"key1_2\":\"キー1_2\"},\"key2\":\"キー2\"}" -H "Content-Type: application/json" 
***ACCEPT_CASE_INSENSITIVE_PROPERTIES:false*** Otacon.Input2(key1=Otacon.Inner(key1_1=キー1, KEY1_2=キー1_2), KEY2=キー2)
>curl http://localhost:8080/OtaAPI/json2api -X POST -d "{\"KEY1\":{\"KEY1_1\":\"キー1\",\"KEY1_2\":\"キー1_2\"},\"KEY2\":\"キー2\"}" -H "Content-Type: application/json" 
***ACCEPT_CASE_INSENSITIVE_PROPERTIES:false*** Otacon.Input2(key1=Otacon.Inner(key1_1=キー1, KEY1_2=キー1_2), KEY2=キー2)

spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=trueを設定することで以下の通りとなった

  • JSONのキーとJavaフィールド名は、大文字小文字の区別なくパースしてくれるよ。
  • JSONのキーが大文字の時もパースしてくれるよ。

蛇足

application.propertiesで上記設定を有効にすると、

ObjectMapper objectMapper = new ObjectMapper();
boolean accept = objectMapper.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);

で true が返るものだと思っていたけど、違ったみたい。
意味なかったねこのコード。

おわるよ。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?