Artikel ini menjelaskan metode servlet memperoleh parameter dalam permintaan AJAX POST dalam data formulir dan meminta muatan. Bagikan untuk referensi Anda, sebagai berikut:
Dalam permintaan HTTP, jika itu adalah permintaan GET, parameter formulir dilampirkan ke URL dalam bentuk nama = nilai & name1 = value1. Jika ini adalah permintaan pos, parameter formulir ada di badan permintaan, dan juga ada di badan permintaan dalam bentuk nama = nilai & name1 = value1. Melalui alat pengembang chrome, Anda dapat melihat yang berikut (berikut adalah formulir yang dapat dibaca, bukan format permintaan protokol permintaan HTTP nyata):
Dapatkan permintaan:
RequestUrl: http: //127.0.0.1: 8080/test/test.do? Name = mikan & alamat = Metode StreetRequest: GetStatus Code: 200 Okrequest Headersaccept: Teks/html, aplikasi/xhtml+xml, aplikasi/xml; q = 0.9, gambar/webp,*/*; q = 0.8accept-encoding: GZIP, koplate, sdchaccept-bahasa: ZH-CN, Zh; q = 0.8, q = 0.6except-bahasa: ZH-CN, ZH; q = 0.8, q = 0.6alexcepte: ZH-CN, ZH; q = 0.8, q = 0.6except-Language: ZH-CN, ZH; q = 0.8, q = 0.6except PH: Alexatoolbar/ALXG-3.2Connection: Keep-AliveCookie: JSessionId = 74AC93F9F572980B6FC10474CD8EDD8DHOST: 127.0.0.1: 8080Referer: http: //127.0.0.1: 8080/tes/index.jspuser-idah 6.1) AppleWebKit/537.36 (KHTML, Like Gecko) Chrome/33.0.1750.149 Safari/537.36 Parameter Parameter: Mikanaddress: StreetResponse Headerscontent-Length: 2Date: Sun, 11 Mei 2014 10:42:42:38 GMTSEPLE: 2DATE: SUN, 11 Mei 2014 10:42:42:42:38.38.388888 GMPS: 2Date: Sun, 11 Mei 2014 10:42:42:38 GMTSCE: 2Date: 2DATE: 11 Mei 2014 10:42:42:38.38
Permintaan Posting:
RequestUrl: http://127.0.0.1:8080/test/test.dorequest Metode: Kode poststatus: 200 Okrequest Headersaccept: Teks/HTML, Aplikasi/XHTML+XML, Aplikasi/XML; Q = 0.9, Image/Webp,*/*; q = 0.8accept-encoding: GZIP, lempeng, s DCHACECCE-LANGUAGE: ZH-CN, ZH; q = 0.8, EN; q = 0.6Alexatoolbar-alx_ns_ph: Alexatoolbar/Alxg-3.2Cache-Control: Max-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, LIKE GECKO) Chrome/33.0.1750.149 Safari/537.36 Dataname: Mikanaddress: StreetResponse Headerscontent-Length: 2Date: Sun, 11 Mei 2014 11:05:05:3.3
Di sini kita harus mencatat bahwa tipe konten dari permintaan POST adalah aplikasi/X-WWW-Form-Burlencoded, dan parameternya ada di badan permintaan, yaitu data formulir dalam permintaan di atas.
Dalam servlet, parameter formulir dapat diperoleh dengan request.getParameter(name) .
Dan jika menggunakan permintaan pos AJAX asli:
fungsi 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.onReadyStateChange = function () {if (xhr.readystate == 4 && xhr.status == 200) {alert ("dikembalikan:"+ xhr.responsetext); }};}Melalui alat pengembang Chrome, lihat header permintaan sebagai berikut:
RequestUrl: http://127.0.0.1:8080/test/test.dorequest Metode: Kode 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/polos; 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, like Gecko) Chrome/33.0.1750.149 Safari/537.36Request Payloadname=mikan&address=streetResponse HeadersContent-Length:2Date:Sun, 11 May 2014 11:49:23 GMTServer:Apache-Coyote/1.1
Perhatikan bahwa tipe konten yang diminta adalah text/plain;charset=UTF-8 , dan parameter formulir permintaan ada di requestPayload.
Kemudian request.getParameter(name) di servlet kosong. Mengapa? Dan bagaimana seharusnya parameter tersebut diperoleh?
Untuk memahami masalah ini, saya mencari beberapa informasi dan membaca kode sumber Tomcat7.0.53 tentang pemrosesan parameter permintaan, dan akhirnya menemukan apa yang sedang terjadi.
Saat mengirimkan permintaan Formulir Posting HTTP, tipe konten yang digunakan adalah application/x-www-form-urlencoded , dan jika permintaan header permintaan tidak ditentukan, tipe konten yang digunakan secara default adalah text/plain;charset=UTF-8 .
Karena Tomcat melakukan "pemrosesan khusus" untuk multipart/form-data tipe konten (unggah file) dan aplikasi/X-www-form-urlencoded (pasca permintaan). Mari kita lihat kode pemrosesan yang relevan di bawah ini.
Kelas implementasi kelas httpservletRequest Tomcat adalah org.apache.catalina.connector.Request (sebenarnya org.apache.coyote.restquest), dan metode parameter permintaan pemrosesan protected void parseParameters() . Kode pemrosesan untuk tipe konten multipart/form-data (unggahan file) dan aplikasi/x-www-form-urlencoded (permintaan pos) dalam metode ini adalah sebagai berikut:
protectedVoid parseparameters () {// hilangkan beberapa kode ... parameter.handlequeryparameters (); // Berikut adalah parameter pemrosesan dalam url // hilangkan bagian kode ... jika ("multipart/form-data" .Equals (contentSype)) {// Di sini adalah file unggahan unggahan unggahan unggahan (contentSe) {// di sini adalah file unggahan pemrosesan. Sukses = Benar; kembali; } if (! ("Application/X-WWW-Form-Urlencoded" .Equals (ContentType))) {// Berikut adalah pemrosesan parameter permintaan pos // hilangkan bagian dari kode ... coba {if (readpostbody (formdata, len)! = Len) {// Baca data readpostbody; }} catch (ioException e) {// client Disconnect if (context.getLogger (). isDebugeNabled ()) {context.getLogger (). debug (sm.getString ("coyoterequest.parseparameters"), e); } kembali; } parameter.processparameters (formdata, 0, len); // Proses Parameter Permintaan POST dan masukkan ke dalam RequestParameter di peta (mis., Peta yang diperoleh dengan request.getParametermap, request.getParameter (nama) juga diperoleh dari peta ini) // oloskan bagian dari kode ...} Int readpostbody yang dilindungi (byte byte [], int len) melempar ioException {byte = byte [], int len) melempar ioException {intrset = 0; do {int inputlen = getStream (). baca (body, offset, len - offset); if (inputlen <= 0) {return offset; } offset += inputlen; } while ((len - offset)> 0); return len;} Dari kode di atas, kita dapat melihat bahwa permintaan POST dari tipe konten bukan aplikasi/X-WWW-Form-Urlencoded tidak akan membaca data Badan Permintaan dan melakukan pemrosesan parameter yang sesuai, yaitu, data formulir tidak akan diuraikan dan ditempatkan di peta parameter permintaan. Oleh karena itu, tidak dapat diperoleh melalui request.getParameter(name) .
Jadi bagaimana kita mendapatkan parameter yang dikirimkan dengan cara ini?
Tentu saja, ini adalah metode paling primitif untuk membaca aliran input untuk mendapatkannya, seperti yang ditunjukkan di bawah ini:
PrivateString getRequestPayload (httpservletRequest req) {stringBuildersB = stringBuilder baru (); coba (bufferedReaderReader = req.getreader ();) {char [] buff = char baru [1024]; Intlen; while ((len = reader.read (buff))! = -1) {sb.append (buff, 0, len); }} catch (ioException e) {E.PrintStackTrace (); } returnsb.toString ();}Tentu saja, permintaan pasca dengan aplikasi Application/X-WWW-Form-Burlencoded juga dapat diperoleh dengan cara ini.
Oleh karena itu, saat menggunakan permintaan Posting AJAX asli, Anda perlu secara eksplisit mengatur header permintaan, yaitu:
xhr.setRequestheader ("tipe konten", "Aplikasi/X-WWW-Form-Urlencoded"); Selain itu, jika Anda menggunakan jQuery, saya menggunakan versi 1.11.0 untuk mengujinya. Permintaan $.ajax post tidak perlu mengatur header permintaan ini secara eksplisit, dan saya belum mengujinya sendiri untuk versi lain. Saya percaya bahwa versi setelah 1.11.0 tidak perlu ditetapkan. Tetapi beberapa sebelumnya mungkin tidak yakin. Ini belum diuji.
nota bene:
Saya benar-benar mengerti mengapa server melakukan pemrosesan khusus untuk pengiriman formulir dan unggahan file, karena data pengiriman formulir adalah pasangan nilai nama, dan tipe konten adalah aplikasi/X-www-form-urlencoded, sedangkan server unggahan file membutuhkan pemrosesan khusus. Format data dari permintaan pos biasa (tipe konten bukan aplikasi/X-WWW-Form-Urlencoded) tidak diperbaiki, dan tidak selalu merupakan pasangan nilai nama, sehingga server tidak dapat mengetahui metode pemrosesan spesifik, sehingga hanya dapat menguraikan dengan mendapatkan aliran data asli.
Ketika JQuery menjalankan permintaan posting, ia menetapkan tipe konten ke aplikasi/X-WWW-Form-Burlencoded, sehingga server dapat menguraikan dengan benar. Saat menggunakan permintaan AJAX asli, jika tipe konten tidak ditampilkan, defaultnya adalah teks/polos. Pada saat ini, server tidak tahu cara menguraikan data, sehingga hanya dapat menguraikan data permintaan dengan mendapatkan aliran data asli.
Untuk informasi lebih lanjut tentang algoritma Java, pembaca yang tertarik dengan situs ini dapat melihat topik: "Ringkasan Keterampilan Pemrograman Jaringan Java", "Tutorial tentang Struktur Data Java dan Algoritma", "Ringkasan Keterampilan Operasi Java Java", "Ringkasan file Operasi Java File dan Direktori Operasi" dan Ringkasan JAVA "Ringkasan JAVA", "Ringkasan JAVA" JAVA OPERASI JAVA "
Saya harap artikel ini akan membantu pemrograman Java semua orang.