【问题标题】:How to use HttpURLConnection PUT with query parameters?如何使用带有查询参数的 HttpURLConnection PUT?
【发布时间】:2018-04-26 05:54:03
【问题描述】:

如何使用带有查询参数的HttpURLConnection 发出 PUT 请求?

我正在尝试使用 HttpURLConnection 使用第三方 REST API,但是当我尝试在 URL 中传递参数时,它不起作用并抛出如下所示的错误:

在映射注册表中找不到 REST API 网址

这是目前对我不起作用的代码块:

    URL url;
    StringBuffer response = new StringBuffer();
    try
    {
        url = new URL(" http://thirdparty.com/party/api/v2/ksp/12/ks");
        HttpURLConnection httpURL = (HttpURLConnection) url.openConnection();
        httpURL.setDoOutput(true);
        httpURL.setRequestMethod("PUT");
        StringBuilder sbUrl = new StringBuilder("parameter1_id=");
        sbUrl.append(getParameter1Value())
             .append("&parameter2_id=")
             .append(getParameter2Value());
        final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpURL.getOutputStream()));
        writer.write(sbUrl.toString());
        writer.flush();
        writer.close();

        // throw the exception here in case invocation of web service
        if (httpURL.getResponseCode() != 200)
        {
            // throw exception
        }
        else
        {
            //SUCCESS
        }
    }
    catch (IOException e)
    {
    }

当我在正文中将这些参数作为form-data 参数提供时,REST API 似乎提供了响应。 我的问题是如何使用 HttpURLConnection 进行这项工作?

到目前为止我尝试了什么? 我已经尝试将上面的内容修改为类似下面的内容,但它不起作用。

    try
    {
        url = new URL(" http://thirdparty.com/party/api/v2/ksp/12/ks");
        HttpURLConnection httpURL = (HttpURLConnection) url.openConnection();
        httpURL.setDoOutput(true);
        httpURL.setRequestMethod("PUT");
        httpURL.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + "----WebKitFormBoundarydklhfklsdfhlksh");
        dataOutputStream = new DataOutputStream(urlConnection.getOutputStream());

        dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"parameter1_id\"");
        dataOutputStream.writeBytes("\r\n" + "parameter1Value" +"\r\n");
        dataOutputStream.writeBytes("--" + "----WebKitFormBoundarydklhfklsdfhlksh");
        dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"parameter2_id\"");
        dataOutputStream.writeBytes("\r\n" + "parameter2Value" + "\r\n");
        dataOutputStream.writeBytes("--" + "----WebKitFormBoundarydklhfklsdfhlksh" + "--");
        dataOutputStream.flush();
        dataOutputStream.close();
        urlConnection.connect();
        // throw the exception here in case invocation of web service
        if (httpURL.getResponseCode() != 200)
        {
            // throw exception
        }
        else
        {
            //SUCCESS
        }
    }
    catch (IOException e)
    {
    }

EDIT:它会抛出一个错误,响应代码为 500

编辑:澄清一下,我不是在尝试上传文件,而是尝试在 BODY 中发送参数(例如查询参数,而不是作为 URL 参数发送)。

非常感谢您对此的任何指示或建议。

【问题讨论】:

  • 从不捕获异常而不处理它,至少记录它们
  • 是的,我已经在我的代码中实现了,但是为了给出实际代码块的图片,添加了这个空的 catch
  • 获取“在映射注册表中找不到 REST API Url”的任何其他人的信息:当您对端点使用错误动词时(例如一个只需要 GET 的端点的 POST)

标签: java rest httpurlconnection


【解决方案1】:

您谈到“查询参数”和“URL 中的参数”,但您展示的这两种方法都没有做任何此类事情。您的两种方法(尝试)都在请求 body 中发送参数,也就是“实体”,而不是在 URL 中。尽管正文内容可能涉及应用程序级别的查询,但它们不是 HTTP 级别的查询字符串,也就是查询参数。您还问“我如何使用 HttpURLConnection 进行这项工作”,就好像当您的两次尝试都已经使用它时,这是一个变化或差异。

您的第一次尝试看起来几乎是正确的。它应该工作,如果 你.setRequestProperty("Content-type", "application/x-www-form-urlencoded")(这不是自动的)并且你的值要么是 URL 编码的,要么不需要它(没有保留字符)(取决于服务器,没有 & 或等号可能就足够了)

