我正在尝试编写一个Java程序,该程序应该自动从网站下载文本,当且仅当它被更新时。我遇到的问题是只使用一个HTTPURLConnection来执行此操作,因为如果我不会有数十亿的HTTPURLConnections到Web服务器,因为我正在使用while(true)循环。这是我正在进行的工作,getMsg()方法接收一个url并打开一个HTTPURLConnection。目前,每次我必须阅读一行时,我都会开始新的连接,这不是我确定的最有效的方式。如何使用相同的HTTPURLConnection继续读取同一行?
// Starts a new URLConnection to "localhost/currentmsg.dat"
// Receives JSON string from the URLConnection
// Sets up a different variable for each object received from the URL for eg. if delete=1 means that the admin is requesting to delete a message from the screen.
import java.io.*;
import java.net.*;
import org.json.*;
import java.io.*;
import java.util.Scanner;
public class jListenerURL {
// Current arguments retrieved from the URL
private static int msgID = 0;
private static int aptID = 1; // Apartment ID of current device
private static int unitID = 3; // Unit ID of current device
static String message; // Message received from admin
static int delete; // Delete a message?
static int dmsgID; // What message to delete?
public static void jListener() {
URL url;
boolean keepGoing = true;
String msg = "";
try {
url = new URL("http://www.lotussmoke.com/msgtest/currentmsg.dat");
while (keepGoing) {
msg = getMsg(url);
JSONObject jObj = null;
try {
jObj = new JSONObject(msg);
}
catch (JSONException je) {
System.out.println("JSON Exception for message, try restarting terminal.");
}
int current = jObj.getInt("msgID");
int targetaptID = jObj.getInt("aptID");
int targetunitID = jObj.getInt("unitID");
// Keep listening, if the message changes meaning a different msgID then print that message
if (current!=msgID && targetaptID == aptID && targetunitID == unitID) {
msgID = jObj.getInt("msgID");
message = jObj.getString("message");
delete = jObj.getInt("delete");
dmsgID = jObj.getInt("dmsgID");
if (delete==1) {
// Delete a message
System.out.println("Delete msg ID? " + dmsgID);
continue;
}
System.out.println("Message ID: " + msgID);
System.out.println("Apartment ID: " + aptID);
System.out.println("Unit ID: " + unitID);
System.out.println("Message: " + message);
}
}
}
catch (MalformedURLException e) {
System.err.println();
}
}
public static void main(String args[]) throws Exception {
jListener();
}
private static String getMsg(URL url) {
HttpURLConnection con = null;
try {
con = (HttpURLConnection) url.openConnection();
} catch (IOException e1) {
e1.printStackTrace();
}
BufferedReader in = null;
String msg = "";
try {
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String received;
while((received = in.readLine()) != null) {
//System.out.println(received);
msg = received;
}
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
return msg;
}
}
答案 0 :(得分:0)
为什么不简单地在while循环之外声明你的HttpURLConnection对象?然后它不会在循环内的每次调用时打开连接。
答案 1 :(得分:0)
HttpURLConnection
无法重复使用,但可以通过设置标头Connection: keep-alive
在内部重用与同一服务器的开放连接。如果你连接到不同的服务器,显然没有意义。
有效测试是否有更改的一种方法是使用If-Modified-Since
标题或类似内容If-Unmodified-Since
,If-None-Match
或If-Match
(请参阅HTTP Headers) 。在这种情况下,如果有更改,Web服务器会决定发送新文档,或者只发送没有正文的响应代码304 Not Modified
。
关于使用成员(尤其是静态成员)的最后一件事:我重构了这段代码,唯一可以保留为静态的项目是static void main()
。您可以将静态成员视为某种全局变量。观察类似于'连接正在返回相同的消息'可能是不适当的异常处理和静态成员使用的影响。