この記事では、フォームデータとリクエストペイロードのAJAX POSTリクエストでパラメーターを取得するサーブレットの方法について説明します。次のように、参照のために共有してください。
HTTPリクエストでは、GETリクエストの場合、フォームパラメーターはname = value&name1 = value1の形式でURLに添付されます。 POST要求の場合、フォームパラメーターはリクエスト本体にあり、name = value&name1 = value1の形式のリクエスト本文にもあります。 Chrome Developer Toolsを通じて、次のことを見ることができます(ここでは、読みやすいフォームで、実際のHTTPリクエストプロトコル要求形式ではありません):
リクエストを取得:
requesturl:http://127.0.0.1:8080/test/test.do?name = mikan&address = StreetRequestメソッド:GetStatusコード:200 OkRequest headerSaccept:text/html、application/xhtml+xml、application/xml; q = 0.9、image/webp、*/*; q = 0.8accept-encoding:gzip、deflate、sdchaccept-language:zh-cn、zh; q = 0.8、en; PH:Alexatoolbar/alxg-3.2connection: Keep-AliveCookie:jSessionId = 74ac93f9f572980b6fc10474cd8edd8dhost:127.0.0.1:8080Referer:http://127.0.0.1:8080/test/index.jspuser-Agent:Mozilla/5.0(Windows NT 6.1)AppleWebkit/537.36(Khtml、Geckoのような)Chrome/33.0.1750.149 Safari/537.36Query String ParametersName:MikanAddress:StreetResponse HeadersContent-Length:2Date:Sun、11、2014年5月
リクエストの投稿:
requesturl:http:///127.0.0.1:8080/test/test.dorequestメソッド:Poststatusコード:200 okrequest headerSaccept:text/html、application/xhtml+xml、application/xml; q = 0.9、image/webp、*/*; q = 0.8accept-encoding:gzip、deflate、s DCHACCEPT-LANGUAGE:ZH-CN、ZH; Q = 0.8、EN; Q = 0.6ALEXATOOL-BAR-ALX_NS_PH:Alexatoolbar/Alxg-3.2Cache-Cache-cache-cache-age = 0connection : Keep-AliveContent-Length:25Content-Type:Application/x-www-form-urlencodedcookie:jsessionId = 74ac93f9f572980b6fc10474cd8 EDD8DHOST:127.0.0.1:8080ORIGIN:http://127.0.0.1:8080Referer:http://127.0.0.1:8080/test/index.jspuser-agent:mozilla/5.0 (Windows NT 6.1)AppleWebkit/537.36(KHTML、GECKOのように)Chrome/33.0.1750.149 Safari/537.36Form Dataname:MikanAddress:MikanAddress:Street Response Headerscontent-Length:2Date:Sun、11、2014年5月
ここでは、POSTリクエストのコンテンツタイプはApplication/X-WWW-Form-UrlenCodedであり、パラメーターはリクエスト本体、つまり上記のリクエストのフォームデータにあることに注意してください。
サーブレットでは、 request.getParameter(name)によってフォームパラメーターを取得できます。
ネイティブAjax POSTリクエストを使用する場合:
関数getXmlhttprequest(){var xhr; if(window.activexobject){xhr = new ActiveXObject( "microsoft.xmlhttp"); } else if(window.xmlhttprequest){xhr = new xmlhttprequest(); } else {xhr = null; } return xhr;} function save(){var xhr = getxmlhttprequest(); xhr.open( "post"、 "http://127.0.0.1:8080/test/test.do"); var data = "name = mikan&address = street ..."; xhr.send(data); xhr.oneadystatechange = function(){if(xhr.readystate == 4 && xhr.status == 200){alert( "returned:"+ xhr.responsetext); }};}Chromeの開発者ツールを使用して、次のようにリクエストヘッダーを参照してください。
requesturl:http:///127.0.0.1:8080/test/test.dorequestメソッド:Poststatusコード:200 okrequest HeaderSaccept:*/*Accept-Encoding:gzip、deflate、sdchaccept-language:zh-cn、zh; q = 0.8、en; q = 0.6alexatoolbar-alx_ns_ph:alexatoolbar/alxg-3.2connection:Keep-alivecontent-length:28content-type:t ext/plain; charset = utf-8cookie:jsessionId = c40c7823648e952e7c6f7d2e687a0a89host:127.0.0.1:8080o Rigin:http://127.0.0.1:8080Referer:http://127.0.0.1:8080/test/index.jspuser-agent:mozilla/5.0 (Windows NT 6.1)AppleWebkit/537.36(KHTML、GECKOのように)Chrome/33.0.1750.149 Safari/537.36Request PayloadName = Mikan&Address = StreetResponse HeadersContent-Length:2Date:Sun、11 May 2014 11:49:49:23 GMTSEREVER:
要求されたコンテンツタイプはtext/plain;charset=UTF-8であり、リクエストフォームパラメーターはrequestpayloadにあることに注意してください。
次に、サーブレットのrequest.getParameter(name)空になります。なぜ?そして、そのようなパラメーターはどのように取得されるべきですか?
この問題を理解するために、私はいくつかの情報を調べて、リクエストパラメーター処理に応じてTomCat7.0.53のソースコードを読み、最終的に何が起こっているのかを見つけました。
http postフォームリクエストを送信する場合、使用されるコンテンツタイプはapplication/x-www-form-urlencodedであり、リクエストヘッダーrequestheaderが指定されていない場合、デフォルトで使用されるコンテンツタイプはtext/plain;charset=UTF-8 。
Tomcatは、コンテンツタイプのMultiPart/Form-Data(ファイルアップロード)およびApplication/X-WWW-Form-Urlencoded(Post Request)に対して「特別な処理」を行っているからです。以下の関連する処理コードを見てみましょう。
Tomcatのhttpservletrequestクラスの実装クラスはorg.apache.catalina.connector.request(実際にはorg.apache.coyote.request)であり、 protected void parseParameters()います。この方法のコンテンツタイプのマルチパート/form-data(ファイルアップロード)およびアプリケーション/x-www-form-urlencoded(post request)の処理コードは次のとおりです。
protectedVoid parseparameters(){//いくつかのコード...パラメーター...ハンドルクリーパラメーター(); // url //コードの部分の処理パラメーターはあります... if( "multipart/form-data"。成功= true;戻る; } if(!( "application/x-www-form-urlencoded" .equals(contentType))){// POSTリクエストパラメーターの処理//コードの部分を省略します... try {if(readpostbody(formdata、len)!= len){//リクエストデータの返品を読みます; }} catch(ioException e){//クライアントはif(context.getLogger()。isdebugenabled()){context.getLogger()。debug(sm.getString( "coyoterequest.parseparameters")、e); } 戻る; } parameters.processparameters(formdata、0、len); // post requestパラメーターを処理し、マップ内のrequestparameter(つまり、request.getParametermap、request.getParameter(name)もこのマップから取得したマップ)に配置します。 {int inputlen = getStream()。read(body、offset、len -offset); if(inputlen <= 0){return offset; } offset += inputlen; } while((len -offset)> 0);レンを返します;}上記のコードから、コンテンツタイプのPOSTリクエストはアプリケーション/X-WWW-Form-UrlenCodedがリクエストボディデータを読み取らず、対応するパラメーター処理を実行しないことがわかります。つまり、フォームデータは解析されず、リクエストパラメーターマップに配置されます。したがって、 request.getParameter(name)を使用して取得することはできません。
では、この方法で提出されたパラメーターをどのように取得するのでしょうか?
もちろん、以下に示すように、入力ストリームを取得するために読み取るのは最も原始的な方法です。
privatestring getRequestPayload(httpservletrequest req){stringbuildersb = new StringBuilder(); try(bufferedreaderreader = req.getReader();){char [] buff = new char [1024]; intlen; while((len = reader.read(buff))!= -1){sb.append(buff、0、len); }} catch(ioexception e){e.printstacktrace(); } returnsb.toString();}もちろん、アプリケーション/x-www-form-urlencodedセットを使用した投稿リクエストもこの方法で取得できます。
したがって、Native Ajax POSTリクエストを使用する場合、リクエストヘッダーを明示的に設定する必要があります。つまり、次のとおりです。
xhr.setRequestheader( "content-type"、 "application/x-www-form-urlencoded");
さらに、jQueryを使用する場合、1.11.0バージョンを使用してテストします。 $.ajax postリクエストは、このリクエストヘッダーを明示的に設定する必要はありません。他のバージョンでは自分でテストしていません。 1.11.0以降のバージョンは設定する必要はないと思います。しかし、以前は確かではないかもしれません。これはテストされていません。
postScript:
フォーム送信データは名前値ペアであり、コンテンツタイプはアプリケーション/x-www-form-urlencodedであるため、フォームの送信とファイルアップロードのためにサーバーが特別な処理を行う理由を本当に理解しました。ファイルアップロードサーバーには特別な処理が必要です。通常のPOSTリクエストのデータ形式(コンテンツタイプはアプリケーション/X-WWW-FORM-URLENCODEDではありません)は固定されておらず、必ずしも名前と価値のペアではないため、サーバーは特定の処理方法を知ることができないため、元のデータストリームを取得することによってのみ解析できます。
jQueryがPOSTリクエストを実行すると、コンテンツタイプをApplication/X-WWW-Form-Urlencodedに設定するため、サーバーは正しく解析できます。ネイティブAJAX要求を使用する場合、コンテンツタイプが表示されない場合、デフォルトはテキスト/プレーンです。現時点では、サーバーはデータを解析する方法がわからないため、元のデータストリームを取得することによってのみリクエストデータを解析できます。
Javaアルゴリズムの詳細については、このサイトに興味のある読者は、「Java Networkプログラミングスキルの要約」、「Javaデータ構造とアルゴリズムに関するチュートリアル」、「Java Operation Dom Nodeスキルの概要」、「Javaファイルの要約と監督操作スキル」、Java Cache操作スキルの概要を見ることができます。
この記事がみんなのJavaプログラミングに役立つことを願っています。