Java - легко надсилає параметри HTTP через метод POST


319

Я успішно використовую цей код для надсилання HTTPзапитів із деякими параметрами за допомогою GETметоду

void sendRequest(String request)
{
    // i.e.: request = "http://example.com/index.php?param1=a&param2=b&param3=c";
    URL url = new URL(request); 
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();           
    connection.setDoOutput(true); 
    connection.setInstanceFollowRedirects(false); 
    connection.setRequestMethod("GET"); 
    connection.setRequestProperty("Content-Type", "text/plain"); 
    connection.setRequestProperty("charset", "utf-8");
    connection.connect();
}

Тепер мені може знадобитися надіслати параметри (тобто param1, param2, param3) POSTметодом, оскільки вони дуже довгі. Я думав додати додатковий параметр до цього методу (тобто String httpMethod).

Як я можу змінити код вище якомога менше, щоб мати можливість надсилати параметри через GETабо POST?

Я сподівався, що зміниться

connection.setRequestMethod("GET");

до

connection.setRequestMethod("POST");

зробив би трюк, але параметри все ще надсилаються методом GET.

Чи HttpURLConnectionє якийсь метод, який би допоміг? Чи є якась корисна конструкція Java?

Будь-яка допомога буде дуже вдячна.


Параметри публікації надсилаються всередині розділу заголовка http, а не в URL-адресі. (ваша URL-адреса буде http://example.com/index.php)
dacwe

2
у Java 1.6 не визначено методу setRequestMethod: docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html
ante.sabo

2
Відкиньте Http (s) UrlConnection ....
Пітер

продовження питання!
Хтось

1
Чому перший фрагмент коду починається з ключового слова "функція"?
Llew Vallis

Відповіді:


470

У запиті GET параметри надсилаються як частина URL-адреси.

У запиті POST параметри надсилаються як тіло запиту, після заголовків.

Щоб виконати POST за допомогою HttpURLConnection, вам потрібно записати параметри до з'єднання після того, як ви відкрили з'єднання.

Цей код повинен розпочати:

String urlParameters  = "param1=a&param2=b&param3=c";
byte[] postData       = urlParameters.getBytes( StandardCharsets.UTF_8 );
int    postDataLength = postData.length;
String request        = "http://example.com/index.php";
URL    url            = new URL( request );
HttpURLConnection conn= (HttpURLConnection) url.openConnection();           
conn.setDoOutput( true );
conn.setInstanceFollowRedirects( false );
conn.setRequestMethod( "POST" );
conn.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded"); 
conn.setRequestProperty( "charset", "utf-8");
conn.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
conn.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( conn.getOutputStream())) {
   wr.write( postData );
}

40
@Alan Geleynse: 'url.openconnection ()' не відкриває з'єднання. Якщо ви не вказуєте оператор connect (), з'єднання відкривається, коли ви пишете в тел / запит http та надіслано та відправляєте його. Я спробував це з сертифікатами. Рукостискання ssl відбувається лише після дзвінка підключення або під час надсилання даних на сервер.
Ешвін

14
getBytes () використовує діапазон середовища за замовчуванням середовища, НЕ UTF-8 charset = utf-8 повинен переслідувати тип вмісту: application / x-www-form-urlencoded; charset = utf-8 Ви виконуєте перетворення байтів двічі у прикладі. Повинні робити: byte [] data = urlParameters.getData ("UTF-8"); connection.getOutputStream (). write (дані); немає потреби закривати І промивати та відключати
Пітер Крінс

8
@PeterKriens Дякую за ваше додаток - я вважаю, ви мали на увазі byte[] data = urlParameters.getBytes(Charset.forName("UTF-8")):).
Геррітан

7
@AlanGeleynse Не пропустіть wr.flush (); і wr.close (); в кінці?
confile

9
Звідки в цьому стільки результатів, якщо він не працює? Вам потрібно зателефонувати conn.getResponseCode()або в conn.getInputStream()іншому випадку, він не надсилатиме даних.
Імаскар

229

Ось простий приклад, який подає форму, а потім пересилає сторінку результатів System.out. Звичайно, змініть параметри URL-адреси та POST:

