【问题标题】:Android - POST to RESTful Web ServiceAndroid - POST 到 RESTful Web 服务
【发布时间】:2016-02-18 05:12:28
【问题描述】:

我正在寻找有关如何在我的 Android 应用程序中将数据发布到 Web 服务的一些指导。不幸的是,这是一个学校项目,所以我无法使用外部库。

Web 服务有一个基本 URL,例如:

http://example.com/service/create

并取两个变量,格式如下:

username = "user1"
locationname = "location1"

Web 服务是 RESTful 并使用 XML 结构,如果这会有所不同的话。根据我的研究,我知道我应该使用 URLconnection 而不是已弃用的 HTTPconnection,但我找不到我正在寻找的示例。

这是我的尝试,目前不起作用:

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toPost test = new toPost();
        text.execute();
    }

    private class toPost extends AsyncTask<URL, Void, String> {
        @Override
        protected String doInBackground(URL... params) {
            HttpURLConnection conn = null;
            try {
                URL url = new URL("http://example.com/service");
                conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);
                String body = "username=user1&locationname=location1";
                OutputStream output = new BufferedOutputStream(conn.getOutputStream());
                output.write(body.getBytes());
                output.flush();
            } catch (ProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                conn.disconnect();
            }
            return null;
        }
    }

}

【问题讨论】:

  • Retrofit 有很多例子
  • 您是否尝试过使用 Retrofit 而不是滚动自己的 HttpUrlConnection?
  • 很遗憾这是一个学校项目,所以我无法使用外部库
  • 如何添加一个json作为Body?

标签: android rest post


【解决方案1】:

我会使用 volley 库,as suggested by google

在该页面上解释了发出请求,但很简单:

final TextView mTextView = (TextView) findViewById(R.id.text);
...

// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Display the first 500 characters of the response string.
        mTextView.setText("Response is: "+ response.substring(0,500));
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mTextView.setText("That didn't work!");
    }
});
// Add the request to the RequestQueue.
queue.add(stringRequest);

【讨论】:

  • 很遗憾,我无法为此应用程序使用任何外部库
  • 为什么不呢?您可以直接从 google 导入它并与您的 apk 一起发送,我不知道会出现什么问题?
【解决方案2】:

如果要使用HttpUrlConnection,可以参考以下两个示例。希望这会有所帮助!

private class LoginRequest extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... voids) {
        String address = "http://server/login";
        HttpURLConnection urlConnection;
        String requestBody;
        Uri.Builder builder = new Uri.Builder();
        Map<String, String> params = new HashMap<>();            
        params.put("username", "bnk");
        params.put("password", "bnk123");

        // encode parameters
        Iterator entries = params.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry entry = (Map.Entry) entries.next();
            builder.appendQueryParameter(entry.getKey().toString(), entry.getValue().toString());
            entries.remove();
        }
        requestBody = builder.build().getEncodedQuery();

        try {
            URL url = new URL(address);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            OutputStream outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
            writer.write(requestBody);
            writer.flush();
            writer.close();
            outputStream.close();

            JSONObject jsonObject = new JSONObject();
            InputStream inputStream;
            // get stream
            if (urlConnection.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
                inputStream = urlConnection.getInputStream();
            } else {
                inputStream = urlConnection.getErrorStream();
            }
            // parse stream
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String temp, response = "";
            while ((temp = bufferedReader.readLine()) != null) {
                response += temp;
            }
            // put into JSONObject
            jsonObject.put("Content", response);
            jsonObject.put("Message", urlConnection.getResponseMessage());
            jsonObject.put("Length", urlConnection.getContentLength());
            jsonObject.put("Type", urlConnection.getContentType());

            return jsonObject.toString();
        } catch (IOException | JSONException e) {
            return e.toString();
        }
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.i(LOG_TAG, "POST\n" + result);
    }
}


private class JsonPostRequest extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... voids) {
        try {
            String address = "http://server/postvalue";
            JSONObject json = new JSONObject();                
            json.put("Title", "Dummy Title");
            json.put("Author", "Dummy Author");
            String requestBody = json.toString();
            URL url = new URL(address);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", "application/json");
            OutputStream outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
            writer.write(requestBody);
            writer.flush();
            writer.close();
            outputStream.close();

            InputStream inputStream;
            // get stream
            if (urlConnection.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
                inputStream = urlConnection.getInputStream();
            } else {
                inputStream = urlConnection.getErrorStream();
            }
            // parse stream
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String temp, response = "";
            while ((temp = bufferedReader.readLine()) != null) {
                response += temp;
            }
            // put into JSONObject
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("Content", response);
            jsonObject.put("Message", urlConnection.getResponseMessage());
            jsonObject.put("Length", urlConnection.getContentLength());
            jsonObject.put("Type", urlConnection.getContentType());
            return jsonObject.toString();
        } catch (IOException | JSONException e) {
            return e.toString();
        }
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.i(LOG_TAG, "POST RESPONSE: " + result);
        mTextView.setText(result);
    }
}

