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 ....
Питер

расширяя вопрос! Кто-нибудь знает, как отправить вложение в качестве параметра сообщения ...
therealprashant

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 () записи (данные). бесполезно закрывать, сбрасывать и отключать
Питер Криенс

8
@PeterKriens Спасибо за ваше добавление - я думаю, что вы имели в виду byte[] data = urlParameters.getBytes(Charset.forName("UTF-8")):).
Gerrytan

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.
engineercoding

@Aprel IFTFY ... использование выражений с побочными эффектами в оценках действительно ужасно.

1
@engineercoding К сожалению, для HTML еще сложнее сделать это правильно, поскольку в документе также может быть спецификация Unicode <meta charset="...">или <meta http-equiv="Content-Type" content="...">заголовок или внутри документа, который необходимо проанализировать.
Boann

1
@ Nepster Не делай этого. response += line;феноменально медленный, и он ест разрывы строк. Я добавил к ответу пример получения строкового ответа.
Boann

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 () сделало это для меня.
Maxime T

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 в качестве языка сценариев, как я, то это отличная библиотека для очень быстрого и эффективного добавления некоторых http-взаимодействий. Нулевой шаблон иногда полезен, и, возможно, он был полезен для ОП.
декан

3
Я буду голосовать. Я успешно использовал DavidWebb в одном из своих приложений и сделаю это еще для двух, которые скоро буду разрабатывать. Очень прост в использовании.
Уильям Т. Маллард

Спасибо, использование DefaultHttpClient с https на Android завершается неудачно с SSLPeerUnverifiedException: нет сертификата однорангового узла (даже для правильно подписанных сертификатов https), использование URL является громоздким (параметры кодирования, проверка результата). Использование DavidWebb работало для меня, спасибо.
Мартин Высный

нет поддержки AsyncTask? Так что блокировка потока пользовательского интерфейса по умолчанию ... это плохо
slinden77

Это очень простая библиотека. Программист должен вызывать его из фонового потока, в 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, где несколько спикеров разглагольствовали об этом.

Вот почему я лично использую библиотеки Apache HTTPClient / HttpCore для этой работы, и я считаю, что их API проще в использовании, чем встроенная поддержка Java в HTTP. 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.*;!
Юша Алеауб

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 с использованием пользовательского Java POJO.

Использование зависимости maven для Gson для сериализации нашего Java-объекта в JSON.

Установите Gson, используя зависимость ниже.

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

Для тех, кто использует gradle, можете использовать ниже

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 Call


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-запрос, основанный на apache 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 в 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

Я взял ответ Боанна и использовал его для создания более гибкого построителя строк запросов, который поддерживает списки и массивы, как и метод php http_build_query:

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, потому что вы ожидаете пары ключ-значение:

Хотя все ответы были очень полезны, мне не хватало базового понимания, какую строку на самом деле отправлять, поскольку в старом apache 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 ...?
Юша Алеауб

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