1

したがって、おそらくかなり古いスタイルのSpringプロパティ変換を使用しています。基本的に、ページが読み込まれると、エンティティオブジェクトがID値に変換され、ページが送信されると、id値が取得され、そのIDでエンティティオブジェクトが検索され、データが返されます。

例を以下に示します。

import org.springframework.binding.convert.converters.StringToObject;

public class StringToExamVO extends StringToObject {

    private VerifyService verifyService;

    public StringToExamVO(VerifyService verifyService) {
        super(ExamVO.class);
        this.verifyService = verifyService;
    }

    @Override
    public String toString(Object object) {
        ExamVO spec = (ExamVO) object;
        return (spec != null && spec.getId() != null ? spec.getId().toString() : null);
    }

    @Override
    public Object toObject(String string, Class targetClass) {
        if (string != null && string.length() > 0 && targetClass.equals(ExamVO.class)) {
            String id = StringUtils.trimToNull(string);
            return verifyService.loadExam(Integer.decode(id));
        }
        return null;
    }
}

これは、フォームバッキングコマンドに単一のエンティティプロパティがある場合にうまく機能します。

private ExamVO exam;

public void setExam(ExamVO exam) {
  this.exam = exam;
}

public ExamVO getExam() {
  return this.exam;
}

ただし、プロパティがエンティティのリストである場合は機能しないようです。

private List<ExamVO> exams;

public void setExams(List<ExamVO>exam) {
  this.exams = exams;
}

public List<ExamVO> getExams() {
  return this.exams;
}

単一のプロパティタイプのデバッガーをたどると(最初の例)、ページの読み込みと送信時にそれぞれtoStringとtoObjectの両方が呼び出されることがわかります。

ただし、プロパティがLISTの場合のデバッグでは、toStringのみが呼び出されます(繰り返しそのリストをcosします)。ページ送信では、toObjectの呼び出しはありません。つまり、文字列IDをエンティティオブジェクトに変換しようとさえしていません。

リストプロパティゲッターにブレークポイントを設定すると、リストはインデックススロットにあったオブジェクトgetExamsとして定義されていますが、 !で上書きされていることがわかります。List<ExamVO>ExamVOStrings

Spring変換フレームワークは、その値を設定しているため、スロットごとList<ExamVO>にコンバーターのtoObjectメソッドを呼び出す必要があることを検出できませんか?StringToExamVO

4

1 に答える 1

0

これについてもう少し考えてみてください。基本的に読んでいる一番下の私の質問に関して。

「Springはリスト、つまりジェネリック型のリストにデータを入力していることを検出できるので、コンバーターを呼び出して文字列をExamVOジェネリック型に変換できますか?」

ジェネリックタイピングは実行時に削除されるため、答えはノーだと思います。したがって、実行時にリストは入力なしの単なるリストです。これが、SpringがExamVOではなく文字列を挿入できる理由であり、一般的な入力がないとフレームワークがリストを認識しないため、変換サービスが呼び出されない理由でもあります。 ExamVOが含まれていると想定されます。

コードの動作方法を変更しましたが、次のアイデアを簡単に試してみました。

@SuppressWarnings("unchecked")
public List<ExamVO> getExams() {
    if(Exams == null) {
        exams = new ArrayList() {

            @Override
            public ExamVO set(int index, Object element) {
                // TODO if element is a String, 
                // call the verifyService.loadExam(Integer.decode(element));
                // to get the ExamVO and set that to element
                return (ExamVO)super.set(index, element);
            }
        };
    }
    return exams;
}

これは理論的には機能しますが、コマンド/フォームのバッキングオブジェクトからサービスレイヤーへの呼び出しを行うことは、私にはかなり不愉快に思えます。

于 2013-03-01T10:30:32.150 に答える