API需要查询参数和正文

时间:2017-07-13 07:15:28

标签: android httpurlconnection retrofit2

See Rest Client Screenshot如何同时使用查询参数和Body。查询参数在GET中使用,我们附加在URL中。在帖子中我们提交Body。但是这个API需要两者。

 URL  = http://www.MYWEBSITENAME.com/api/serveVideos/serveVideosToClient.php

 QUERY  PARAMS = show_by=rating&start=1&end=10
 HEADER  = X-WWW-FORM-URL-ENCODED

 Request Body :
 "android_ref_id" : "14"
 "token": "1223232"

我使用Retrofit并且我得到的回复无效但是当我使用Rest Client时,API工作正常。我也试过Async Task。 这是我到目前为止所尝试的。但没有运气。

改造代码1:

@FormUrlEncoded
@POST("serveVideos/serveVideosToClient.php?show_by=rating&start=1&end=10")
Call<JsonObject> serveVideosToDevice(@Field("android_ref_id") String android_uuid, @Field("token") String token);

改造代码2:

@FormUrlEncoded
@POST("serveVideos/serveVideosToClient.php")
@Headers({"Content-Type:application/x-www-form-urlencoded"})
Call<JsonObject> serveVideosToDevice(@QueryMap Map<String, String> options,
                                     @Field("android_ref_id") String 
android_uuid, @Field("token") String token);

改造代码3:

  @FormUrlEncoded
  @POST("serveVideos/serveVideosToClient.php")
  Call<JsonObject> serveVideosToDevice(@Query("show_by") String showBy, 
  @Query("start") String start, @Query("end") String end, 
  @Field("android_ref_id") String android_uuid, @Field("token") String 
  token);

异步任务代码

   @Override
   protected String doInBackground(String... params) {

    URL url = null;
    String response = null;
    HttpURLConnection urlConnection = null;
    String urlStr = params[0];
    String android_ref_id = params[2].trim();
    String token = params[1].trim();

    String urlParameters = "show_by=rating&start=1&end=10";
    byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);

    try {
        url = new URL(params[0]);
        urlConnection = (HttpURLConnection) url.openConnection();

        urlConnection.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        urlConnection.setRequestMethod("POST");

        DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
        PrintWriter out = new PrintWriter(urlConnection.getOutputStream());

        try {
            // wr.write(postData);

            Map<String, String> stringMap = new HashMap<>();
            stringMap.put("android_ref_id", android_ref_id);
            stringMap.put("token", token);

            wr.writeBytes(stringMap.toString());
           // out.print(postData);

            Log.e(Constants.mLogs, "Json : " + stringMap.toString());
            wr.flush();
            wr.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        InputStream in = new BufferedInputStream(urlConnection.getInputStream());
        response = readStream(in);
        //readStream(in);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        urlConnection.disconnect();
    }
    return response;
}

这两个代码都不起作用。在这种情况下该怎么做。

3 个答案:

答案 0 :(得分:0)

对于Async Task代码。将查询参数附加到请求URL并将其余部分作为一部分发送到正文可能会更容易。见下文。

URL url = null;   
HttpURLConnection urlConnection = null;
String urlStr = params[0];
String android_ref_id = params[2].trim();
String token = params[1].trim();URL url;
String responseStr="";
try {
        url = new URL(urlStr+"?show_by=rating&start=1&end=10");
    } catch (MalformedURLException e) {
        throw new IllegalArgumentException("invalid url: " + urlStr);
    }
    params.put("android_ref_id", android_ref_id);
    params.put("token", token);
    StringBuilder bodyBuilder = new StringBuilder();
    Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
    // constructs the POST body using the parameters
    while (iterator.hasNext()) {
        Entry<String, String> param = iterator.next();
        bodyBuilder.append(param.getKey()).append('=')
                   .append(param.getValue());
        if (iterator.hasNext()) {
            bodyBuilder.append('&');
        }
    }
    String body = bodyBuilder.toString();
    HttpURLConnection conn = null;
    try {
        conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setChunkedStreamingMode(0);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
        // post the request
        OutputStream out = conn.getOutputStream();
        out.write(body.getBytes());
        out.close();
        // handle the response
        int status = conn.getResponseCode();
        if (status != 200) {
            throw new IOException("Post failed with error code " + status);
        }
        // Get Response
        InputStream is = conn.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuffer response = new StringBuffer();
        while ((line = rd.readLine()) != null) {
            response.append(line);
        }
        rd.close();
        responseStr = response.toString();
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
    return responseStr;

答案 1 :(得分:0)

试试这个:

<强>声明

@FormUrlEncoded
@POST("serveVideos/serveVideosToClient.php")
Call<JsonObject> serveVideosToDevice(@Query("show_by") String showBy, @Query("start") String start, @Query("end") String end, @Field("android_ref_id") String android_uuid, @Field("token") String token);

拨打

serveVideosToDevice("rating", "1", "10" ,"14", "1223232").enqueue(new Callback<JsonObject>() {
            @Override
            public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                Log.e(this.getClass().getName(), response.toString());
            }

            @Override
            public void onFailure(Call<JsonObject> call, Throwable t) {
                t.printStackTrace();
            }
        });

答案 2 :(得分:0)

@FormUrlEncoded //type application/x-www-form-urlencoded
@POST("serveVideos/serveVideosToClient.php") // POST request to url
Call<JsonObject> serveVideosToDevice(@QueryMap Map<String, String> options,// adding query like url?<key>=<value>&<key>=<value>... 
      @Body() RequestBody requestBody);// Json params

选项

{
  options.put("show_by", "rating")
  options.put("start", "1")
  options.put("end", "10")
}


class RequestBody{
   @SerializedName("android_ref_id")
   public int refId;
   @SerializedName("token")
   public String token;
}