import java.io.*;
import java.net.*;
import java.util.*;

class Test {
    public static void main(String[] args) throws Exception {
        URL url = new URL("http://example.net/new-message.php");
        Map<String,Object> params = new LinkedHashMap<>();
        params.put("name", "Freddie the Fish");
        params.put("email", "fishie@seamail.example.com");
        params.put("reply_to_thread", 10394);
        params.put("message", "Shark attacks in Botany Bay have gotten out of control. We need more defensive dolphins to protect the schools here, but Mayor Porpoise is too busy stuffing his snout with lobsters. He's so shellfish.");

        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String,Object> param : params.entrySet()) {
            if (postData.length() != 0) postData.append('&');
            postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes("UTF-8");

        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
        conn.setDoOutput(true);
        conn.getOutputStream().write(postDataBytes);

        Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

        for (int c; (c = in.read()) >= 0;)
            System.out.print((char)c);
    }
}

Якщо ви хочете, щоб результат був Stringзамість безпосередньо роздрукованого, зробіть:

        StringBuilder sb = new StringBuilder();
        for (int c; (c = in.read()) >= 0;)
            sb.append((char)c);
        String response = sb.toString();

Це найкраща відповідь, оскільки вона включає кодування параметрів та використання Map.
Ейрі

4
На жаль, цей код передбачає кодування вмісту UTF-8, що не завжди так. Для отримання шаблону слід отримати заголовок Content-Typeта проаналізувати його. Коли цей заголовок не доступний, використовуйте стандартний HTTP один: ISO-8859-1.
інженерне

@Aprel IFTFY ... використання виразів із побічними ефектами в оцінках справді некрасиво.

1
@engineercoding На жаль, для HTML це навіть складніше, ніж це зробити повністю правильно, оскільки всередині документа може бути також Unicode BOM <meta charset="...">або <meta http-equiv="Content-Type" content="...">заголовк або або заголовок.
Боан

1
@Nepster Не роби цього. response += line;феноменально повільно, і він їсть розриви ліній. Я додав до відповіді приклад отримання строкової відповіді.
Боан

63

Я не міг отримати приклад Алана насправді виконувати посаду, тому я закінчив це:

String urlParameters = "param1=a&param2=b&param3=c";
URL url = new URL("http://example.com/index.php");
URLConnection conn = url.openConnection();

conn.setDoOutput(true);

OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());

writer.write(urlParameters);
writer.flush();

String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

while ((line = reader.readLine()) != null) {
    System.out.println(line);
}
writer.close();
reader.close();         

1
На жаль, цей код не читає відповіді. Він читає html порожню форму.
Ковач Імре

Що я мав додати до прикладу Алана, це відкриття потоку відповідей. до того, як я це зробив, жодних байтів насправді не було надіслано.
beefeather

1
Видалення виклику Writer.close () зробило це для мене.
Максим Т

23

Я вважаю HttpURLConnectionсправді громіздким у використанні. І вам доведеться писати багато котла, коду, схильного до помилок. Мені потрібна була легка обгортка для моїх проектів на Android, і я створив бібліотеку, яку ви також можете використовувати: DavidWebb .

Наведений вище приклад можна записати так:

Webb webb = Webb.create();
webb.post("http://example.com/index.php")
        .param("param1", "a")
        .param("param2", "b")
        .param("param3", "c")
        .ensureSuccess()
        .asVoid();

Список альтернативних бібліотек можна знайти за наданим посиланням.


1
Я не збираюся голосувати, тому що ваш пост був менш відповіді, а більше реклами ... але я грав з вашою бібліотекою і мені це подобається. Дуже лаконічний; багато синтаксичного цукру; якщо ви використовуєте Java як трохи мову сценарію, як я, то це чудова бібліотека для дуже швидкого та ефективного додавання деяких HTML-взаємодій. Нульова котельня часом корисна і може бути корисною для ОП.
Декан

3
Я підтримаю. Я успішно використовував DavidWebb в одному зі своїх додатків, і буду це робити ще для двох, які я буду розробляти незабаром. Дуже простий у використанні.
Вільям Т. Маллард

