1
2

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.

Spring で既存のBeanをいじらずにJSONへの出力内容を調整

Last updated at Posted at 2024-08-24

はじめに

DAOから取得した既存のBeanのデータをそのままレスポンスにJSONとして出力したいけど、いらない項目があったり、出力形式を少し変更したり、プロパティ名を変更したりしたい、ということがあるかと思います。
そんな場合の対処法を紹介します。

やり方

まず、以下のよな既存のBeanがあったとします。

既存のBean
@Data
public class User {
    String userId;
    String userName;
    String password;
    Date birthday;
}

上記のうち、userNameは、nameというプロパティ名で、birthdayは"yyyy/mm/dd"形式で、そして、passwordは出力したくない、というケースがあったとします。
そういう場合の例です。

コントローラー
@RestController
@Transactional
public class UserListController {

	@Inject
	private userMapper userMapper;

    // produces属性に"application/json;charset=UTF-8"を追加しないと日本語文字列が文字化けする
	@PostMapping(path = "/userlist", produces = "application/json;charset=UTF-8")
	public String userList() throws JsonProcessingException {

		List<User> users = UserMapper.selectAll();

		ObjectMapper mapper = new ObjectMapper();
		// Userで定義されている項目について、JSONに出力する項目定義を追加する
		mapper.addMixIn(User.class, UserView.class);
		return mapper.writeValueAsString(users);
	}

    // JSONに出力する項目の定義
	static abstract class UserView {

        // 出力しないフィールド
		@JsonIgnore
		String password;

        // 出力パターンを指定
		@JsonFormat(pattern = "yyyy/MM/dd", timezone = "Asia/Tokyo")
		String birthday;

        // 出力するプロパティ名を指定
		@JsonProperty("name")
        String userName
	}
}

こんな感じで、JSONに出力する項目定義用の抽象クラスを作成して、ObjectMapper#addMixIn(既存Bean.class,作成した定義クラス.class)を実行して、writeValueAsStringメソッドでJSON文字列を生成すればOKです。
注意点としては、RequestMapping(GetMapping,PostMapping)の属性にproduces = "application/json;charset=UTF-8"を付与しないと、日本語文字列が文字化けしてしまうので、別途指定が必要ということです。

なお、上記抽象クラスは、以下のようなインタフェースでも可能です。

	static interface UserView {

		@JsonIgnore
		String getPassword();

		@JsonFormat(pattern = "yyyy/MM/dd", timezone = "Asia/Tokyo")
		String getBirthday();
  
		@JsonProperty("name")
        String getUserName();
 }

実行すると、こんな感じのJSON文字列がレスポンスに出力されます。

{
    "userId": "yamada",
    "name": "山田 太郎",
    "birthday": "2000/03/05"
},
{
    "userId": "sato",
    "name": "佐藤 花子",
    "birthday": "2000/05/09"
}

余談

  • JsonFormatアノテーションのtimezoneの指定をしないと、デフォルトでUTCが適用されてしまうので必須。デフォルトのタイムゾーンを適用してくれないので注意
  • Spring Bootの場合は、@JsonMixinを使用すれば、ObjectMapperのインスタンスを生成する作業以降を行わなくても出来そうだが、Spring MVCでは未対応っぽい

Beanの編集OKで同じBeanを複数処理で使いまわす場合

JsonViewを利用する方法があります。
以下のサイトに説明があります。

参考サイト

以下のサイトを参考にしました。

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?