2016-09-20 2 views
1

HttpsURLConnection 호출을 사용하여 HTTP 서블릿에서 메시지 및 오류 코드와 함께 응답을받습니다. 내 코드에서 일부 코드는 다음과 같은 : - 측면의 HttpServlet에서HttpsURLConnection.getResponseCode() -1 대신 1001 또는 1002 또는 1003을 반환합니다.

 connection = (HttpsURLConnection) url.openConnection(); 
      connection.setDoInput(true); 
      connection.setDoOutput(true); 
      connection.setUseCaches(false); 

      // Headers 
      connection.setRequestMethod("POST"); 
      connection.setRequestProperty("Content-type", "text/xml"); 
      connection.setRequestProperty("Accept", "text/plain"); 
      connection.setRequestProperty("Connection", "Keep-Alive"); 
      connection.setRequestProperty("Authorization", authorization); 

      connection.connect(); 

, 난 상태 코드와 설명을 설정하고있다 : -

response.setStatus(code); 
    response.getWriter().write(returnDescription); 

위의 모든 코드는 기존되는 코드와 그것을 제외하고 잘 작동합니다. 응답 코드로 상태 코드를 반환해야합니다. 그러나 거의 코드가 1001,1002 또는 1003처럼 작동하지 않습니다. 즉, response.setStatus (1001)를 설정하면 "java.io.IOException : Invalid Http response"가있는 클라이언트 측에서 responseCode()를 -1로 반환합니다. 1101,1102, 1232 등의 다른 정수 값의 경우 제대로 작동합니다. 코드를 디버그하고 서블릿이 올바른 값을 설정하고 있지만 클라이언트가 응답을 구문 분석 할 수 없음을 발견했습니다. 그리고 다른 숫자 값으로 상태 코드를 변경하면 제대로 작동하기 시작합니다! HTTPS뿐만 아니라 HTTP에서도 동일한 동작이 나타납니다. 이러한 비 작동 코드는 특정 목적을 가진 미리 정의 된 코드로 보이며 상태 코드로 사용할 수 없지만 웹에서 아무 것도 찾지 못했습니다. 누구도 같은 것을 경험했고 이유가 무엇인지 알았습니까?

미리 감사드립니다. :)

답변

0

짧은 버전 : OpenJDK 및 다른 사람들은 HTTP 상태 코드 번호의 3자를 정확히 파싱하는 parseHttpHeader 메서드를 사용하며 '100'문자열로 시작하는 모든 것은 HTTP continue로 처리됩니다. 이 서블릿 대화의 비 연속적 특성으로 인해 클라이언트가 혼란을 겪었으므로 출력 스트림을 열 수없고 포기했습니다.

waaaay를 긴 버전 : 단지 100-599 (이것보다 실제로 더 적은 틱) 상태 코드는 정말 전혀 작동해야하기 때문에

이 사람은 좀 나를 도청. RFC2616에 따르면 코드는 3 자리 숫자 여야하며 첫 번째 숫자의 클래스 만 이해하면됩니다 (확장을 허용하기 위해). (지정하지 않았기 때문에)

오픈 JDK 6의 HttpURLConnection 구현은 먼저 내가 확인했고 코드는 기본적으로 수행합니다

  • 잡아 응답의 첫 번째 줄을.
  • HTTP/1을 찾으십시오. 0.9는 분명히 신경 쓰지 않고 두 번째 숫자는 무시합니다.
  • 텍스트 이유로 인해 모든 것을 찾습니다.
  • int가 중간에 있으면 구문 분석을 시도하십시오.

GNU Classpath는 거의 같습니다.

특히 OpenJDK는 RFC 규칙에 대해 특별히 심사하지 않습니다. 당신은 10 억을 거기에 넣을 수 있습니다. (적어도 getResponseCode()가 신경 쓰지 만, 어쨌든 ... getInputStream()은 모든 코드에서 barf가됩니다. sun.net.www.protocol ...의 구체적인 구현).

어쨌든이 홀수 동작이 100 배 밖에 안되는 이유는 무엇입니까? "서버 반환 된 HTTP 1234 ...

... 또는 그래서 나는 생각했다 .HttpURLConnection 추상, 그래서 구체적인 구현 적어도 추상 메서드를 재정의해야합니다 OpenJDK 것 같습니다.음, concrete implementation of HttpURLConnection, 추상 버전의 getResponseCode()는 무시됩니다. 킨다. 이 구현은 HTTP/1을 구문 분석하는 입력 스트림 열기의 일부로 sun.net.www.http.HttpClient의 parseHTTP를 호출합니다. 그런 다음 코드의 정확히 세자를 입력합니다. 그런 다음 입력 스트림을 마사지하여 HttpCapture라고하는 항목에서 소급하여 다시 밀어 넣습니다. 그 세 문자가 come out to 100에 발생하면 클라이언트는 작동중인 InputStream을 얻기 위해 대화를 계속해야한다고 생각합니다.

실제로 서블릿이 이미 트랜잭션으로 완료되었으므로 계속되지 않으므로 클라이언트가 서블릿이 수행중인 WTF에 대해 혼란을 느끼고 있으므로 RFC에 따라 오류가 반환됩니다.

그래서 수수께끼가 풀렸다 고 생각합니다. "100"으로 시작하는 모든 것을 넣을 수 있고 동일한 동작을 얻을 수도 있습니다 (서블릿 API를 사용하면 "100xyz"조차도 가능).

(안드로이드, BTW,이 세 문자 구문 분석을 수행합니다.)

을이 모든 기술적 RFC를 (하지만, 정직하게, 그것은 바보 같은 버그의 종류의) 위반합니다. 엄밀히 말하면, 2xx 코드 만이 unmolest를 전달하기 위해 완전히 OK로 처리되어야하지만 아마도 "000"상태를 사용하고 OK를 전달할 수 있습니다 (API에서 임의의 문자열을 입력 할 수 있다고 가정 할 때).

귀하의 질문에 대한 답변입니다.

+0

감사합니다. @BJ Black. 내 질문에 대한 답변입니다. 나는 더 많이 분석해야했다. –

+0

나는 너무 많이 땀을 흘리지 않을 것이다. 나는 아주 오랫동안 자바 프로그래머로 일해 왔으며 이것은 결코 명백하지 않다. –