您的第二次尝试也非常接近。您还需要在第一部分之前写一个边界,对于Content-disposition: form-data; name="blah" 之后的每个部分,您需要一个 CRLF 来结束该标题行,第二个 CRLF 来结束标题块。 (MIME 多部分格式通常允许多个标题行,尽管在这种情况下只需要一个。)并且结束边界后面应该跟一个 CRLF(在额外的 -- 之后)。

当然,前提是您的 URL 正确。没有正确的 URL 将无法正常工作。

【讨论】:

  • 如果我理解您的 cmets 正确,那么我在问题中提出的两种方法都是在请求正文中发送参数而不是在 URL 中? (至少我认为的第一个是在 URL 本身中发送这些参数)
  • 尽管如此,这两种方法目前都不起作用!我会努力落实您的建议!
【解决方案2】:

使用 HttpUrlConnection PUT 方法调用 WebService 的最佳方法

  ApiListener apilistener=null;

public void updateWorker()

    {

progressDialog = ProgressDialog.show(myContext, "Message",      
progressDialog.setCancelable(false);
progressDialog.setCanceledOnTouchOutside(false);

Thread runThread = new Thread(new Runnable() {

    @Override
    public void run() {

        HttpAppRequest http = new HttpAppRequest();


        try {

            JSONObject paramObject = new JSONObject();
            JSONObject dataObject = new JSONObject();

            dataObject.put("id", csId);

         }                       


        paramObject.put("data", dataObject);

            Log.e(AppConstants.TAG, "Param = " + paramObject.toString());

            AppResponse response = http.putJSONData(BASE_URL + "/updateapi", paramObject.toString(), true);

            if (response.getStatusCode() == 200) {

                String csUpdateResult = response.getContentData();
                Log.e(AppConstants.TAG, csUpdateResult);

                JSONObject updateObject = new JSONObject(csUpdateResult);


      Message completeMessage = handler.obtainMessage(1,    updateObject);
                completeMessage.sendToTarget();
            } else {
                handler.sendEmptyMessage(-1);
            }


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

            String csMessage = myContext.getResources().getString(R.string.id_network_response_failure);
            Message completeMessage = handler.obtainMessage(0, csMessage);
            completeMessage.sendToTarget();
        }
    }
});

runThread.start();

}


   /*******************************************************************************************************/ Handler Api Response Here
               Handler handler= new Handler() {
@Override
public void handleMessage(Message inputMessage) {

    progressDialog.dismiss();

    if (inputMessage.what == 1) {
        try {

            JSONObject msgObject = (JSONObject) inputMessage.obj;

            if (msgObject.has("result")) {
                JSONObject resultObject = msgObject.getJSONObject("result");

                if (resultObject.has("status")) {
                    String csStatus = resultObject.getString("status");

                    if (csStatus.equalsIgnoreCase("success")) {

                        apilistener.onUpdate(resultObject.getString("msg"));

                    }
                } else {

                    if(resultObject.has("status"))
                    {
                                apilistener.onFailed(resultObject.getString("reason"));
                    }
                }


            }
        } catch (JSONException e) {
            CommonMethods.showMessageBox("", e.getMessage(), myContext);
        }

    } else if (inputMessage.what == 0) {
        String csMessage = (String) inputMessage.obj;
        CommonMethods.showMessageBox("", csMessage, myContext);
    }

}
       };

       //CallBack Listener to parent Activity/Fragment
      //User listener like this
       public interface ApiListener extends EventListener
      {
           void onSuccess(String msg);
           void onFaiulure(String msg);
        }

       public void setListener(ApiListener listener)
     {

           apilistener=listener;
                }


     }

【讨论】:

  • 你能更详细地解释一下这段代码吗?我对ApiListenerHttpAppRequest了解不多!
  • HttpAppRequest 只是处理请求发送和接收和解析响应,你可以使用标准代码来处理这些,监听器是活动的回调,因为这个请求是在单独的类和线程中进行的。它只是向活动/片段发送回调,例如当调用 apilistener.onSuccess(msg) 时,活动可以从此类接收消息
  • 似乎不太适合场景,需要大量返工。您能建议对我现在发布的代码 sn-p 进行哪些更改吗?
  • 我认为你完全弄错了,我不是要上传文件,而是要发送两个参数。请交叉检查问题一次!
  • 你还没有回答。您使用了另一个 API,并且无偿地引入了 JSON。不以任何方式回答问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 2011-12-23
  • 2022-08-03
  • 2019-02-01
相关资源
最近更新 更多