Дякуємо, що використання DefaultHttpClient з https на Android не вдається з SSLPeerUnverifiedException: Немає однорангового сертифіката (навіть на правильно підписаних сертифікатах https), використання URL є громіздким (параметри кодування, перевірка результату). Використання DavidWebb працювало на мене, дякую.
Мартін Висний

немає підтримки AsyncTask? Тож за замовчуванням
блокуйте

Це дуже основна бібліотека. Програміст повинен викликати його з фонового потоку, в AsyncTask, в IntentService, в синхронізаторі і тому подібне. І це не залежить від Android -> може використовуватися і в Java SE та EE.
hgoebl

12

я прочитав вище відповіді та створив клас утиліти для спрощення запиту HTTP. Я сподіваюся, що це допоможе тобі.

Метод виклику

  // send params with Hash Map
    HashMap<String, String> params = new HashMap<String, String>();
    params.put("email","me@example.com");
    params.put("password","12345");

    //server url
    String url = "http://www.example.com";

    // static class "HttpUtility" with static method "newRequest(url,method,callback)"
    HttpUtility.newRequest(url,HttpUtility.METHOD_POST,params, new HttpUtility.Callback() {
        @Override
        public void OnSuccess(String response) {
        // on success
           System.out.println("Server OnSuccess response="+response);
        }
        @Override
        public void OnError(int status_code, String message) {
        // on error
              System.out.println("Server OnError status_code="+status_code+" message="+message);
        }
    });

Клас утиліти

import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import static java.net.HttpURLConnection.HTTP_OK;

public class HttpUtility {

 public static final int METHOD_GET = 0; // METHOD GET
 public static final int METHOD_POST = 1; // METHOD POST

 // Callback interface
 public interface Callback {
  // abstract methods
  public void OnSuccess(String response);
  public void OnError(int status_code, String message);
 }
 // static method
 public static void newRequest(String web_url, int method, HashMap < String, String > params, Callback callback) {

  // thread for handling async task
  new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     String url = web_url;
     // write GET params,append with url
     if (method == METHOD_GET && params != null) {
      for (Map.Entry < String, String > item: params.entrySet()) {
       String key = URLEncoder.encode(item.getKey(), "UTF-8");
       String value = URLEncoder.encode(item.getValue(), "UTF-8");
       if (!url.contains("?")) {
        url += "?" + key + "=" + value;
       } else {
        url += "&" + key + "=" + value;
       }
      }
     }

     HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
     urlConnection.setUseCaches(false);
     urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // handle url encoded form data
     urlConnection.setRequestProperty("charset", "utf-8");
     if (method == METHOD_GET) {
      urlConnection.setRequestMethod("GET");
     } else if (method == METHOD_POST) {
      urlConnection.setDoOutput(true); // write POST params
      urlConnection.setRequestMethod("POST");
     }

     //write POST data 
     if (method == METHOD_POST && params != null) {
      StringBuilder postData = new StringBuilder();
      for (Map.Entry < String, String > item: params.entrySet()) {
       if (postData.length() != 0) postData.append('&');
       postData.append(URLEncoder.encode(item.getKey(), "UTF-8"));
       postData.append('=');
       postData.append(URLEncoder.encode(String.valueOf(item.getValue()), "UTF-8"));
      }
      byte[] postDataBytes = postData.toString().getBytes("UTF-8");
      urlConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
      urlConnection.getOutputStream().write(postDataBytes);

     }
     // server response code
     int responseCode = urlConnection.getResponseCode();
     if (responseCode == HTTP_OK && callback != null) {
      BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
      StringBuilder response = new StringBuilder();
      String line;
      while ((line = reader.readLine()) != null) {
       response.append(line);
      }
      // callback success
      callback.OnSuccess(response.toString());
      reader.close(); // close BufferReader
     } else if (callback != null) {
      // callback error
      callback.OnError(responseCode, urlConnection.getResponseMessage());
     }

     urlConnection.disconnect(); // disconnect connection
    } catch (IOException e) {
     e.printStackTrace();
     if (callback != null) {
      // callback error
      callback.OnError(500, e.getLocalizedMessage());
     }
    }
   }
  }).start(); // start thread
 }
}

10