【讨论】:

    【解决方案3】:

    我的建议是使用RetrofitJackson converter

    Retrofit 支持异步和同步请求。它支持GETPOSTPUTDELETEHEAD方法。

    Jackson 将帮助您将 XML 解析为 JSON 对象。

    这两个都非常易于使用并且有很好的文档。

    Here你可以找到使用 Retrofit 的简单教程。

    【讨论】:

      【解决方案4】:

      使用以下代码从您的 android 应用程序调用 REST Web 服务。这是经过全面测试的代码。

      public class RestClient {
      
          static Context context;
          private static int responseCode;
          private static String response;
      
          public static String getResponse() {
              return response;
          }
      
          public static void setResponse(String response) {
              RestClient.response = response;
          }
      
          public static int getResponseCode() {
              return responseCode;
          }
      
          public static void setResponseCode(int responseCode) {
              RestClient.responseCode = responseCode;
          }
      
          public static void Execute(String requestMethod, String jsonData, String urlMethod, Context contextTemp, HashMap<String, Object> params) {
              try {
                  context = contextTemp;
                  String ip = context.getResources().getString(R.string.ip);
                  StringBuilder urlString = new StringBuilder(ip + urlMethod);
                  if (params != null) {
                      for (Map.Entry<String, Object> para : params.entrySet()) {
                          if (para.getValue() instanceof Long) {
                              urlString.append("?" + para.getKey() + "=" +(Long)para.getValue());
                          }
                          if (para.getValue() instanceof String) {
                              urlString.append("?" + para.getKey() + "=" +String.valueOf(para.getValue()));
                          }
                      }
                  }
      
                  URL url = new URL(urlString.toString());
      
                  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                  conn.setRequestMethod(requestMethod);
                  conn.setReadTimeout(10000 /*milliseconds*/);
                  conn.setConnectTimeout(15000 /* milliseconds */);
      
      
                  switch (requestMethod) {
                      case "POST" : case "PUT":
                          conn.setDoInput(true);
                          conn.setDoOutput(true);
                          conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
                          conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
                          conn.connect();
                          OutputStream os = new BufferedOutputStream(conn.getOutputStream());
                          os.write(jsonData.getBytes());
                          os.flush();
                          responseCode = conn.getResponseCode();
                          break;
                      case "GET":
                          responseCode = conn.getResponseCode();
                          System.out.println("GET Response Code :: " + responseCode);
                          break;
                       break;
      
                  }
                  if (responseCode == HttpURLConnection.HTTP_OK) { // success
                      BufferedReader in = new BufferedReader(new InputStreamReader(
                              conn.getInputStream()));
                      String inputLine;
                      StringBuffer tempResponse = new StringBuffer();
      
                      while ((inputLine = in.readLine()) != null) {
                          tempResponse.append(inputLine);
                      }
                      in.close();
                      response = tempResponse.toString();
                      System.out.println(response.toString());
                  } else {
                      System.out.println("GET request not worked");
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
      
          }
      
      
      }
      

      【讨论】:

        【解决方案5】:

        是的,您应该使用 URLConnection 来发出请求。

        您可以将 xml 数据作为有效负载发送。

        请参考Android - Using HttpURLConnection to POST XML data

            URL url = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            try {
                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);
                String body = "<xml...</xml>";
                OutputStream output = new BufferedOutputStream(conn.getOutputStream());
                output.write(body.getBytes());
                output.flush();
            } finally {
                conn.disconnect();
            }
        

        【讨论】:

        • 我已经更新了我的帖子,以尝试让它发挥作用,但是什么也没发生。你能看一下吗?
        • 你需要调用 test.execute();以便 AsyncTask 可以执行您的请求。另外不要忘记在清单文件 中添加访问互联网的权限
        • 我在清单中有正确的权限并添加了执行,但它仍然无法正常工作
        【解决方案6】:

        您必须提交请求。这可以通过调用 getResponseCode()、getResponseMessage()) 或 getInputStream() 来完成,以便返回和处理响应。

        您的示例的工作代码:

        import android.os.AsyncTask;
        import android.os.Bundle;
        import android.support.v7.app.AppCompatActivity;
        
        import java.io.BufferedOutputStream;
        import java.io.IOException;
        import java.io.OutputStream;
        import java.net.HttpURLConnection;
        import java.net.ProtocolException;
        import java.net.URL;
        
        public class MainActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                toPost test = new toPost();
                test.execute();
            }
        
            private class toPost extends AsyncTask<URL, Void, String> {
                @Override
                protected String doInBackground(URL... params) {
                    HttpURLConnection conn = null;
                    try {
                        URL url = new URL("http://example.com/service");
                        conn = (HttpURLConnection) url.openConnection();
                        conn.setReadTimeout(10000);
                        conn.setConnectTimeout(15000);
                        conn.setRequestMethod("POST");
                        conn.setDoInput(true);
                        conn.setDoOutput(true);
                        String body = "username=user1&locationname=location1";
                        OutputStream output = new BufferedOutputStream(conn.getOutputStream());
                        output.write(body.getBytes());
                        output.flush();
        
                        //This is needed
                        // Could alternatively use conn.getResponseMessage() or conn.getInputStream()
                        conn.getResponseCode();
        
                    } catch (ProtocolException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        conn.disconnect();
                    }
                    return null;
                }
            }
        }
        

        【讨论】:

          【解决方案7】:

          试试这个。 (msg 是 xml 字符串)

           try
                {
                  URL url = new URL(address);
                  URLConnection uc = url.openConnection();
                  HttpURLConnection conn = (HttpURLConnection) uc;
                  conn.setDoInput(true);
                  conn.setDoOutput(true);
                  conn.setRequestMethod("POST");
                  conn.setRequestProperty("Content-type", "text/xml");        
                  PrintWriter pw = new PrintWriter(conn.getOutputStream());
                  pw.write(msg.getText());
                  pw.close();
                  BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
                  bis.close();
          
                }
                catch (Exception e)
                {
                  e.printStackTrace();
                }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-09-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-17
            • 2012-01-12
            • 1970-01-01
            相关资源
            最近更新 更多