String message = URLEncoder.encode("my message", "UTF-8");
try {
// instantiate the URL object with the target URL of the resource to
// request
URL url = new URL("http://www.example.com/comment");
// instantiate the HttpURLConnection with the URL object - A new
// connection is opened every time by calling the openConnection
// method of the protocol handler for this URL.
// 1. This is the point where the connection is opened.
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
// set connection output to true
connection.setDoOutput(true);
// instead of a GET, we're going to send using method="POST"
connection.setRequestMethod("POST");
// instantiate OutputStreamWriter using the output stream, returned
// from getOutputStream, that writes to this connection.
// 2. This is the point where you'll know if the connection was
// successfully established. If an I/O error occurs while creating
// the output stream, you'll see an IOException.
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
// write data to the connection. This is data that you are sending
// to the server
// 3. No. Sending the data is conducted here. We established the
// connection with getOutputStream
writer.write("message=" + message);
// Closes this output stream and releases any system resources
// associated with this stream. At this point, we've sent all the
// data. Only the outputStream is closed at this point, not the
// actual connection
writer.close();
// if there is a response code AND that response code is 200 OK, do
// stuff in the first if block
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// OK
// otherwise, if any other status code is returned, or no status
// code is returned, do stuff in the else block
} else {
// Server returned HTTP error code.
}
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
귀하의 질문에 대한 처음 3 답변은 위의 HTTP POST 예제에서 각 방법 옆에 인라인 주석으로 나열됩니다.
에서 로 getOutputStream :
이 연결에 쓰는 출력 스트림을 반환합니다.
기본적으로 나는 이것이 어떻게 작동하는지 잘 이해하고 있다고 생각하므로 평신도의 용어로 반복하겠습니다. getOutputStream
기본적으로 서버에 데이터를 쓰려는 의도로 연결 스트림을 엽니 다 . 위의 코드 예에서 "메시지"는 게시물에 남겨진 주석을 나타내는 서버로 보내는 주석 일 수 있습니다. 이 표시되면 쓰기 위해 연결 스트림을 getOutputStream
여는 중이지만을 호출 할 때까지 실제로 데이터를 쓰지 않습니다 .writer.write("message=" + message);
에서 ()는 getInputStream :
이 열린 연결에서 읽는 입력 스트림을 반환합니다. 데이터를 읽을 수있게되기 전에 읽기 시간 초과가 만료되면 반환 된 입력 스트림에서 읽을 때 SocketTimeoutException이 발생할 수 있습니다.
getInputStream
반대입니다. 마찬가지로 연결 스트림 getOutputStream
도 열리지 만 서버에서 데이터를 쓰지 않고 읽습니다. 연결 또는 스트림 열기에 실패하면가 표시 됩니다.SocketTimeoutException
getInputStream은 어떻습니까? getInputStream에서만 응답을 얻을 수 있기 때문에 getOutputStream에서 요청을 보내지 않고 단순히 연결을 설정한다는 의미입니까?
요청 전송과 데이터 전송은 서로 다른 두 가지 작업입니다. getOutputStream 또는 getInputStream 을 호출 url.openConnection()
하면 서버에 연결 설정 요청을 보냅니다. 서버가 연결이 설정되었다는 승인을 다시 보내는 핸드 셰이크가 있습니다. 그런 다음 데이터를 보내거나받을 준비가 된 시점입니다. 따라서 요청을 작성하는 목적이 데이터를 전송하는 것이 아니라면 스트림을 열어 연결 을 설정하기 위해 getOutputStream을 호출 할 필요가 없습니다 .
평신도의 관점에서, getInputStream
요청하는 것은 친구의 집에 전화를 걸어 "이봐, 내가 그 쌍의 바이스 그립을 빌려도 괜찮습니까?"라고 말하는 것과 같습니다. 친구가 "확실히 와라."라고 말함으로써 악수를 설정합니다. 그런 다음 연결이 이루어지고 친구 집으로 걸어 가서 문을 두드리고 바이스 그립을 요청한 다음 집으로 돌아갑니다.
비슷한 예를 사용 getOutputStream
하여 친구에게 전화를 걸어 "이봐, 내가 돈을 빚지고있다, 그것을 보낼 수 있니?" 돈이 필요하고 몸이 아파서 오랫동안 오래 간직한 친구는 "물론, 싸구려 놈 이여." 그래서 당신은 당신의 친구의 집으로 걸어 돈을 그에게 "POST". 그는 당신을 쫓아 내고 집으로 돌아갑니다.
이제 평신도의 모범으로 계속해서 몇 가지 예외를 살펴 보겠습니다. 친구에게 전화했는데 집에 없었다면 500 오류 일 수 있습니다. 친구가 항상 돈을 빌리는 데 지쳐서 전화를 걸고 연결이 끊긴 번호 메시지를 받았다면 404 페이지를 찾을 수 없습니다. 청구서를 지불하지 않아 휴대 전화가 죽은 경우 IOException이 될 수 있습니다. (참고 :이 섹션은 100 % 정확하지 않을 수 있습니다. 일반인의 관점에서 무슨 일이 일어나고 있는지에 대한 일반적인 아이디어를 제공하기위한 것입니다.)
질문 # 5 :
예, openConnection은 단순히 새 연결 객체를 생성하지만 설정하지는 않습니다. getInputStream 또는 getOutputStream을 호출하면 연결이 설정됩니다.
openConnection
새로운 연결 객체를 만듭니다. 로부터 URL.openConnection의의 javadoc :
이 URL에 대한 프로토콜 핸들러의 openConnection 메소드를 호출하여 매번 새 연결이 열립니다.
openConnection을 호출하면 연결이 설정되고 인스턴스화 할 때 InputStream, OutputStream 또는 둘 다 호출됩니다.
질문 # 6 :
오버 헤드를 측정하기 위해 일반적으로 전체 연결 블록 주위에 매우 간단한 타이밍 코드를 다음과 같이 래핑합니다.
long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );
// run the above example code here
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );
요청 시간과 오버 헤드를 측정하기위한 고급 방법이 있지만 이것이 일반적으로 내 요구에 충분합니다.
요청하지 않은 연결을 닫는 방법에 대한 자세한 내용은 언제 URL 연결이 닫히나요?를 참조하십시오 . .