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?

【Jakarta Validation】メッセージ内の項目名をカスタマイズしたい!

0
Last updated at Posted at 2026-04-13

結論

ecuacion-lib-validation では、Item#itemNameKey(String) または @ItemNameKeyClass を使うことで、メッセージに表示される項目名のキーをカスタマイズできます、というお話。

はじめに

ecuacion-lib-validationExceptionUtil.getMessageList でメッセージを生成する際、項目名は messages.properties または item_names.properties のキーで管理します。

デフォルトでは、クラス名(アンキャピタライズ)とフィールド名を . でつないだキーが使用されます。

例えば OrderForm クラスの productCode フィールドであれば orderForm.productCode というキーになります。

messages.properties
orderForm.productCode=商品コード

これで十分な場面も多いのですが、「フィールド名は productCode だけど、メッセージには 商品名 と表示したい」というケースが出てきます。

ecuacion-lib-validation では、ItemItemContainer の仕組みでこれを解決できます。

ecuacion-lib-validation の導入方法

導入方法については下記記事をご参照ください。

ItemContainer の実装

項目名をカスタマイズするには、対象のクラスに ItemContainer インターフェースを実装します。

OrderForm.java
public record OrderForm(@NotEmpty String productCode, @NotNull Integer qty)
    implements ItemContainer {

  @Override
  public Item[] customizedItems() {
    return new Item[] {new Item("productCode").itemNameKey("productName")};
  }
}

customizedItems() に、カスタマイズしたい項目を Item オブジェクトの配列で返します。

Item オブジェクトの取得は、ItemContainer#getItem を使用します。ただし customizedItems() 内では new Item(...) で定義し、実際の利用は getItem 経由で行われます。

Item#itemNameKey(String) の使い方

ドットなし:フィールド部分だけ変更

itemNameKey の引数に . を含まない文字列を渡した場合、フィールド部分だけが変更され、クラス部分はデフォルト(クラス名のアンキャピタライズ)が使用されます。

OrderForm.java
public record OrderForm(@NotEmpty String productCode, @NotNull Integer qty)
    implements ItemContainer {

  @Override
  public Item[] customizedItems() {
    return new Item[] {new Item("productCode").itemNameKey("productName")};
  }
}

getItem("productCode").getItemNameKey(form) で解決後のキーを確認できます。

Main.java(一部抜粋)
  public static void itemNameKeyの使用_ドットなし() {
    OrderForm form = new OrderForm(null, null);
    System.out.println("getItem: " + form.getItem("productCode").getItemNameKey(form));

    try {
      MessageParameters params = ValidationUtil.messageParameters().isMessageWithItemName(true);
      ValidationUtil.validateThenThrow(form, params);
    } catch (ConstraintViolationException ex) {
      for (String message : ExceptionUtil.getMessageList(ex, false)) {
        System.out.println(message);
      }
    }
  }

messages.properties に以下を定義します。

messages.properties
orderForm.productName=商品名
orderForm.qty=数量
出力結果
getItem: orderForm.productName
「商品名」は入力必須です。
「数量」は入力必須です。

productCode フィールドのキーが orderForm.productCode から orderForm.productName に変わりました。クラス部分 orderForm はそのままで、フィールド部分だけが productName に変わっています。

ドットあり:クラス部分も明示指定

itemNameKey の引数に . を含む文字列を渡した場合、クラス部分とフィールド部分の両方が明示指定されます。

OrderFormWithDot.java
public record OrderFormWithDot(@NotEmpty String productCode, @NotNull Integer qty)
    implements ItemContainer {

  @Override
  public Item[] customizedItems() {
    return new Item[] {new Item("productCode").itemNameKey("product.name")};
  }
}
Main.java(一部抜粋)
  public static void itemNameKeyの使用_ドットあり() {
    OrderFormWithDot form = new OrderFormWithDot(null, null);
    System.out.println("getItem: " + form.getItem("productCode").getItemNameKey(form));

    try {
      MessageParameters params = ValidationUtil.messageParameters().isMessageWithItemName(true);
      ValidationUtil.validateThenThrow(form, params);
    } catch (ConstraintViolationException ex) {
      for (String message : ExceptionUtil.getMessageList(ex, false)) {
        System.out.println(message);
      }
    }
  }

messages.properties に以下を定義します。

messages.properties
product.name=商品名
orderFormWithDot.qty=数量
出力結果
getItem: product.name
「数量」は入力必須です。
「商品名」は入力必須です。

キーが product.name となり、クラス名に依存しない完全な指定になっています。

「商品」エンティティ共通の定義(product.name=商品名)を複数の form クラスから参照したい場合などに有効です。

まとめ:ドットなし vs ドットあり

指定例 クラス部分 フィールド部分 解決後のキー
itemNameKey("productName") クラス名から自動 (orderForm) productName orderForm.productName
itemNameKey("product.name") 明示指定 (product) name product.name

@ItemNameKeyClass の使い方

@ItemNameKeyClass はクラスに付加するアノテーションで、そのクラス全フィールドのデフォルトのクラス部分を上書きします。

クラス名が長い、またはデフォルトのクラス名がキーとして適切でない場合に有効です。

OrderFormWithAnnotation.java
@ItemNameKeyClass("order")
public record OrderFormWithAnnotation(@NotEmpty String productCode, @NotNull Integer qty)
    implements ItemContainer {

  @Override
  public Item[] customizedItems() {
    return new Item[] {};
  }
}
Main.java(一部抜粋)
  public static void ItemNameKeyClassの使用() {
    OrderFormWithAnnotation form = new OrderFormWithAnnotation(null, null);
    System.out.println("getItem: " + form.getItem("productCode").getItemNameKey(form));

    try {
      MessageParameters params = ValidationUtil.messageParameters().isMessageWithItemName(true);
      ValidationUtil.validateThenThrow(form, params);
    } catch (ConstraintViolationException ex) {
      for (String message : ExceptionUtil.getMessageList(ex, false)) {
        System.out.println(message);
      }
    }
  }

messages.properties に以下を定義します。

messages.properties
order.productCode=商品コード
order.qty=数量
出力結果
getItem: order.productCode
「商品コード」は入力必須です。
「数量」は入力必須です。

OrderFormWithAnnotation のクラス名由来の orderFormWithAnnotation ではなく、order がクラス部分として使われました。

@ItemNameKeyClass はクラス全体のデフォルトを変えるものです。個別フィールドの itemNameKey 指定が優先されます。

サンプルコード

サンプルコードは以下です。
https://github.com/ecuacion-jp/ecuacion-code-snippets/tree/main/ecuacion-lib-core-JakartaValidationItemNameKey

※このページから直接ソースの zip を download はできないと思うので、そのページにある ecuacion-code-snippets のリンクをクリックし、そこにある緑の <> Code ボタンから Download ZIP で download してください。

本サンプルのフォルダに移動後、mvn compile exec:java で実行できます。

まとめ

ecuacion-lib-validation でメッセージの項目名をカスタマイズする2つの方法のご紹介でした。

方法 用途
itemNameKey("fieldOnly") フィールド部分だけ変更、クラス部分はデフォルト
itemNameKey("class.field") クラス部分とフィールド部分を両方明示指定
@ItemNameKeyClass("className") クラス全体のデフォルトクラス部分を変更
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?