AJAX POST 요청 에서 매개 변 수 는 form data 와 request payload 형식 으로 servlet 에서 가 져 오 는 방식 입 니 다.

HTTP 요청 에서 get 요청 이 라면 폼 매개 변 수 는 name=value&name 1=value 1 형식 으로 url 뒤에 첨부 됩 니 다.
post 요청 이 라면 폼 매개 변 수 는 요청 체 에 있 고 name=value&name 1=value 1 형식 으로 요청 체 에 있 습 니 다.chrome 개발 자 도 구 를 통 해 다음 과 같이 볼 수 있 습 니 다.
요청 받 기:
RequestURL:http://127.0.0.1:8080/test/test.do?name=mikan&address=street  
Request Method:GET  
Status Code:200 OK  
   
Request Headers  
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8  
Accept-Encoding:gzip,deflate,sdch  
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6  
AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.2  
Connection:keep-alive  
Cookie:JSESSIONID=74AC93F9F572980B6FC10474CD8EDD8D  
Host:127.0.0.1:8080  
Referer:http://127.0.0.1:8080/test/index.jsp  
User-Agent:Mozilla/5.0 (Windows NT 6.1)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.149 Safari/537.36  
   
Query String Parameters  
name:mikan  
address:street  
   
Response Headers  
Content-Length:2  
Date:Sun, 11 May 2014 10:42:38 GMT  
Server:Apache-Coyote/1.1  

포스트 요청:
RequestURL:http://127.0.0.1:8080/test/test.do  
Request Method:POST  
Status Code:200 OK  
   
Request Headers  
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8  
Accept-Encoding:gzip,deflate,sdch  
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6  
AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.2  
Cache-Control:max-age=0  
Connection:keep-alive  
Content-Length:25  
Content-Type:application/x-www-form-urlencoded  
Cookie:JSESSIONID=74AC93F9F572980B6FC10474CD8EDD8D  
Host:127.0.0.1:8080  
Origin:http://127.0.0.1:8080  
Referer:http://127.0.0.1:8080/test/index.jsp  
User-Agent:Mozilla/5.0 (Windows NT 6.1)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.149 Safari/537.36  
   
Form Data  
name:mikan  
address:street  
   
Response Headers  
Content-Length:2  
Date:Sun, 11 May 2014 11:05:33 GMT  
Server:Apache-Coyote/1.1  

post 가 요청 한 Content-type 은 application/x-www-form-urlencoded 이 며,매개 변 수 는 요청 체,즉 위 에서 요청 한 Form Data 입 니 다.
servlet 에 서 는 request.getParameter(name)형식 으로 폼 인 자 를 가 져 올 수 있 습 니 다.
원생 AJAX POST 요청 을 사용 하면(아래 와 같이)
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&address=street...";  
          xhr.send(data);  
          xhr.onreadystatechange= function() {  
                   if(xhr.readyState == 4 && xhr.status == 200) {  
                            alert("returned:"+ xhr.responseText);  
                   }  
          };  
}  

chrome 개발 자 도 구 를 통 해 요청 머리 를 다음 과 같이 볼 수 있 습 니 다.
RequestURL:http://127.0.0.1:8080/test/test.do  
Request Method:POST  
Status Code:200 OK  
   
