解決httpServletRequest.getParameter獲取不到參數(shù)的問題
httpServletRequest.getParameter獲取不到參數(shù)
用httpServletRequest.getParameter接收post請(qǐng)求參數(shù),發(fā)送端content Type必須設(shè)置為application/x-www-form-urlencoded;否則會(huì)接收不到
@RequestMapping(value = "/a2") @ResponseBody public String hello3(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { String string = httpServletRequest.getParameter("json"); System.out.println(string); return "hahah"; }
用@RequestBody接收請(qǐng)求可以用任意類型的content Type
@RequestMapping(value = "/a") @ResponseBody public void hello1(@RequestBody String string) { System.out.println(string); }
application/x-www-form-urlencoded通過表單提交,在sevlet實(shí)現(xiàn)中,mutipart/form-data和application/x-www-form-urlencoded會(huì)被特殊處理,請(qǐng)求參數(shù)將被放置于request.paramter,這是一個(gè)map。
我們可以從map中獲取參數(shù)進(jìn)行驗(yàn)證,或者其他攔截需求,map的獲取類似hibernate的延遲加載,當(dāng)調(diào)用request.getparamter()方法,servlet才會(huì)從請(qǐng)求流中讀取請(qǐng)求參數(shù)加載入map。
InputStream也會(huì)存有這份數(shù)據(jù),但如果這份數(shù)據(jù)被讀取,那么到了controller層將無法讀出數(shù)據(jù),同樣,攔截之后到達(dá)controller層時(shí)請(qǐng)求數(shù)據(jù)已經(jīng)被加載入了controller層方法實(shí)參,實(shí)參對(duì)象需要有set方法,框架會(huì)以反射的方式調(diào)用屬性的set方法注入數(shù)據(jù),數(shù)據(jù)只會(huì)被注入到已有的屬性。
當(dāng)以application/json的content-type傳送數(shù)據(jù),被傳送的對(duì)象只需被json序列化。
當(dāng)以application/x-www-form-urlencoded的方式傳送數(shù)據(jù)。
請(qǐng)求的內(nèi)容需要以..=..&..=..的格式提交,在請(qǐng)求體內(nèi)內(nèi)容將會(huì)以”&”和“ = ”進(jìn)行拆分。
HttpServletRequest.getParameter 亂碼情況,源碼解析
出現(xiàn)這種情況,一般的解決辦法,如:HttpServletRequest.setCharacterEncoding("utf-8")
是無效的。
因?yàn)?code>HttpServletRequest在實(shí)例化的時(shí)候是根據(jù)請(qǐng)求的Content-Type
讀取編碼如果Content-Type
的值找不到那么就會(huì)用默認(rèn)是編碼格式ISO-8859-1
源碼如下
org.apache.catalina.connector.Request
package org.apache.catalina.connector; public class Request @Override public String getParameter(String name) { if (!parametersParsed) { parseParameters(); } return coyoteRequest.getParameters().getParameter(name); } /** * Parse request parameters. */ protected void parseParameters() { parametersParsed = true; Parameters parameters = coyoteRequest.getParameters(); boolean success = false; try { // Set this every time in case limit has been changed via JMX parameters.setLimit(getConnector().getMaxParameterCount()); // getCharacterEncoding() may have been overridden to search for // hidden form field containing request encoding String enc = getCharacterEncoding(); boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI(); if (enc != null) { parameters.setEncoding(enc); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding(enc); } } else { parameters.setEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); } } ..... 省略 ..... } /** * Get the character encoding used for this request. */ public String getCharacterEncoding() { if (charEncoding != null) return charEncoding; charEncoding = ContentType.getCharsetFromContentType(getContentType()); return charEncoding; } }
org.apache.tomcat.util.http.ContentType
package org.apache.tomcat.util.http; public class ContentType { /** * Parse the character encoding from the specified content type header. * If the content type is null, or there is no explicit character encoding, * <code>null</code> is returned. * * @param contentType a content type header */ public static String getCharsetFromContentType(String contentType) { if (contentType == null) { return (null); } int start = contentType.indexOf("charset="); if (start < 0) { return (null); } String encoding = contentType.substring(start + 8); int end = encoding.indexOf(';'); if (end >= 0) { encoding = encoding.substring(0, end); } encoding = encoding.trim(); if ((encoding.length() > 2) && (encoding.startsWith("\"")) && (encoding.endsWith("\""))) { encoding = encoding.substring(1, encoding.length() - 1); } return (encoding.trim()); } }
org.apache.coyote.Constants
package org.apache.coyote; public final class Constants { // -------------------------------------------------------------- Constants public static final String Package = "org.apache.coyote"; public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1"; ... 省略 ... }
org.apache.catalina.connector.Request.java
為實(shí)際實(shí)現(xiàn)類,剩下你見到的亂七八糟的都是他的裝飾類。
可以見到,getParameter
的時(shí)候會(huì)先判斷是否曾經(jīng)解析過編碼。
如果從來未使用getParameter
的話,會(huì)先對(duì)數(shù)據(jù)進(jìn)行編碼格式設(shè)置。
這也就為什么,setCharacterEncoding
一定要在getParameter
之前。
方法parseParameters
里有這么一行代碼String enc = getCharacterEncoding();
這行代碼決定了post
的編碼格式,我們?cè)偻锩媾芸梢钥吹健?/p>
org.apache.tomcat.util.http.ContentType.java
類的getCharsetFromContentType
方法中,編碼格式是由http.headers
的Content-Type
中搜索charset=
截取出來的。
如果里面不包含編碼格式,那么就會(huì)使用默認(rèn)字符集ISO-8859-1
到這里為止,整個(gè)過程已經(jīng)很清晰了。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java 對(duì)象序列化 NIO NIO2詳細(xì)介紹及解析
這篇文章主要介紹了Java 對(duì)象序列化 NIO NIO2詳細(xì)介紹及解析的相關(guān)資料,序列化機(jī)制可以使對(duì)象可以脫離程序的運(yùn)行而對(duì)立存在,需要的朋友可以參考下2017-02-02詳解JDBC的概念及獲取數(shù)據(jù)庫(kù)連接的5種方式
Java?DataBase?Connectivity是將Java與SQL結(jié)合且獨(dú)立于特定的數(shù)據(jù)庫(kù)系統(tǒng)的應(yīng)用程序編程接口,一種可用于執(zhí)行SQL語(yǔ)句的JavaAPI。本文主要介紹了JDBC的概念及獲取數(shù)據(jù)庫(kù)連接的5種方式,需要的可以參考一下2022-09-09深層剖析java應(yīng)用開發(fā)中MyBayis緩存
這篇文章主要為大家深層剖析java開發(fā)中MyBayis緩存,文中講解了Mybatis緩存的分類以及使用的方式,有需要的朋友可以借鑒參考下,希望可以有所幫助2021-09-09MyBatis緩存實(shí)現(xiàn)原理及代碼實(shí)例解析
這篇文章主要介紹了MyBatis緩存實(shí)現(xiàn)原理及代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08Java8時(shí)間api之LocalDate/LocalDateTime的用法詳解
在項(xiàng)目中,時(shí)間的使用必不可少,而java8之前的時(shí)間api?Date和Calander等在使用上存在著很多問題,于是,jdk1.8引進(jìn)了新的時(shí)間api-LocalDateTime,本文就來講講它的具體使用吧2023-05-05Activiti進(jìn)階之組任務(wù)實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了Activiti進(jìn)階之組任務(wù)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題
這篇文章主要介紹了使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05httpclient ConnectionHolder連接池連接保持源碼解析
這篇文章主要為大家介紹了httpclient ConnectionHolder連接池連接保持源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11