5

Spring MVC モデル Bean の一部のみを表示する場合、ブラウザから返されたモデルのみを更新する方法はありますか?

User クラスがあるとしましょう (もちろん、この例ではパブリック プロパティのみです)。

public class User {
  public String firstName;
  public String lastName;
  public String email;
  public Date subscriptionExpiration;
}

ここで、最初の 3 つのプロパティを JSP の入力フィールドとして表示し、それに応じてデータベース内のオブジェクトを更新したいと考えています。これら 3 つのパラメーターのみを更新する必要があります。4 番目のパラメーターは更新しないでください。これを達成する1つの方法は、

@RequestMapping("/user/{userId}", method=RequestMethod.POST)
public String saveChanges(@PathVariable userId, User user, Model model) {
  User oldUser = User.loadFromDB(userId);
  oldUser.firstName = user.firstName;
  oldUser.lastName = user.lastName;
  oldUser.email = user.email;
  oldUser.saveToDB();

  model.addAttribute("user", oldUser);
}

しかし、これは変更される可能性のあるすべてのプロパティをハードコーディングすることを意味し、私はあまり好きではありません。

ユーザーが変更を許可された内容に基づいて、どのフィールドを更新するかを決定する方法はありますか? そのメカニズムは、リクエスト パラメータに含まれるすべてのものが変更される可能性があると想定するよりもスマートである必要があります。そうしないと、知識のあるユーザーがリクエストに追加のフィールドを手動で挿入できます。

@Entity(dynamicUpdate=true) を使用しても、リクエストで User オブジェクト全体を取得できず、多くのセキュリティ ホールが開くため、問題は解決しません。

Spring の優れた機能が不足していますか、またはこの問題を概念的に解決する他の方法はありますか? どんなヒントでも大歓迎です!

4

6 に答える 6

3

この質問を参照して、 @InitBinder を使用して、Spring がパラメーターを要求するために一部のモデル フィールドをバインドすることを許可/防止する方法を確認してください。これによりsubscriptionExpiration、リクエスト パラメータを挿入して を変更できないようにすることができます。

また、メソッドおよびメソッド引数で@ModelAttributeアノテーションを使用して、データベースからユーザーをロードし、@RequestMapping メソッドが呼び出される前にモデルに追加する方法と、@ RequestMapping メソッドが呼び出されます。これにより、DB からユーザーを取得し、Spring にリクエストからの ne 値を入力させることができます。ユーザーの新しい状態を検証してデータベースに保存するだけです。

于 2012-12-22T21:48:05.950 に答える
2

方法だと思います

BeanUtils.copyProperties(Object source, Object target, String[] ignoreProperties) 

あなたが望むことをします。で定義されたプロパティに触れることなく、あるオブジェクトから別のオブジェクトにすべてのプロパティをコピーしますString[] ignoreProperties

指定された「ignoreProperties」を無視して、指定されたソース Bean のプロパティ値を指定されたターゲット Bean にコピーします。

注: ソース クラスとターゲット クラスは、プロパティが一致する限り、一致する必要はなく、相互に派生する必要さえありません。ソース Bean が公開するがターゲット Bean が公開しない Bean プロパティは、黙って無視されます。

これは単なる便利な方法です。より複雑な転送が必要な場合は、完全な BeanWrapper の使用を検討してください。

API ドキュメント

于 2012-12-22T21:48:12.657 に答える
0

私は同じ問題を抱えており、タイプコンバーターを追加するだけで最終的に解決します。

public class AbstractDocumentConverter implements Converter<String, AbstractDocument> {

    private AbstractDocumentRepository abstractDocumentRepository;

    public AbstractDocumentConverter(AbstractDocumentRepository abstractDocumentRepository) {
        this.abstractDocumentRepository = abstractDocumentRepository;
    }

    @Override
    public AbstractDocument convert(String id) {
        return abstractDocumentRepository.findOne(id);
    }
}

私はmongodbを使用しています。AbstractDocumentはすべてのドキュメントのスーパークラスであり、コントローラーに @ModelAttribute("id") を追加します。

@RequestMapping("save")
public String save(@ModelAttribute("id") SportGame game) {
    sportGameService.save(game);
    return "redirect:/game/list";
}

最初に id をモデルに変換し (私のコンバーターでは id で db から 1 つを見つけます)、次にリクエストパラメーターからモデルフィールドを埋めます。

于 2018-06-22T13:40:11.983 に答える
0

最初にデータベースからオブジェクトを読み取り、次にリクエストをバインドできます。FuWeSta-Sampleで例を見つけることができます。

Spring で初期化する必要があるヘルパー Beanを使用します。

于 2014-03-03T11:03:35.637 に答える