Я бачу, що деякі інші відповіді дали альтернативу, я особисто вважаю, що інтуїтивно ви все робите правильно;). Вибачте, у devoxx, де декілька спікерів оскаржували подібні речі.

Ось чому я особисто використовую бібліотеки HTTPClient / HttpCore Apache для виконання такої роботи, я вважаю, що їх API простіший у використанні, ніж підтримка HTTP для рідної Java. YMMV звичайно!


10
import java.net.*;

public class Demo{

  public static void main(){

       String data = "data=Hello+World!";
       URL url = new URL("http://localhost:8084/WebListenerServer/webListener");
       HttpURLConnection con = (HttpURLConnection) url.openConnection();
       con.setRequestMethod("POST");
       con.setDoOutput(true);
       con.getOutputStream().write(data.getBytes("UTF-8"));
       con.getInputStream();

    }

}

5
WTH import java.net.*;!
Yousha Aleayoub

4

У мене було те саме питання. Я хотів надсилати дані через POST. Я використав наступний код:

    URL url = new URL("http://example.com/getval.php");
    Map<String,Object> params = new LinkedHashMap<>();
    params.put("param1", param1);
    params.put("param2", param2);

    StringBuilder postData = new StringBuilder();
    for (Map.Entry<String,Object> param : params.entrySet()) {
        if (postData.length() != 0) postData.append('&');
        postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
        postData.append('=');
        postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
    }
    String urlParameters = postData.toString();
    URLConnection conn = url.openConnection();

    conn.setDoOutput(true);

    OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());

    writer.write(urlParameters);
    writer.flush();

    String result = "";
    String line;
    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

    while ((line = reader.readLine()) != null) {
        result += line;
    }
    writer.close();
    reader.close()
    System.out.println(result);

Я використовував Jsoup для розбору:

    Document doc = Jsoup.parseBodyFragment(value);
    Iterator<Element> opts = doc.select("option").iterator();
    for (;opts.hasNext();) {
        Element item = opts.next();
        if (item.hasAttr("value")) {
            System.out.println(item.attr("value"));
        }
    }

4

Метод GET і POST встановлений так ... Два типи для виклику api 1) get () та 2) post (). метод get () для отримання значення з масиву api json для отримання методу value & post () в нашому пості даних в URL-адресі та отримання відповіді.

 public class HttpClientForExample {

    private final String USER_AGENT = "Mozilla/5.0";

    public static void main(String[] args) throws Exception {

        HttpClientExample http = new HttpClientExample();

        System.out.println("Testing 1 - Send Http GET request");
        http.sendGet();

        System.out.println("\nTesting 2 - Send Http POST request");
        http.sendPost();

    }

    // HTTP GET request
    private void sendGet() throws Exception {

        String url = "http://www.google.com/search?q=developer";

        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(url);

        // add request header
        request.addHeader("User-Agent", USER_AGENT);

        HttpResponse response = client.execute(request);

        System.out.println("\nSending 'GET' request to URL : " + url);
        System.out.println("Response Code : " + 
                       response.getStatusLine().getStatusCode());

        BufferedReader rd = new BufferedReader(
                       new InputStreamReader(response.getEntity().getContent()));

        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }

        System.out.println(result.toString());

    }

    // HTTP POST request
    private void sendPost() throws Exception {

        String url = "https://selfsolve.apple.com/wcResults.do";

        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(url);

        // add header
        post.setHeader("User-Agent", USER_AGENT);

        List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
        urlParameters.add(new BasicNameValuePair("sn", "C02G8416DRJM"));
        urlParameters.add(new BasicNameValuePair("cn", ""));
        urlParameters.add(new BasicNameValuePair("locale", ""));
        urlParameters.add(new BasicNameValuePair("caller", ""));
        urlParameters.add(new BasicNameValuePair("num", "12345"));

        post.setEntity(new UrlEncodedFormEntity(urlParameters));

        HttpResponse response = client.execute(post);
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + post.getEntity());
        System.out.println("Response Code : " + 
                                    response.getStatusLine().getStatusCode());

        BufferedReader rd = new BufferedReader(
                        new InputStreamReader(response.getEntity().getContent()));

        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }

        System.out.println(result.toString());

    }

}

3

Спробуйте цю схему:

