Java로 HTTP POST 요청 보내기


294

이 URL을 가정하자 ...

http://www.example.com/page.php?id=10            

(여기서 ID는 POST 요청으로 전송되어야합니다)

POST 메소드에서 id = 10서버 page.php의을 (를) 서버 에 보내고 싶습니다 .

Java 내에서 어떻게 할 수 있습니까?

나는 이것을 시도했다 :

URL aaa = new URL("http://www.example.com/page.php");
URLConnection ccc = aaa.openConnection();

하지만 여전히 POST를 통해 보내는 방법을 알 수 없습니다.

답변:


339

업데이트 된 답변 :

원래 답변에서 일부 클래스는 최신 버전의 Apache HTTP 구성 요소에서 더 이상 사용되지 않으므로이 업데이트를 게시하고 있습니다.

그건 그렇고, 더 많은 예제를 보려면 전체 문서에 액세스 할 수 있습니다 .

HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("http://www.a-domain.com/foo/");

// Request parameters and other properties.
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("param-1", "12345"));
params.add(new BasicNameValuePair("param-2", "Hello!"));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));

//Execute and get the response.
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();

if (entity != null) {
    try (InputStream instream = entity.getContent()) {
        // do something useful
    }
}

원래 답변 :

Apache HttpClient를 사용하는 것이 좋습니다. 더 빠르고 쉽게 구현할 수 있습니다.

HttpPost post = new HttpPost("http://jakarata.apache.org/");
NameValuePair[] data = {
    new NameValuePair("user", "joe"),
    new NameValuePair("password", "bloggs")
};
post.setRequestBody(data);
// execute method and handle any error responses.
...
InputStream in = post.getResponseBodyAsStream();
// handle response.

자세한 내용은 다음 URL을 확인하십시오. http://hc.apache.org/


25
내 손을 얻기 위해 잠시 동안 시도 후 PostMethod실제로 지금이라고 불리는 것 같다 HttpPost따라 stackoverflow.com/a/9242394/1338936 그냥 :)했던 것처럼이 대답을 찾는 사람을 위해 -
마틴 라인 씨

1
@ Juan (및 Martin Lyne)의 의견에 감사드립니다. 방금 답변을 업데이트했습니다.
mhshams

수정 된 답변이 여전히 hc.apache.org를 사용합니까?
djangofan

@djangofan 예. 수정 된 답변에도 apache-hc에 대한 링크가 있습니다.
mhshams

6
가져온 라이브러리를 추가해야합니다
gouchaoer

191

바닐라 자바에서는 POST 요청을 쉽게 보낼 수 있습니다. 을 시작으로 URL, 우리는 t가로 변환이 필요 URLConnection사용 url.openConnection();. 그런 다음에로 캐스팅해야 HttpURLConnection하므로 setRequestMethod()메소드에 액세스하여 메소드를 설정할 수 있습니다 . 마지막으로 연결을 통해 데이터를 보내겠다고 말합니다.

URL url = new URL("https://www.example.com/login");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);

그런 다음 보낼 내용을 명시해야합니다.

간단한 양식 보내기

http 양식에서 오는 일반 POST는 형식이 잘 정의되어 있습니다. 입력을 다음 형식으로 변환해야합니다.

Map<String,String> arguments = new HashMap<>();
arguments.put("username", "root");
arguments.put("password", "sjh76HSn!"); // This is a fake password obviously
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
    sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" 
         + URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;

그런 다음 양식 내용을 http 요청에 적절한 헤더로 첨부하여 보낼 수 있습니다.

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

JSON 보내기

자바를 사용하여 json을 보낼 수도 있습니다.

byte[] out = "{\"username\":\"root\",\"password\":\"password\"}" .getBytes(StandardCharsets.UTF_8);
int length = out.length;

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

서버마다 json에 대해 다른 콘텐츠 유형을 허용 합니다. 질문을 참조하십시오 .


자바 포스트로 파일 보내기

