0

这是我的简单程序(try catch 块内的代码),它将负责调用正在运行的 web 服务。基本上,这负责将应用程序的事件记录到 webService:

更新的问题代码

package com;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class NetClientPost {

    HttpURLConnection conn = null;

    NetClientPost() throws Exception {


        URL url = new URL("http://localhost:8080/RestTest/custom/log_service");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    }

    public static void main(String[] args) {

        NetClientPost po;
        try {
            po = new NetClientPost();
            po.execute();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void execute() {

        try {


            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");

            String input = "{\"qty\":100,\"name\":\"eee 4\"}";

            OutputStream os = conn.getOutputStream();
            os.write(input.getBytes());
            os.flush();



            BufferedReader br = new BufferedReader(new InputStreamReader(
                    (conn.getInputStream())));





        } catch (MalformedURLException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}
4

5 回答 5

1

您应该将其移至不同的方法(因为那是更好的代码而不是因为功能)。此方法由您的main. 你需要关闭连接。

我假设您希望在服务器端注册每个呼叫作为新请求。(否则请参阅@Santosh 的答案)。那么重要的是每次都打开一个新连接,因此每次也要关闭它。

public void doSomething() {
   logMyself();
   // do whatever the program does
}

private static void logMyself() {
   // you can put the next line into the constructor.
   URL url = new URL(
                "http://192.168.2.46:8080/RestTest/custom/log_service");
   HttpURLConnection conn;
   try {
       // you can NOT put the next line into the constructor.
       conn = (HttpURLConnection) url.openConnection()
       conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");

        String input = "{\"qty\":100,\"name\":\"micromax 4\"}";

        OutputStream os = conn.getOutputStream();
        os.write(input.getBytes());
        os.flush();

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));
   } catch //...
   } finally {
        // its important to put the disconnect into the finally.
        conn.disconnect();
   }
}
于 2013-06-20T11:31:05.843 回答
1

在 JavaDoc 中:

“每个 HttpURLConnection 实例用于发出单个请求,但到 HTTP 服务器的底层网络连接可能会被其他实例透明地共享。在请求后调用 HttpURLConnection 的 InputStream 或 OutputStream 上的 close() 方法可能会释放相关的网络资源使用此实例,但对任何共享持久连接没有影响。如果持久连接当时处于空闲状态,则调用 disconnect() 方法可能会关闭底层套接字。"

http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html

所以看起来你每次都可以创建新实例。像这样的东西:

   ...
   private void getConnection() {
         conn = (HttpURLConnection) url.openConnection();
   }
   ...

然后当输出到 web 服务时,您需要关闭流但不需要调用 desconnect() 否则您将停止共享底层网络连接(这会降低应用程序的性能)。

于 2013-06-20T12:37:57.190 回答
0

它不会创建太多的 HTTPConnections,因为日志记录每秒都会发生。

不,不会的。HttpURLConnection在幕后进行连接池。很可能会继续重复使用单个连接。您可以防止这种情况的唯一方法是调用disconnect(),因此您应该避免这种情况。但是,您当然应该关闭连接的输入和输出流,而您没有这样做。

于 2013-06-20T11:57:42.203 回答
0

如果调用每秒只发生一次,并且只有一个线程在执行此操作(即没有并发),那么打开连接、调用然后断开连接就可以了。如果您每秒进行数百次调用和/或有高货币/低延迟要求,那么重用连接(保持活动)和池(用于并发支持)可能是合适的,因为连接时 TCP 握手非常耗时。如果是这种情况,请查看Apache Http ComponentsAsync Http Client(如果您更喜欢 NIO),因为它们会为您处理这些复杂性。

于 2013-06-20T11:57:54.257 回答
0

此代码似乎只在您的应用程序中运行一次。如果我遗漏任何东西,请纠正我。这里可能有两个用例

  • 您只运行一次这段代码,即打开连接、发布数据然后断开连接。为此,您拥有的(第一个片段)就足够了。

  • 您正在多次调用 Web 服务。即打开一次连接,并多次使用同一个连接来调用Web 服务。这里代码的第二个片段(或在构造函数中创建连接的代码)是适当的。只有当您确定不会再对该 URL 进行任何调用时,您才调用断开连接。Javadocdisconnect()表示如下

表示在不久的将来不太可能向服务器发出其他请求。调用 disconnect() 不应暗示此 HttpURLConnection 实例可用于其他请求。

于 2013-06-20T11:31:41.743 回答