Request Headers  
Accept:*/*  
Accept-Encoding:gzip,deflate,sdch  
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6  
AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.2  
Connection:keep-alive  
Content-Length:28  
Content-Type:text/plain;charset=UTF-8  
Cookie:JSESSIONID=C40C7823648E952E7C6F7D2E687A0A89  
Host:127.0.0.1:8080  
Origin:http://127.0.0.1:8080  
Referer:http://127.0.0.1:8080/test/index.jsp  
User-Agent:Mozilla/5.0 (Windows NT 6.1)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.149 Safari/537.36  
   
Request Payload  
name=mikan&address=street  
   
Response Headers  
Content-Length:2  
Date:Sun, 11 May 2014 11:49:23 GMT  
Server:Apache-Coyote/1.1  

요청 한 Content-type 은 text/plain 입 니 다.charset=UTF-8,요청 폼 인 자 는 RequestPayload 에 있 습 니 다.
그럼 servlet 에 서 는 request.getParameter(name)를 통 해 비어 있 습 니 다.왜 일 까요?이런 인 자 는 어떻게 가 져 와 야 합 니까?
이 문 제 를 이해 하기 위해 자 료 를 찾 아 보 았 고 Tomcat 7.0.53 요청 매개 변수 처리 에 관 한 소스 코드 도 보고 어떻게 된 일 인지 알 게 되 었 습 니 다.
HTTP POST 폼 이 제출 을 요청 할 때 사용 하 는 Content-Type 은 application/x-www-form-urlencoded 이 고,원생 AJAX 의 POST 요청 을 사용 하여 요청 헤더 RequestHeader 를 지정 하지 않 으 면 기본적으로 사용 하 는 Content-Type 은 text/plain 입 니 다.charset=UTF-8。
Tomcat 은 Content-Type multipart/form-data(파일 업로드)와 application/x-www-form-urlencoded(POST 요청)에 대해'특수 처리'를 했 기 때문이다.
다음은 관련 처리 코드 를 살 펴 보 겠 습 니 다.
Tomcat 의 HttpServletRequest 클래스 의 구현 클래스 는 org.apache.catalina.connector.Request(실제 org.apache.coyote.Request)이 며,요청 파 라 메 터 를 처리 하 는 방법 은 proctected void parseParameters()입 니 다.이 방법 은 Content-type multipart/form-data(파일 업로드)와 application/x-www-form-urlencoded(POST 요청)에 대한 처리 코드 는 다음 과 같 습 니 다.
protectedvoid parseParameters() {  
           //      ......  
           parameters.handleQueryParameters();//      url      
           //      ......  
           if ("multipart/form-data".equals(contentType)) { //              
                parseParts();  
                success = true;  
                return;  
           }  
   
           if(!("application/x-www-form-urlencoded".equals(contentType))) {//       POST      ,        
                success = true;  
                return;  
           }  
           //         POST      
           //      ......  
           try {  
                if (readPostBody(formData, len)!= len) { //          
                    return;  
                }  
           } catch (IOException e) {  
                // Client disconnect  
                if(context.getLogger().isDebugEnabled()) {  
                    context.getLogger().debug(  
                            sm.getString("coyoteRequest.parseParameters"),e);  
                }  
                return;  
           }  
           parameters.processParameters(formData, 0, len); //   POST    ,    requestparameter map ( request.getParameterMap    Map,request.getParameter(name)     Map    )  
           //       ......  
}  
   
   protected int readPostBody(byte 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);  
       return len;  
    }  

위의 코드 를 통 해 알 수 있 듯 이 Content-type 은 application/x-ww-form-urlencoded 의 POST 요청 이 아니 라 요청 체 데 이 터 를 읽 고 해당 하 는 매개 변 수 를 처리 하지 않 습 니 다.즉,폼 데 이 터 를 분석 하지 않 고 request parameter map 에 넣 지 않 습 니 다.그래서 request.getParameter(name)를 통 해 얻 을 수 없습니다.
그러면 이렇게 제출 한 인 자 를 어떻게 가 져 와 야 합 니까?
물론 가장 원시 적 인 방식 으로 입력 흐름 을 읽 어서 얻 었 습 니 다req.getReader()다음 과 같 습 니 다.
private String 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();  
}  

물론 application/x-ww-form-urlencoded 를 설정 한 POST 요청 도 이런 방식 으로 얻 을 수 있 습 니 다.
따라서 원생 AJAX POST 요청 을 사용 할 때 Request Header 를 명 확 히 설정 해 야 합 니 다.즉:
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  

또한 jQuery 를 사용 하면 저 는 1.11.0 버 전 으로 테스트 합 니 다.$.ajax post 요청 은 이 요청 헤드 를 명확 하 게 설정 할 필요 가 없습니다.다른 버 전의 본인 은 직접 테스트 한 적 이 없습니다.1.11.0 이후 버 전도 설정 할 필요 가 없다 고 믿 습 니 다.하지만 전에 있 었 던 건 모 르 겠 어 요.이 건 테스트 를 해 본 적 이 없어 요.
최근 책 을 읽 을 때 서버 가 왜 폼 제출 과 파일 업로드 에 대해 특별한 처 리 를 하 는 지 알 게 되 었 다.
폼 제출 데 이 터 는 이름 값 이 맞 고 Content-type 은 application/x-ww-form-urlencoded 이 며 파일 업로드 서버 는 특수 처리 가 필요 하기 때 문 입 니 다.일반적인 post 요청(Content-type 은 application/x-ww-form-urlencoded 가 아 닙 니 다)데이터 형식 이 고정 되 지 않 아 이름 값 이 맞 는 방식 이 아 닙 니 다.따라서 서버 는 구체 적 인 처리 방식 을 알 수 없 기 때문에 원본 데이터 흐름 을 가 져 오 는 방식 으로 만 해석 할 수 있 습 니 다.
jquery 는 post 요청 을 수행 할 때 Content-Type 을 application/x-www-form-urlencoded 로 설정 하기 때문에 서버 가 올 바 르 게 해석 할 수 있 습 니 다.원생 ajax 요청 을 사용 할 때 표시 되 지 않 는 Content-Type 을 설정 하면 기본 값 은 text/plain 입 니 다.이 때 서버 는 데 이 터 를 어떻게 해석 해 야 할 지 모 릅 니 다.그래서 원본 데이터 흐름 을 가 져 오 는 방식 으로 요청 데 이 터 를 분석 할 수 밖 에 없습니다.

좋은 웹페이지 즐겨찾기