public static PricesResponse getResponse(EventRequestRaw request) {

    // String urlParameters  = "param1=a&param2=b&param3=c";
    String urlParameters = Piping.serialize(request);

    HttpURLConnection conn = RestClient.getPOSTConnection(endPoint, urlParameters);

    PricesResponse response = null;

    try {
        // POST
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
        writer.write(urlParameters);
        writer.flush();

        // RESPONSE
        BufferedReader reader = new BufferedReader(new InputStreamReader((conn.getInputStream()), StandardCharsets.UTF_8));
        String json = Buffering.getString(reader);
        response = (PricesResponse) Piping.deserialize(json, PricesResponse.class);

        writer.close();
        reader.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    conn.disconnect();

    System.out.println("PricesClient: " + response.toString());

    return response;
}

public static HttpURLConnection getPOSTConnection(String endPoint, String urlParameters) {

    return RestClient.getConnection(endPoint, "POST", urlParameters);

}


public static HttpURLConnection getConnection(String endPoint, String method, String urlParameters) {

    System.out.println("ENDPOINT " + endPoint + " METHOD " + method);
    HttpURLConnection conn = null;

    try {
        URL url = new URL(endPoint);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "text/plain");

    } catch (IOException e) {
        e.printStackTrace();
    }

    return conn;
}

3

Ця відповідь стосується конкретного випадку POST-дзвінка за допомогою спеціального POJO Java.

Використання Maven залежності для Gson для серіалізації нашого Java-об'єкта до JSON.

Встановіть Gson, використовуючи залежність нижче.

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.8.5</version>
  <scope>compile</scope>
</dependency>

Для тих, хто використовує градел, можна скористатись нижче

dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}

Інший використаний імпорт:

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.*;
import org.apache.http.impl.client.CloseableHttpClient;
import com.google.gson.Gson;

Тепер ми можемо продовжувати та використовувати HttpPost, наданий Apache

private CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://example.com");

Product product = new Product(); //custom java object to be posted as Request Body
    Gson gson = new Gson();
    String client = gson.toJson(product);

    httppost.setEntity(new StringEntity(client, ContentType.APPLICATION_JSON));
    httppost.setHeader("RANDOM-HEADER", "headervalue");
    //Execute and get the response.
    HttpResponse response = null;
    try {
        response = httpclient.execute(httppost);
    } catch (IOException e) {
        throw new InternalServerErrorException("Post fails");
    }
    Response.Status responseStatus = Response.Status.fromStatusCode(response.getStatusLine().getStatusCode());
    return Response.status(responseStatus).build();

Вищевказаний код повернеться з кодом відповіді, отриманим від виклику POST


2

тут я надіслав jsonobject як параметр // jsonobject = {"name": "lucifer", "pass": "abc"} // serverUrl = " http://192.168.100.12/testing " //host=192.168.100.12

  public static String getJson(String serverUrl,String host,String jsonobject){

    StringBuilder sb = new StringBuilder();

    String http = serverUrl;

    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(http);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setDoOutput(true);
        urlConnection.setRequestMethod("POST");
        urlConnection.setUseCaches(false);
        urlConnection.setConnectTimeout(50000);
        urlConnection.setReadTimeout(50000);
        urlConnection.setRequestProperty("Content-Type", "application/json");
        urlConnection.setRequestProperty("Host", host);
        urlConnection.connect();
        //You Can also Create JSONObject here 
        OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
        out.write(jsonobject);// here i sent the parameter
        out.close();
        int HttpResult = urlConnection.getResponseCode();
        if (HttpResult == HttpURLConnection.HTTP_OK) {
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    urlConnection.getInputStream(), "utf-8"));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
            br.close();
            Log.e("new Test", "" + sb.toString());
            return sb.toString();
        } else {
            Log.e(" ", "" + urlConnection.getResponseMessage());
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    } finally {
        if (urlConnection != null)
            urlConnection.disconnect();
    }
    return null;
}

2

Я дуже рекомендую http-запит, побудований на апачі http api.

Для вашого випадку ви можете побачити приклад:

private static final HttpRequest<String.class> HTTP_REQUEST = 
      HttpRequestBuilder.createPost("http://example.com/index.php", String.class)
           .responseDeserializer(ResponseDeserializer.ignorableDeserializer())
           .build();

public void sendRequest(String request){
     String parameters = request.split("\\?")[1];
     ResponseHandler<String> responseHandler = 
            HTTP_REQUEST.executeWithQuery(parameters);

   System.out.println(responseHandler.getStatusCode());
   System.out.println(responseHandler.get()); //prints response body
}

Якщо вас не цікавить орган реагування

private static final HttpRequest<?> HTTP_REQUEST = 
     HttpRequestBuilder.createPost("http://example.com/index.php").build();

public void sendRequest(String request){
     ResponseHandler<String> responseHandler = 
           HTTP_REQUEST.executeWithQuery(parameters);
}

Загальне надсилання запиту на пошту з http-запитом : Прочитайте документацію та подивіться мої відповіді HTTP POST-запит з JSON String в JAVA , Надсилання запиту HTTP POST на Java , HTTP POST з використанням JSON в Java


1

Привіт, будь ласка, використовуйте цей клас, щоб покращити ваш пост

public static JSONObject doPostRequest(HashMap<String, String> data, String url) {

    try {
        RequestBody requestBody;
        MultipartBuilder mBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);

        if (data != null) {


            for (String key : data.keySet()) {
                String value = data.get(key);
                Utility.printLog("Key Values", key + "-----------------" + value);

                mBuilder.addFormDataPart(key, value);

            }
        } else {
            mBuilder.addFormDataPart("temp", "temp");
        }
        requestBody = mBuilder.build();


        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        OkHttpClient client = new OkHttpClient();
        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        Utility.printLog("URL", url);
        Utility.printLog("Response", responseBody);
        return new JSONObject(responseBody);

    } catch (UnknownHostException | UnsupportedEncodingException e) {

        JSONObject jsonObject=new JSONObject();

        try {
            jsonObject.put("status","false");
            jsonObject.put("message",e.getLocalizedMessage());
        } catch (JSONException e1) {
            e1.printStackTrace();
        }
        Log.e(TAG, "Error: " + e.getLocalizedMessage());
    } catch (Exception e) {
        e.printStackTrace();
        JSONObject jsonObject=new JSONObject();

        try {
            jsonObject.put("status","false");
            jsonObject.put("message",e.getLocalizedMessage());
        } catch (JSONException e1) {
            e1.printStackTrace();
        }
        Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
    }
    return null;
}

0

Я взяв відповідь Боана і використав її для створення більш гнучких конструкторів рядків запитів, який підтримує списки та масиви, як і метод http_build_query php:

public static byte[] httpBuildQueryString(Map<String, Object> postsData) throws UnsupportedEncodingException {
    StringBuilder postData = new StringBuilder();
    for (Map.Entry<String,Object> param : postsData.entrySet()) {
        if (postData.length() != 0) postData.append('&');

        Object value = param.getValue();
        String key = param.getKey();

        if(value instanceof Object[] || value instanceof List<?>)
        {
            int size = value instanceof Object[] ? ((Object[])value).length : ((List<?>)value).size();
            for(int i = 0; i < size; i++)
            {
                Object val = value instanceof Object[] ? ((Object[])value)[i] : ((List<?>)value).get(i);
                if(i>0) postData.append('&');
                postData.append(URLEncoder.encode(key + "[" + i + "]", "UTF-8"));
                postData.append('=');            
                postData.append(URLEncoder.encode(String.valueOf(val), "UTF-8"));
            }
        }
        else
        {
            postData.append(URLEncoder.encode(key, "UTF-8"));
            postData.append('=');            
            postData.append(URLEncoder.encode(String.valueOf(value), "UTF-8"));
        }
    }
    return postData.toString().getBytes("UTF-8");
}

0

Для тих, хто має проблеми з отриманням запиту на сторінці php за допомогою $ _POST, тому що ви очікуєте пар ключ-значення:

Хоча всі відповіді, де дуже корисні, мені не вистачило базового розуміння, яку строку насправді опублікувати, оскільки в старому апачі HttpClient я використовував

new UrlEncodedFormEntity(nameValuePairs); (Java)

