Cet article décrit la méthode de l'obtention de paramètres d'obtention du servlet dans les demandes de post ajax dans les données du formulaire et la charge utile de demande. Partagez-le pour votre référence, comme suit:
Dans la demande HTTP, s'il s'agit d'une demande GET, le paramètre de formulaire est joint à l'URL sous la forme de nom = valeur et name1 = valeur1. S'il s'agit d'une demande de post, le paramètre de formulaire est dans le corps de la demande et est également dans le corps de la demande sous la forme de name = valeur & name1 = value1. Grâce aux outils de développeur Chrome, vous pouvez voir ce qui suit (voici un formulaire lisible, pas un véritable format de demande de protocole de demande HTTP):
Obtenir une demande:
RequestUrl: http: //127.0.0.1: 8080 / test / test.do? Name = mikan & adresse = Méthode streetRequest: Code getStatus: 200 okrequest Headersaccept: Text / HTML, application / xhtml + xml, application / xml; q = 0,9, image / webp, * / *; q = 0,8ACcept-Encoding: gzip, dégonfler Ph: Alexatoolbar / Alxg-3.2Connection: Keep-AaliveCookie: JSessionID = 74AC93F9F572980B6FC10474CD8EDD8DHOST: 127.0.0.1: 8080Referer: Http: //127.0.0.1: 8080 / Test (Windows NT 6.1) Applewebkit / 537.36 (KHTML, comme Gecko) Chrome / 33.0.1750.149 Safari / 537.36Query String Paramètres Name: Mikanaddress: StreetResponse Headerscontent-Longle
Demande de poste:
RequestUrl: http://127.0.0.1:8080/test/test.dorequest Méthode: Code PostSatus: 200 Okrequest En-têtes de réception: texte / html, application / xhtml + xml, application / xml; q = 0,9, image / webp, * / *; q = 0,8ACcept-Encoding: gzip, dégonfler, s dchaccept-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, comme Gecko) Chrome / 33.0.1750.149 Safari / 537.36form Dataname: Mikanaddress: StreetResponse Headerscontent-Length: 2Date: Sun, 11 mai 2014 11:05:33 GMTSERVER: APCAhe-Coyote / 1.1
Ici, nous devons noter que le type de contenu de la demande de post est Application / X-WWW-Form-Urlencoded, et le paramètre est dans le corps de la demande, c'est-à-dire les données de formulaire dans la demande ci-dessus.
Dans un servlet, les paramètres de formulaire peuvent être obtenus par request.getParameter(name) .
Et si vous utilisez la demande de post native Ajax:
function 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 & adresse = street ..."; xhr.send (données); xhr.OnreadyStateChange = function () {if (xhr.readystate == 4 && xhr.status == 200) {alert ("renvoyé:" + xhr.ResponSExt); }};}Grâce aux outils du développeur de Chrome, consultez l'en-tête de demande comme suit:
RequestUrl: http://127.0.0.1:8080/test/test.dorequest Méthode: Code PostSatus: 200 Okrequest En-têtes de tête: * / * Accept-codage: gzip, dégonfler, sdchaccept-language: zh-cn, zh; q = 0,8, en; q = 0,6alexatoolbar-alx_ns_ph: alexatoolbar / alxg-3.22connection: keep-alivecontent-longueur: 28content-type: t: t: t ext / plaine; 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, comme Gecko) Chrome / 33.0.1750.149 Safari / 537.36Request PayloadName = Mikan & Address = StreetResponse HeadersContent-Length: 2Date: Sun, 11 mai 2014 11:49:23 GMTSERVER: APCAhe
Notez que le type de contenu demandé est text/plain;charset=UTF-8 , et le paramètre de formulaire de demande est dans RequestPayload.
Ensuite, request.getParameter(name) dans le servlet est vide. Pourquoi? Et comment obtenir de tels paramètres?
Afin de comprendre ce problème, j'ai recherché certaines informations et lu le code source de Tomcat7.0.53 sur le traitement des paramètres de demande, et j'ai finalement compris ce qui se passait.
Lors de la soumission des demandes de formulaire HTTP Post, le type de contenu utilisé est application/x-www-form-urlencoded , et si le pointage de demande d'en-tête de demande n'est pas spécifié, le type de contenu utilisé par défaut est text/plain;charset=UTF-8 .
Parce que Tomcat fait "Traitement spécial" pour le multipart / formulaire de type contenu (téléchargement de fichiers) et l'application / x-www-form-urlencoded (requête post-demande). Jetons un coup d'œil au code de traitement pertinent ci-dessous.
La classe d'implémentation de la classe HTTPServletRequest de Tomcat est org.apache.catalina.connector.request (en fait org.apache.coyote.request), et sa méthode de traitement des paramètres de demande est protected void parseParameters() . Les codes de traitement pour le multipart / formulaire de type contenu (téléchargement de fichiers) et l'application / x-www-form-urlencoded (requête post-demande) dans cette méthode sont les suivants:
ProtectedVoid ParseParameters () {// omettre certains code ... Paramètres.HandLeQueryParameters (); // Voici les paramètres de traitement dans l'URL // OMIT PARTIE DU CODE ... if ("Multipart / Form-data" .Equals (ContentType)) {// voici la requête de fichier de traitement de la demande de fichiers (); succès = vrai; retour; } if (! ("application / x-www-form-urlencoded" .equals (contentType))) {// voici le traitement des paramètres de la demande post // omettre la partie du code ... try {if (readPostBody (formdata, len)! = len) {// Read the demander data return; }} catch (ioException e) {// Client Disconnect if (context.getLogger (). IsDebugeNabled ()) {context.getLogger (). Debug (sm.getString ("coyoteRquest.parseparameters"), e); } retour; } Paramètres.ProcessParameters (formdata, 0, len); // traite le paramètre de demande de la demande et le mettez-le dans le demandeur de request dans la carte (c'est-à-dire que la carte obtenue par demande.getParameTermap, request.getParameter (name) est également obtenue à partir de cette carte) // omit partie du code ...} Int Protected Int ReadPostBody (Body Body [], int len) Throws ioException {int offset = 0; do {int inputLen = getStream (). read (body, offset, len - offset); if (inputlen <= 0) {return offset; } offset + = inputlen; } while ((len - offset)> 0); Retour Len;} À partir du code ci-dessus, nous pouvons voir que la demande publique du type de contenu n'est pas l'application / x-www-form-urlencoded ne lira pas les données du corps de demande et effectuera le traitement des paramètres correspondants, c'est-à-dire que les données de formulaire ne seront pas analysées et placées dans la carte des paramètres de demande. Par conséquent, il ne peut pas être obtenu via request.getParameter(name) .
Alors, comment pouvons-nous obtenir les paramètres soumis de cette manière?
Bien sûr, c'est la méthode la plus primitive pour lire le flux d'entrée pour l'obtenir, comme indiqué ci-dessous:
privateString getRequestPayload (httpServLequest 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 ();}Bien sûr, les demandes de publication avec l'application / x-www-form-urlencoded set peuvent également être obtenues de cette manière.
Par conséquent, lorsque vous utilisez la demande de post Ajax native, vous devez définir explicitement l'en-tête de demande, c'est-à-dire:
xhr.setRequestHeader ("Content-Type", "Application / X-Www-Form-Urlencoded"); De plus, si vous utilisez jQuery, j'utilise la version 1.11.0 pour la tester. $.ajax post n'a pas besoin de définir explicitement cet en-tête de demande, et je ne l'ai pas testé moi-même pour d'autres versions. Je crois que les versions après 1.11.0 n'ont pas besoin d'être définies. Mais certains avant ne sont peut-être pas certains. Cela n'a pas été testé.
PostScript:
J'ai vraiment compris pourquoi le serveur effectue un traitement spécial pour la soumission et le téléchargement de fichiers de formulaire, car les données de soumission de formulaire sont une paire de valeurs de nom, et le type de contenu est l'application / x-www-form-urlencoded, tandis que le serveur de téléchargement de fichiers a besoin d'un traitement spécial. Le format de données des demandes de poste ordinaires (le type de contenu n'est pas une application / x-www-form-urlencoded) n'est pas fixe, et ce n'est pas nécessairement une paire de valeurs de nom, de sorte que le serveur ne peut pas connaître la méthode de traitement spécifique, donc elle ne peut analyser qu'en obtenant le flux de données d'origine.
Lorsque jQuery exécute une demande de post, il définit le type de contenu sur Application / X-Www-Form-Urlencoded, afin que le serveur puisse analyser correctement. Lorsque vous utilisez une demande AJAX native, si le type de contenu n'est pas affiché, la valeur par défaut est texte / simple. Pour le moment, le serveur ne sait pas comment analyser les données, il ne peut donc analyser les données de demande qu'en obtenant le flux de données d'origine.
Pour plus d'informations sur les algorithmes Java, les lecteurs qui sont intéressés par ce site peuvent consulter les sujets: "Résumé des compétences de programmation du réseau Java", "Tutorials sur les structures de données Java et les algorithmes", "Résumé des compétences de nœuds Java Dom", "Résumé des compétences de fichiers Java et de l'opération de répertoire" et "Résumé des compétences en opération Java Cache" "
J'espère que cet article sera utile à la programmation Java de tous.