7

SpringMVCを使用してRESTfulWebサービスを公開しています。操作の1つは、フォームが送信されたときにRESTfulPUT操作を要求します。

ただし、このフォームは、テキストやチェックボックスなどの通常の入力に加えてファイル入力が含まれているという点で、通常のフォームではありません。

にを追加して、RESTfulPUTおよびDELETEと連携するようにSpringを構成しHiddenHttpMethodFilterましたweb.xml。私のフォームでは、非表示の_methodパラメーターも送信されています。

これはすべて、DELETE、ファイルアップロードなしのPUTなどで正常に機能します。ファイルアップロードとフォームデータを使用してPUTを実行しようとすると、が表示されます405

HTTP Status 405 - Request method 'POST' not supported

私のコントローラーメソッドは次のようになります。

@RequestMapping(value = "/admin/cars/{carId}", method = PUT, headers = "content-type=multipart/form-data")
public String updateCar(@PathVariable("carId") String carId, CarForm form) {
    // save and return the right view.
}

私のHTMLフォームは次のようになります。

<form action="<c:url value='/admin/cars/${car.id}'/>" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="_method" value="PUT" />
    <input type="text" name="carName" value="${car.name}" />
    <input type="file" name="photo" />
    <input type="submit" />
</form>

私が達成しようとしていることは、PUTを使用してまったく実行可能ですか?もしそうなら、SpringMVCにそれを理解させる方法は?

4

3 に答える 3

9

web.xml のMultipartFilterにファイルのアップロードを有効にするために追加します ( API ドキュメントに記述されているように、 NOTE を参照してください)。 HiddenHttpMethodFilterHiddenHttpMethodFilter

また:

注: このフィルターは、 Spring の Web MVC を使用しないカスタム Web ビューを持つ Web アプリケーションや、Spring MVC の前に適用されるカスタム フィルター(例: )DispatcherServletなど、の サポートを使用する代替手段です。いずれにせよ、このフィルターはサーブレット固有のマルチパート解決と組み合わせるべきではありません。MultipartResolverDispatcherServletHiddenHttpMethodFilter

(MFのドキュメントから、強調鉱山)

また、MultipartResolverの Bean 名はfilterMultipartResolver、MultipartFilter を適切に実行するために必要です (または を介し​​て設定する必要があります<init-param>)。

編集:

前回のコメントで予想したとおり、CommonsMultipartResolverデフォルトで POST メソッドのみをサポートするという問題があります。(実際には、MultipartFilter が HiddenHttpMethodFilter の前に宣言されているため、PUT であっても isMultipartContent 内のメソッドは POST として入ってきます 。OP の注意事項として) 以下は、元々使用していた静的メソッドをわずかに変更した拡張クラスです。

public class PutAwareCommonsMultipartResolver extends CommonsMultipartResolver {

    private static final String MULTIPART = "multipart/";

    @Override
    public boolean isMultipart(HttpServletRequest request) {
        return request != null && isMultipartContent(request);
    }

    /**
     * Utility method that determines whether the request contains multipart
     * content.
     * 
     * @param request The servlet request to be evaluated. Must be non-null.
     * 
     * @return <code>true</code> if the request is multipart; {@code false}
     * otherwise.
     * 
     * @see ServletFileUpload#isMultipartContent(HttpServletRequest)
     */
    public static final boolean isMultipartContent(HttpServletRequest request) {
        final String method = request.getMethod().toLowerCase();
        if (!method.equals("post") && !method.equals("put")) {
            return false;
        }
        String contentType = request.getContentType();
        if (contentType == null) {
            return false;
        }
        if (contentType.toLowerCase().startsWith(MULTIPART)) {
            return true;
        }
        return false;
    }

}
于 2012-09-27T08:32:29.680 に答える
2

実際にPUTは、マルチパート データではなく、バイナリ ストリームを受け取ります。使用して機能させることができますorg.springframework.web.filter.HiddenHttpMethodFilter

于 2012-09-27T08:25:19.030 に答える
1

たとえば、Restful スタイルを適用するために、代替ソリューション (PUT メソッドを使用した MultipartResolver) に興味がある場合は、Spring 3.0 FileUpload with POST のみをご覧ください。.

于 2015-11-11T19:19:11.560 に答える