我成功地使用这段代码通过GET方法发送带有一些参数的HTTP请求

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();
}

现在我可能需要通过POST方法发送参数(即param1, param2, param3),因为它们非常长。 我想添加一个额外的参数,该方法(即字符串httpMethod)。

我怎样才能尽可能少地更改上面的代码,以便能够通过GET或POST发送参数?

我希望情况会有所改变

connection.setRequestMethod("GET");

to

connection.setRequestMethod("POST");

可以完成这个任务,但是参数仍然通过GET方法发送。

HttpURLConnection有任何方法可以帮助吗? 有什么有用的Java构造吗?

任何帮助都将不胜感激。


当前回答

试试这个模式:

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;
}

其他回答

我看到一些其他的答案给出了另一种选择,我个人认为直觉上你在做正确的事情;)不好意思,在devoxx上,有几个演讲者一直在抱怨这种事情。

这就是为什么我个人使用Apache的HTTPClient/HttpCore库来做这类工作,我发现它们的API比Java的原生HTTP支持更容易使用。当然是YMMV了!

这个答案涵盖了使用自定义Java POJO的POST调用的特定情况。

使用Gson的maven依赖项将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;

现在,我们可以继续使用Apache提供的HttpPost

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调用接收到的响应代码

在GET请求中,参数作为URL的一部分发送。

在POST请求中,参数作为请求体发送,位于请求头之后。

要使用HttpURLConnection进行POST,需要在打开连接后将参数写入连接。

这段代码应该让你开始:

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 );
}

我强烈推荐构建在apache http api上的http-request。

对于你的案例,你可以看到例子:

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);
}

对于一般发送post请求与HTTP -request:阅读文档,看到我的答案HTTP post请求与JSON字符串在JAVA,发送HTTP post请求在JAVA, HTTP post使用JSON在JAVA

似乎你还必须调用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(); 

令人惊讶的是,你甚至可以在urlString中使用“GET”样式参数。尽管这可能会让事情变得复杂。

显然,你也可以使用NameValuePair。