Java 在连续调用的代码中使用HttpURLConnetion
这是我的简单程序(try-catch块中的代码),负责调用正在运行的Web服务。 基本上,它负责将应用程序的事件记录到Web服务: 更新的问题代码Java 在连续调用的代码中使用HttpURLConnetion,java,Java,这是我的简单程序(try-catch块中的代码),负责调用正在运行的Web服务。 基本上,它负责将应用程序的事件记录到Web服务: 更新的问题代码 package com; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; impor
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();
}
}
}
您应该将其移动到另一个方法(因为这是更好的代码,而不是因为功能)。此方法由
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();
}
}
这段代码在应用程序中似乎只运行一次。如果我遗漏了什么,请纠正我。这里可能有两个用例
- 您只运行这段代码一次,即打开连接,发布数据,然后断开连接。为此,您所拥有的(第一个代码片段)就足够了
- 您多次调用web服务。i、 e.打开一次连接,并多次使用同一连接来调用web服务。这里是代码的第二个片段(或在构造函数中创建连接的代码)。只有在确定不再有任何对该URL的调用时,才能调用disconnect。Javadoc表示如下
它不会创建太多的HTTPConnections,因为日志记录每秒都会发生
不,不会的
HttpURLConnection
在后台执行连接池。很可能单个连接将继续重复使用。防止这种情况发生的唯一方法是调用disconnect()
,因此应该避免调用。但是,您当然应该关闭连接的输入和输出流,而您没有这样做。如果调用每秒只发生一次,并且只有一个线程在这样做(即没有并发),那么打开连接、调用然后断开连接就可以了。如果您每秒进行数百次呼叫和/或具有高货币/低延迟要求,那么重用连接(保持活动)和池(用于并发支持)可能是合适的,因为连接时TCP握手非常耗时。如果是这样的话,那么研究一下or(如果您更喜欢NIO),因为他们会为您处理这些复杂性。在JavaDoc中:
“每个HttpURLConnection实例都用于发出单个请求,但是到HTTP服务器的底层网络连接可能会被其他实例透明地共享。调用close()请求后HttpURLConnection的InputStream或OutputStream上的方法可能会释放与此实例关联的网络资源,但对任何共享的持久性连接没有影响。如果持久性连接当时处于空闲状态,则调用disconnect()方法可能会关闭基础套接字。”
()
看起来每次都可以创建新实例。诸如此类:
...
private void getConnection() {
conn = (HttpURLConnection) url.openConnection();
}
...
然后,当输出到webservice时,您需要关闭streams,但不需要调用Deconnect(),否则您将停止共享底层网络连接(这将降低应用程序的性能)。它不会在每秒进行日志记录时创建太多HTTPConnections。感谢Angelo Neuschitzer,log4j自定义appender每秒都会调用这个方法logimf,所以我关心的是我是否需要多次调用URL URL=new URL和HttpURLConnection conn??我已经修改了我的代码,以便它多次使用相同的连接来调用web服务,但它不起作用,我在conn.setDoOutput获得NullpointerException(true)@PreethiJain我犯了一个错误(HttpURLConnection不能自动关闭),请查看我的编辑。此外,您应该每次创建一个新连接,并在最后断开连接。将
disconnect()
放入finally
块并不重要。它是可选的。请参阅Javadoc。在这种情况下,最好不要调用它,因为它可以防止发生connecton池。