0

私はで実行JEE6していて、にglassfish v3取り組んNetBean6.9でいRESTful web serviceます。

以下のjavascript関数を含むjspファイルがあります。

基本的にから情報を読み取りHTML input fields、に変換しJSON formatます。

次に、を使用してonclick Ajax callHTTPPUTメソッドを使用してJSON文字列を送信してみますUPDATE(つまり、RESTを使用してdbレコードを作成しようとしています)

私が使用しているjsフレームワークの場合はPrototype1.7

以下の関数をテストすると、常に404が返されるため、「問題が発生しました」というアラートが表示されます。

私の検索によると、1.5バージョンを超えるプロトタイプはHTTP PUT / DELETEメソッドをサポートしており、そうするために、私が行っているようにリクエストURLに_methodを追加します。

var url = "/resources/inventory/" + invId + "?_method=PUT";

これにより、たとえば次のものが作成されます。

http://localhost:8080/NoJSF/resources/inventory/123?_method=PUT

Firebugとコンソールを見て、リクエストが実際にPOSTであることを示しました。わかりませんが、これはPUTメソッドを実現するためにPOSTトンネリングを使用するプロトタイプによるものだと思いますか?

また、Ajaxが呼び出されていても、@ POSTで注釈が付けられたJAX-RSを含むJavaファイルは呼び出されていません(@GETバージョンは別のデータを処理しているため、これは正しいファイルです)。が表示されないので、Ajaxステートメントにバグがあるか、私の考えを超えた何かがあると思われます。誰かが私にヒントを与えることができますか?

function protoAjaxPut() {
            //get all fields value and store into json
            var invId = document.getElementById("invIdField").value;
            var invName = document.getElementById("invNameField").value;
            //put info into JSON format

            var jsonInput = JSON.stringify(new Array(invName));

            var url = "/resources/inventory/" + invId + "?_method=PUT";

            new Ajax.Request(url, {
                method:'put',
                postBody: jsonInput,
                ContentType: 'application/json',
                onSuccess: function(transport) {
                    var responseData = transport.responseText;
                    document.getElementById('putResponseText').innerHTML = responseData;
                },
                onFailure: function() { alert('something went wrong!')}
            })
        }//end protoAjaxPut
4

4 に答える 4

1

それらはトンネルされています:

http://dobrzanski.net/2007/04/22/using-put-and-delete-methods-in-ajax-requesta-with-prototypejs/

于 2010-12-18T15:54:51.567 に答える
1

質問ですでに述べたように、プロトタイプはデフォルトで PUT、DELETE、... リクエストを回避します。一部の人々 (私を含む) は、これはばかげた振る舞いだと考えていますが、開発者はそれを気にしていないように見えるので、request-function 自体を編集する必要があります (prototype.js の dist には触れずに!):

Ajax.Request.prototype.request = function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.isString(this.options.parameters) ?
        this.options.parameters :
        Object.toQueryString(this.options.parameters);

        // NOTE: THE MISSING PART WAS HERE

    if (params && this.method === 'get') {
        // when GET, append parameters to URL
        this.url += (this.url.include('?') ? '&' : '?') + params;
    }

    this.parameters = params.toQueryParams();

    try {
        var response = new Ajax.Response(this);
        if (this.options.onCreate) this.options.onCreate(response);
        Ajax.Responders.dispatch('onCreate', this, response);

        this.transport.open(this.method.toUpperCase(), this.url,
            this.options.asynchronous);

        if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);

        this.transport.onreadystatechange = this.onStateChange.bind(this);
        this.setRequestHeaders();

        this.body = this.method == 'post' ? (this.options.postBody || params) : null;
        this.transport.send(this.body);

        /* Force Firefox to handle ready state 4 for synchronous requests */
        if (!this.options.asynchronous && this.transport.overrideMimeType)
            this.onStateChange();

    }
    catch (e) {
        this.dispatchException(e);
    }
};

プロトタイプが開始された後にこのコードを実行します。今これ:

new Ajax.Request('42', {method:'PUT'});

実際のHTTP PUTリクエストが発生します ( jsFiddle を参照)。

于 2013-05-03T02:28:40.720 に答える
0

Below which using raw xml rather than using prototype works.

When I use prototype ajax call, 405 method not allowed would return, not sure why.

<script type="text/javascript">
  function simplePut() {
            var xmlHttp = new XMLHttpRequest();
            var invId = document.getElementById("invIdField").value;
            var invName = document.getElementById("invNameField").value;
            //put info into JSON format

            var jsonInput = JSON.stringify(new Array(invId, invName));

            var url = "resources/inventory/" + invId;

            xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    //out = xmlHttp.responseText;
                    document.getElementById('simple').innerHTML = xmlHttp.responseText;
                }
            }

            xmlHttp.open("put", url, true);
            //xmlHttp.open("put", "resources/inventory/1", true);
            //xmlHttp.setRequestHeader("Content-Type", "text/plain");
            xmlHttp.setRequestHeader("Content-Type", "application/json");
            xmlHttp.send(jsonInput);
        }//end protoAjaxPut
</script>

...html body 

 <body>
        <h1>Inventory page</h1>

        <table border="1" cellspacing="1" cellpadding="5">
            <th>id</th>
            <th>amount</th>
            <c:forEach items="${inventoryList}" var="inv" >
                <tr>
                    <td>${inv.id}</td>
                    <td><a href="" onclick="ajaxGet(${inv.id}); return false;">${inv.amount}</a></td>
                </tr>
            </c:forEach>
        </table>
        <hr />
        <h3>REST</h3>
        <form method="post" action="">
            Inventory ID: <input type="test" id="invIdField" readonly /><br />
            Inventory Name: <input type="text" id="invNameField" /><br />

            <input type="button" value="insert POST form" onclick="protoAjaxPost()" /><br />
            <!-- <input type="button" value="update PUT" onclick="protoAjaxPut()" /><br /> -->
            <div id="putResponseText"></div>
        </form>
        <button onclick="protoAjaxPut()">update PUT</button><br />
         <button onclick="simplePut()">call SIMPLE PUT</button><br />
         <button onclick="ajaxDelete()">HTTP DELETE</button><br />
         <div id="simple"></div>
    </body>
于 2010-12-19T23:46:45.833 に答える