а потім може використовувати $ _POST у php, щоб отримати пари ключ-значення.

Наскільки я розумію, зараз слід створити цей рядок вручну перед публікацією. Отже, струна повинна виглядати так

val data = "key1=val1&key2=val2"

але замість того, щоб просто додати його до URL, він розміщується (у заголовку).

Альтернативою було б використовувати натомість json-рядок:

val data = "{\"key1\":\"val1\",\"key2\":\"val2\"}" // {"key1":"val1","key2":"val2"}

і витягніть його в php без $ _POST:

$json_params = file_get_contents('php://input');
// echo_p("Data: $json_params");
$data = json_decode($json_params, true);

Тут ви знайдете зразок коду в Котліні:

class TaskDownloadTest : AsyncTask<Void, Void, Void>() {
    override fun doInBackground(vararg params: Void): Void? {
        var urlConnection: HttpURLConnection? = null

        try {

            val postData = JsonObject()
            postData.addProperty("key1", "val1")
            postData.addProperty("key2", "val2")

            // reformat json to key1=value1&key2=value2
            // keeping json because I may change the php part to interpret json requests, could be a HashMap instead
            val keys = postData.keySet()
            var request = ""
            keys.forEach { key ->
                // Log.i("data", key)
                request += "$key=${postData.get(key)}&"
            }
            request = request.replace("\"", "").removeSuffix("&")
            val requestLength = request.toByteArray().size
            // Warning in Android 9 you need to add a line in the application part of the manifest: android:usesCleartextTraffic="true"
            // /programming/45940861/android-8-cleartext-http-traffic-not-permitted
            val url = URL("http://10.0.2.2/getdata.php")
            urlConnection = url.openConnection() as HttpURLConnection
            // urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") // apparently default
            // Not sure what these are for, I do not use them
            // urlConnection.setRequestProperty("Content-Type", "application/json")
            // urlConnection.setRequestProperty("Key","Value")
            urlConnection.readTimeout = 5000
            urlConnection.connectTimeout = 5000
            urlConnection.requestMethod = "POST"
            urlConnection.doOutput = true
            // urlConnection.doInput = true
            urlConnection.useCaches = false
            urlConnection.setFixedLengthStreamingMode(requestLength)
            // urlConnection.setChunkedStreamingMode(0) // if you do not want to handle request length which is fine for small requests

            val out = urlConnection.outputStream
            val writer = BufferedWriter(
                OutputStreamWriter(
                    out, "UTF-8"
                )
            )
            writer.write(request)
            // writer.write("{\"key1\":\"val1\",\"key2\":\"val2\"}") // {"key1":"val1","key2":"val2"} JsonFormat or just postData.toString() for $json_params=file_get_contents('php://input'); json_decode($json_params, true); in php
            // writer.write("key1=val1&key2=val2") // key=value format for $_POST in php
            writer.flush()
            writer.close()
            out.close()

            val code = urlConnection.responseCode
            if (code != 200) {
                throw IOException("Invalid response from server: $code")
            }

            val rd = BufferedReader(
                InputStreamReader(
                    urlConnection.inputStream
                )
            )
            var line = rd.readLine()
            while (line != null) {
                Log.i("data", line)
                line = rd.readLine()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            urlConnection?.disconnect()
        }

        return null
    }
}

-3

Здається, що вам також доведеться зателефонувати connection.getOutputStream()"хоча б раз" (як іsetDoOutput(true) ), щоб він ставився до нього як до POST.

Отже мінімально необхідний код:

    URL url = new URL(urlString);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    //connection.setRequestMethod("POST"); this doesn't seem to do anything at all..so not useful
    connection.setDoOutput(true); // set it to POST...not enough by itself however, also need the getOutputStream call...
    connection.connect();
    connection.getOutputStream().close(); 

Ви навіть можете використовувати параметри стилю "GET" в urlString, на диво. Хоча це може заплутати речі.

Ви також можете використовувати NameValuePair, мабуть.


Де параметри POST ...?
Yousha Aleayoub

Чому люди заперечують це? Це примітка про те, як взагалі робити POST, хоча без параметрів ... (тобто немає корисного навантаження0 ...
rogerdpack
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.