我有一个休息服务http://xxx.yy.zz.ww:5000/config/server_config/grant,返回:
[
{
"address":"xxx.yy.zz.ww",
"chat_port":"8010",
"comm_hub_address":"192.168.137.38",
"comm_hub_port":50000,
"comm_hub_udp_beacon":"192.168.42.129",
"mqtt_port":"1883",
"rest_port":"8000"
}
]
我已经确认可以通过在浏览器中复制粘贴网址来使用此服务。
我正在使用Callable和Future来返回一个JSON字符串,另一个帮助程序方法将其解析为实际属性。
以下是相关代码段:
/**
* Attempts to load in the JSPN server configuration info from RESTful web service else if there is a failure fall back on default embedded JSON config file.
*
* @return true on success, false on error
*/
private boolean loadServerConfig() {
boolean loaded = false;
InputStream is = null;
URL url = null;
try {
//lets get the path of rest service that has the config file
String address = XYZApp.getContext().getResources().getString(R.string.address);
String restful_port = XYZApp.getContext().getResources().getString(R.string.rest_port);
String client_name = XYZApp.getContext().getResources().getString(R.string.client_name);
String protocol = XYZApp.getContext().getResources().getString(R.string.protocol);
//construct server_config_path
String server_config_path = XYZApp.getContext().getResources().getString(R.string.server_config_path);
url = new URL(protocol + "://" + address + ":" + restful_port + server_config_path + client_name);
//lets execute an FutureTask (async task with a result, that blocks until result is returned).
ExecutorService exService = Executors.newSingleThreadExecutor();
Log.i(TAG, "making call to URL:" + url.toString());
Future<InputStream> future = exService.submit(new GetJsonSettingsTask(url));
is = future.get();
}
catch (MalformedURLException e1) {
e1.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
finally
{
if (is!=null) {
try {
serverConfig = Util.readServerJsonStream(is);
Log.i(TAG, "Read confing file from URL:"+url.toString());
}
catch (IOException e) {
Log.e(TAG, "Error reading server config file: " + e.getMessage());
}
}
else
{
try {
is = Util.scanForJson(getString(R.string.file_path), configFile);
serverConfig = Util.readServerJsonStream(is);
Log.i(TAG, "Read confing file from PATH:"+getString(R.string.file_path));
}
catch (FileNotFoundException e) {
Log.e(TAG, "Unable to locate server config file: " + configFile);
}
catch (IOException e) {
Log.e(TAG, "Error reading server config file: " + e.getMessage());
}
}
//clean up
if (is!=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//check if property was loaded
if (serverConfig!=null) {
loaded = !serverConfig.address.isEmpty();
}
return loaded;
}
}//end loadServerConfig()
class GetJsonSettingsTask implements Callable<InputStream> {
private URL url = null;
public GetJsonSettingsTask(URL url) {
this.url = url;
}
public InputStream call() {
InputStream in = null;
try {
if (this.url != null)
{
HttpURLConnection httpURLConnection = (HttpURLConnection) this.url.openConnection();
httpURLConnection.setReadTimeout(15);
httpURLConnection.setConnectTimeout(10);
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
in = httpURLConnection.getInputStream();
}
}
} catch (MalformedURLException exc) {
exc.printStackTrace();
} catch (java.net.UnknownHostException exc) {
exc.printStackTrace();
} catch (IOException exc) {
exc.printStackTrace();
} catch (NullPointerException exc) {
exc.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException exc) {
exc.printStackTrace();
}
}
}
return in;
}
}//end of inner class GetJsonSettingsTask
//reads the inputstream and extracts JSON & attributes
public static ServerConfig readServerJsonStream(InputStream in) throws IOException {
String address = "";
String commHubAddress = "";
String mqttPort = "";
String restPort = "";
String chatPort = "";
String commHubUdpBeacon = "";
String commHubPort = "";
if (in == null) {
Log.e(TAG, "Attempting to read null InputStream! Are storage permissions granted?");
} else {
try (JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"))) {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
switch (name) {
case "address":
address = reader.nextString();
break;
case "comm_hub_address":
commHubAddress = reader.nextString();
break;
case "mqtt_port":
mqttPort = reader.nextString();
break;
case "rest_port":
restPort = reader.nextString();
break;
case "chat_port":
chatPort = reader.nextString();
break;
case "comm_hub_udp_beacon":
commHubUdpBeacon = reader.nextString();
break;
case "comm_hub_port":
commHubPort = reader.nextString();
break;
default:
Log.w(TAG, "Unexcepted JSON field! Skipping value!");
break;
}
}
reader.endObject();
}
}
return new ServerConfig(address, commHubAddress, mqttPort,
restPort, chatPort, commHubUdpBeacon, commHubPort);
}
我注意到的是,将连接和读取超时设置为15秒(实际上,在浏览器中它的时间不应超过1秒),代码只是将InputStream返回为null,因此会因错误而超时或例外。
当我注释掉连接和读取超时时,我得到IOException:
06-19 19:44:33.470 22675-22675 / XYZ.wams.controller.core W / System.err:java.io.IOException:已关闭 在com.android.okhttp.okio.RealBufferedSource $ 1.read(RealBufferedSource.java:388) 在sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288) 在sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:351) 在sun.nio.cs.StreamDecoder.read(StreamDecoder.java:180) 在java.io.InputStreamReader.read(InputStreamReader.java:184) 在android.util.JsonReader.fillBuffer(JsonReader.java:742) 在android.util.JsonReader.nextNonWhitespace(JsonReader.java:782) 在android.util.JsonReader.nextValue(JsonReader.java:695) 在android.util.JsonReader.peek(JsonReader.java:334) 在android.util.JsonReader.expect(JsonReader.java:308) 在android.util.JsonReader.beginObject(JsonReader.java:293) 在XYZ.wams.controller.core.helpers.Util.readServerJsonStream(Util.java:181)
此IOException发生在readServerJsonStream(InputStream in)方法中
有什么想法吗?
感谢一百万!