0

PlayerHTML フォームを使用して単純なドメイン オブジェクト (a) の作成と編集を可能にする Spring MVC コントローラーを作成しようとしています。できれば RESTful な方法で。送信されたフォームにエラーがあると、編集で問題が発生しました。クライアント (ブラウザー) にエラー メッセージと元のフォームを表示して、ユーザーが修正して再送信できるようにしたい。

しかし、私はそれを機能させることができません。エラーが発生すると、Web アプリケーションに元のフォームを再表示させることができますが、エラー メッセージは表示されません。その場合、コードがフォームページにリダイレクトされるためだと思います。リダイレクトを削除しようとしましたが、Web サーバーPUTはリソースに対して許可されていないと文句を言います。私は何をする必要がありますか?

私のコントローラーに関連するコードは次のとおりです。

 @Controller
 @RequestMapping({
    "/player"
 })
 public class PlayerController {

    @RequestMapping(value = "/{id}/edit", method = RequestMethod.PUT)
    public String editPlayer(@PathVariable("id")
    final long id, @Valid
    @ModelAttribute(Model.PLAYER)
    final PlayerModel player, final BindingResult result) {
       if (!result.hasErrors()) {
          final Player playerEntity = playerService.find(id);
          playerEntity.setName(player.getName());
          playerService.update(playerEntity);
          return "redirect:/player/" + id;
       } else {
          return "redirect:/player/" + id + "/edit";
       }
    }

    @RequestMapping(value = "/{id}/edit", method = RequestMethod.GET)
    public String showEditPlayerPage(@PathVariable("id")
    final long id, final org.springframework.ui.Model model) {
       createModel(id, model);
       return View.EDIT_PLAYER;// the player editing page
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String showPlayerPage(@PathVariable("id")
    final long id, final org.springframework.ui.Model model) {
       // ...
       return View.PLAYER;// the read-only view of a player
    }

    // Other code
 }

に JSR-303 検証アノテーションがあり、が短すぎたり長すぎたりPersonModelすると検証エラーが発生します。name編集フォームの HTML は次のとおりです。

 <form:form commandName="player" method="PUT">
    <fieldset>
       <table>
          <tr>
             <th><label for="player_name">Player Name:</label></th>
             <td><form:input path="name" size="64" maxlength="64"
                   id="player_name" /> <br /> <small
                id="player_name_msg">Not empty, but no more
                   than 64 characters.</small> <form:errors path="name"
                   class="error" /></td>
          </tr>
       </table>
       <input type="submit" value="Submit"></input>
    </fieldset>
 </form:form>

編集:

明確にするために、フォームが有効な場合はすべて正常に機能します。PUT を POST に変換するためのサーブレット フィルターがあり、正常に動作しているようです。


編集2:

実験と調整により、コントローラーが実行されていることがわかりました。PUT の拒否は、コントローラーの実行後に発生します。Spring は、PUT への応答にビュー名を付けたくないようです。

4

2 に答える 2

0

あなたは仕事をするためHiddenHttpMethodFilterにあなたを追加する必要があります :web.xmlPUT/DELETE

<filter>
    <filter-name>httpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>httpMethodFilter</filter-name>
    <servlet-name>your-servlet</servlet-name>
</filter-mapping>

Springドキュメントから:

... HTTPはこれらの4つのメソッドを定義しますが、HTMLはGETとPOSTの2つのみをサポートします。幸い、2つの回避策が考えられます。JavaScriptを使用してPUTまたはDELETEを実行するか、追加パラメーターとして「real」メソッドを使用してPOSTを実行することができます(HTMLフォームの非表示の入力フィールドとしてモデル化されます)。この後者のトリックは、SpringのHiddenHttpMethodFilterが行うことです。このフィルターはプレーンなサーブレットフィルターであるため、(Spring MVCだけでなく)任意のWebフレームワークと組み合わせて使用​​できます。このフィルターをweb.xmlに追加するだけで、_methodパラメーターが非表示のPOSTが対応するHTTPメソッド要求に変換されます。

ここで完全なリファレンス。

編集:

<url-mapping/>の代わりにタグを使用してみてください<servlet-name/>

<filter>
    <filter-name>httpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>httpMethodFilter</filter-name>
    <url-mapping>/*</url-mapping>
</filter-mapping>
于 2012-08-28T06:45:35.090 に答える
0

したがって、私の問題の原因は、プレーヤー エンティティ (リソース) を変更するために HTTP PUT を使用することに固執することです。私がそうすることに固執したのは、それが純粋な RESTful な方法であると信じていたからです。POST は作成、PUT は変更です。しかし、私と他の人は間違っているようです: POST を変更に使用しても問題ありません。

コントローラーを次のように変更しました。

 @Controller
 @RequestMapping({
    "/player"
 })
 public class PlayerController {

    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void editPlayer(
       @PathVariable("id") final long id,
       @Valid @ModelAttribute(Model.PLAYER) final PlayerModel player,
       final BindingResult result) {
       // ...
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public String editPlayerWithView(
       @PathVariable("id") final long id,
       @Valid @ModelAttribute(Model.PLAYER) final PlayerModel player,
       final BindingResult result) {
       // ...
       if (result.hasErrors()) {
          return View.EDIT_PLAYER;
       } else {
          // ...
          return View.PLAYER;
       }
    }

    @RequestMapping(value = "/{id}/edit", method = RequestMethod.GET)
    public String showEditPlayerPage(
       @PathVariable("id") final long id,
       final org.springframework.ui.Model model) {
       // ...
       return View.EDIT_PLAYER;
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String showPlayerPage(
       @PathVariable("id") final long id,
       final org.springframework.ui.Model model) {
       // ...
       return View.PLAYER;
    }

そして、フォームに簡単な変更を加えました。

 <form:form commandName="player" action="/player/${player.id}">
    <!-- ... -->
 </form:form>

これで、プレーヤー エンティティ (リソース) を表示、作成、および変更できます。HTML フォームを使用して作成および変更し、無効な作成または変更を試みると、フォームでユーザーにエラー メッセージが表示されます。

私は自分の答えにサブタイトルを付けることができました.

于 2012-08-28T21:28:32.900 に答える