형식이 복잡하므로 파일 전송이 처리하기가 더 어려울 수 있습니다. 또한 파일을 메모리에 완전히 버퍼링하고 싶지 않기 때문에 파일을 문자열로 보내기위한 지원을 추가 할 것입니다.

이를 위해 몇 가지 도우미 메서드를 정의합니다.

private void sendFile(OutputStream out, String name, InputStream in, String fileName) {
    String o = "Content-Disposition: form-data; name=\"" + URLEncoder.encode(name,"UTF-8") 
             + "\"; filename=\"" + URLEncoder.encode(filename,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    byte[] buffer = new byte[2048];
    for (int n = 0; n >= 0; n = in.read(buffer))
        out.write(buffer, 0, n);
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

private void sendField(OutputStream out, String name, String field) {
    String o = "Content-Disposition: form-data; name=\"" 
             + URLEncoder.encode(name,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    out.write(URLEncoder.encode(field,"UTF-8").getBytes(StandardCharsets.UTF_8));
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

그런 다음이 메소드를 사용하여 다음과 같이 멀티 파트 게시 요청을 작성할 수 있습니다.

String boundary = UUID.randomUUID().toString();
byte[] boundaryBytes = 
           ("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8);
byte[] finishBoundaryBytes = 
           ("--" + boundary + "--").getBytes(StandardCharsets.UTF_8);
http.setRequestProperty("Content-Type", 
           "multipart/form-data; charset=UTF-8; boundary=" + boundary);

// Enable streaming mode with default settings
http.setChunkedStreamingMode(0); 

// Send our fields:
try(OutputStream out = http.getOutputStream()) {
    // Send our header (thx Algoman)
    out.write(boundaryBytes);

    // Send our first field
    sendField(out, "username", "root");

    // Send a seperator
    out.write(boundaryBytes);

    // Send our second field
    sendField(out, "password", "toor");

    // Send another seperator
    out.write(boundaryBytes);

    // Send our file
    try(InputStream file = new FileInputStream("test.txt")) {
        sendFile(out, "identification", file, "text.txt");
    }

    // Finish the request
    out.write(finishBoundaryBytes);
}


// Do something with http.getInputStream()

5
이 게시물은 유용하지만 결함이 있습니다. 작동시키는 데 2 ​​일이 걸렸습니다. 따라서 작동하려면 StandartCharsets.UTF8을 StandardCharsets.UTF_8로 바꿔야합니다. boundaryBytes 및 finishBoundaryBytes는 Content-Type에서 전송되지 않는 두 개의 추가 하이픈을 가져와야하므로 boundaryBytes = ( "-"+ boundary + "\ r \ n"). get ... 또한 borderBytes를 한 번 전송해야합니다. 첫 번째 필드 또는 첫 번째 필드가 무시되기 전에!
Algoman

out.write(finishBoundaryBytes);라인이 필요합니까? http.connect();POST 전송을 수행합니까?
János 2016 년

16
"바닐라 자바에서는 POST 요청을 쉽게 보낼 수 있습니다." 그리고 파이썬에서 와 비교할 때 수십 줄의 코드가 뒤 따릅니다 requests.post('http://httpbin.org/post', data = {'key':'value'}). 저는 Java를 처음 사용하기 때문에“easy”라는 단어를 매우 이상하게 사용합니다. :)
Lynn

1
내가 그것의 자바 : 고려 예상 한 것보다 상대적으로 쉽다
shaahiin을

수수께끼 \ r \ n \ r \ n은 CRLF CRLF (캐리지 리턴 + 줄 바꿈)를 의미합니다. 2 배 새 줄을 만듭니다. 첫 번째 줄은 현재 줄을 완성하는 것입니다. 두 번째 줄은 요청에서 http 헤더와 http 본문을 구별하는 것입니다. HTTP는 ASCII 기반 프로토콜입니다. 이것은 \ r \ n을 삽입하는 규칙입니다.
Mitja Gustin

99
String rawData = "id=10";
String type = "application/x-www-form-urlencoded";
String encodedData = URLEncoder.encode( rawData, "UTF-8" ); 
URL u = new URL("http://www.example.com/page.php");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty( "Content-Type", type );
conn.setRequestProperty( "Content-Length", String.valueOf(encodedData.length()));
OutputStream os = conn.getOutputStream();
os.write(encodedData.getBytes());

유의해야 할 점 : String.getBytes () 이외의 다른 것을 사용하면 작동하지 않는 것 같습니다. 예를 들어, PrintWriter 사용은 완전히 실패합니다.
Little Bobby Tables

5
2 게시물 데이터를 설정하는 방법은 무엇입니까? 콜론으로 구분, 쉼표?
시끄러운 고양이

10
encode(String)더 이상 사용되지 않습니다. encode(String, String)인코딩 유형을 지정하는 을 사용해야 합니다. 예 : encode(rawData, "UTF-8").
sudo

3
마지막에 팔로우하고 싶을 수도 있습니다. 이렇게하면 요청이 완료되고 서버가 응답을 처리 할 기회를 얻게됩니다. conn.getResponseCode ();
Szymon Jachim 2016 년

3
전체 문자열을 인코딩하지
마십시오.

22

첫 번째 대답은 훌륭했지만 Java 컴파일러 오류를 피하기 위해 try / catch를 추가해야했습니다.
또한, 읽는 방법을 이해하는 데 어려움이있었습니다.HttpResponse Java 라이브러리를 사용 .

더 완전한 코드는 다음과 같습니다.

/*
 * Create the POST request
 */
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://example.com/");
// Request parameters and other properties.
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("user", "Bob"));
try {
    httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
} catch (UnsupportedEncodingException e) {
    // writing error to Log
    e.printStackTrace();
}
/*
 * Execute the HTTP Request
 */
try {
    HttpResponse response = httpClient.execute(httpPost);
    HttpEntity respEntity = response.getEntity();

    if (respEntity != null) {
        // EntityUtils to get the response content
        String content =  EntityUtils.toString(respEntity);
    }
} catch (ClientProtocolException e) {
    // writing exception to log
    e.printStackTrace();
} catch (IOException e) {
    // writing exception to log
    e.printStackTrace();
}

EntityUtils가 도움이되었습니다.
Jay

6
죄송하지만 오류를 발견하지 못했습니다. 처리 할 수없는 곳에서 예외를 잡는 것은 명백 e.printStackTrace()하지 않으며 아무것도 처리하지 않습니다.
maaartinus

java.net.ConnectException : 연결 시간 초과 : connect
kerZy Hart


5

게시 요청으로 매개 변수를 보내는 가장 간단한 방법 :

String postURL = "http://www.example.com/page.php";

HttpPost post = new HttpPost(postURL);

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", "10"));

UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, "UTF-8");
post.setEntity(ent);

HttpClient client = new DefaultHttpClient();
HttpResponse responsePOST = client.execute(post);

했어요 이제 사용할 수 있습니다 responsePOST. 응답 내용을 문자열로 가져옵니다.

BufferedReader reader = new BufferedReader(new  InputStreamReader(responsePOST.getEntity().getContent()), 2048);

if (responsePOST != null) {
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(" line : " + line);
        sb.append(line);
    }
    String getResponseString = "";
    getResponseString = sb.toString();
//use server output getResponseString as string value.
}

1

전화 HttpURLConnection.setRequestMethod("POST")HttpURLConnection.setDoOutput(true);POST 후 기본 방법됨에 따라 실제로 후자 만이 필요하다.


it HttpURLConnection.setRequestMethod () :)
Jose Diaz

1

아파치 http api에 빌드 된 http-request를 사용하는 것이 좋습니다 .

HttpRequest<String> httpRequest = HttpRequestBuilder.createPost("http://www.example.com/page.php", String.class)
.responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();

public void send(){
   String response = httpRequest.execute("id", "10").get();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.