[解決済み] バリデーションエラーです。値が有効ではありません
質問
p:selectOneMenuで問題が発生しました。何をやってもJSFがJPAエンティティのセッターを呼び出すことができません。JSFの検証はこのメッセージで失敗します。
form:location: バリデーションエラーです。値が有効ではありません
同じタイプの他のいくつかのクラス (たとえば、結合テーブル・クラス) でこれが機能していますが、このクラスがどうしてもうまくいきません。
この種の問題に対するトラブルシューティング/デバッグのヒントを投げられる人がいれば、それは非常に感謝されます。
ログ ステートメントを使用して、私は以下を確認しました。
-
は
Conveter
は正しく、非null
の値を返します。 - JPAエンティティにBean Validationがないのですが。
-
セッターは
setLocation(Location location)
は決して呼ばれません。
これは私ができる最も単純な例ですが、単純にうまくいきません。
<h:body>
<h:form id="form">
<p:messages id="messages" autoUpdate="true" />
<p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
<p:ajax event="change" update=":form:lblLocation"/>
<f:selectItems value="#{locationStockList.locationSelection}"/>
</p:selectOneMenu>
</h:form>
</h:body>
コンバータです。
@FacesConverter(forClass=Location.class, value="locationConverter")
public class LocationConverter implements Converter, Serializable {
private static final Logger logger = Logger.getLogger(LocationConverter.class.getName());
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.isEmpty())
return null;
try {
Long id = Long.parseLong(value);
Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id);
logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location});
return location;
} catch (NumberFormatException e) {
return new Location();
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.toString().isEmpty() || !(value instanceof Location))
return "";
return String.valueOf(((Location) value).getId());
}
}
コンソール出力です。
// Getter method
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
// Session Bean
INFO: Finding ejb.locations.Location with id=3
// Session Bean
INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Converter
SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Getter method -> Where did my selected Location go ??
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
どのように解決するのですか?
<ブロッククオートバリデーションに失敗し、"form:location.Validationというメッセージが表示されます。Validation Error: 値は有効ではありません"。
このエラーは、選択された項目が、ネストされたすべての
<f:selectItem(s)>
タグで指定された値と一致しない場合に発生します。
改ざんやハッキングされたリクエストに対する安全策の一環として、JSF は利用可能なすべての選択項目の値を繰り返し、その値が
selectedItem.equals(availableItem)
が返す
true
は少なくとも一つの利用可能な項目値に対して返されます。もし、1つも一致する項目値がなければ、まさにこの検証エラーが発生します。
この処理は、基本的に以下のように隠蔽されています。
bean.getAvailableItems()
で定義された、利用可能な選択項目の全リストを架空のものとして表しています。
<f:selectItem(s)>
:
String submittedValue = request.getParameter(component.getClientId());
Converter converter = component.getConverter();
Object selectedItem = (converter != null) ? converter.getAsObject(context, component, submittedValue) : submittedValue;
boolean valid = false;
for (Object availableItem : bean.getAvailableItems()) {
if (selectedItem.equals(availableItem)) {
valid = true;
break;
}
}
if (!valid) {
throw new ValidatorException("Validation Error: Value is not valid");
}
ということで、上記のロジックから、この問題は論理的に少なくとも以下の原因が考えられます。
- 選択した項目が、使用可能な項目のリストにない。
-
は
equals()
メソッドが存在しないか、壊れています。 -
もしカスタム
Converter
が含まれている場合、それは間違ったオブジェクトをgetAsObject()
. おそらくそれはnull
.
それを解決するために
-
特に複数のカスケードメニューの場合、後続のリクエストで全く同じリストが保存されていることを確認する。ビーンを作成する
@ViewScoped
の代わりに@RequestScoped
に変更することで、ほとんどの場合解決するはずです。のゲッターメソッドでビジネスロジックを実行しないことも確認してください。<f:selectItem(s)>
のゲッターメソッドでビジネスロジックを実行せず、代わりに@PostConstruct
またはアクションイベント (リスナー) メソッドに格納します。もし特定のリクエストパラメータに依存しているのなら、明示的に@ViewScoped
ビーンに格納するか、あるいは次のリクエストの際に例えば<f:param>
. また 正しいビーンスコープを選択する方法は? -
が正しいことを確認します。
equals()
メソッドが正しく実装されていることを確認します。これはすでに、標準的な Java の型であるjava.lang.String
,java.lang.Number
などがありますが、必ずしもカスタムオブジェクト/ビーン/エンタイトルに当てはまるとは限りません。また イコールコントラクトを実装する正しい方法 . すでにString
を使用している場合、リクエストの文字エンコーディングが正しく設定されていることを確認してください。もし特殊文字が含まれていて、JSFが出力をUTF-8としてレンダリングし、入力を例えばISO-8859-1として解釈するように設定されている場合は、失敗します。a.o. も参照してください。 PrimeFaces入力コンポーネントで取得されたUnicode入力が破損する . -
カスタム
Converter
の動作をデバッグし、それに応じて修正します。ガイドラインについては コンバージョンエラー 'ヌルコンバーター'の値設定 を使用している場合java.util.Date
で利用可能な項目として<f:convertDateTime>
のように、フルタイムの部分を忘れないようにパターン化してください。以下もご参照ください。 "バリデーションエラー。f:datetimeConverterのValue is not valid"エラーも参照してください。 .
こちらもご覧ください。
-
私たちの
selectOneMenu
wikiページ - h:selectOneMenuのオプションをデータベースから読み込むには?
- JSFで複数の依存/カスケード接続されたselectOneMenuドロップダウンリストを作成する。
もし誰かがこの種の問題のトラブルシューティング/デバッグのヒントを投げられるなら、それは非常に感謝されるでしょう。
ここで明確で具体的な質問をしてください。あまりに広範な質問をしないようにしましょう;)
関連
-
[解決済み] 名前が''の無効なフォームコントロールはフォーカスされない
-
[解決済み] Wekaにおけるクロスバリデーション
-
[解決済み] JAX-WSによるサーバーサイドのスキーマ検証
-
[解決済み] reactとmaterial-uiによるフォームバリデーション
-
[解決済み] 文字列が有効な数値であるかどうかを確認するにはどうすればよいですか?
-
[解決済み] クライアントから危険な可能性のあるRequest.Formの値が検出された
-
[解決済み] 有効なメールアドレスの最大長を教えてください。
-
[解決済み] HTML5 form 要素の検証を無効にする
-
[解決済み] REST APIサービスが検証に失敗した場合に返すべき適切なHTTPステータスコードは何ですか?
-
[解決済み] Bashスクリプトのパラメータを検証する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Wekaにおけるクロスバリデーション
-
[解決済み] reactとmaterial-uiによるフォームバリデーション
-
[解決済み] IETFが定義するメールアドレスの実際の最小の長さはどのくらいですか?
-
[解決済み] HTML5 form 要素の検証を無効にする
-
[解決済み] Angularフォームフィールドを手動で無効に設定するにはどうすればよいですか?
-
[解決済み】Hibernate Validator(JSR303)でクロスフィールド検証を行う。)
-
[解決済み】入力に誤りがあった場合のHTTPステータスコードについて
-
[解決済み] ユーザ名/パスワードが正しくないが、正しい形式でログインしようとした場合に返すべき適切なHTTPステータスコードは何ですか?
-
[解決済み] Bashスクリプトのパラメータを検証する
-
[解決済み] 住所録の検証はどのように行うのですか?[クローズド]