Java 句柄HttpURLConnection重定向(NASA开放API)
我正在编写一个Java应用程序,它与NASA的开放API进行通信。我有一个名为NASAClient的类,它公开了实现此任务所需的接口,但在处理地球图像API时,我面临以下问题Java 句柄HttpURLConnection重定向(NASA开放API),java,json,http,Java,Json,Http,我正在编写一个Java应用程序,它与NASA的开放API进行通信。我有一个名为NASAClient的类,它公开了实现此任务所需的接口,但在处理地球图像API时,我面临以下问题 public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) { String cs; if(cloud
public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) {
String cs;
if(cloud_score) cs = "True";
else cs = "False";
String url = "https://api.nasa.gov/planetary/earth/imagery?lon="
+ lon
+ "&lat="
+ lat
+ "&date="
+ year+"-"+mon+"-"+day
+ "&cloud_score="
+ cs
+ "&api_key=" + api_key;
try {
String json = (read(getConnection(url)));
return gson.fromJson(json, EarthImageryResponseObject.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private String read(HttpURLConnection conn) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
return readFromBufferedReader(br);
}
private String readFromBufferedReader(BufferedReader br) throws IOException {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
return sb.toString();
}
private HttpURLConnection getConnection(String url) throws IOException {
HttpURLConnection connection;
connection = createConnection(url);
this.availability = connection.getHeaderField("X-RateLimit-Remaining");
connection.setConnectTimeout(2000);
this.last_resp = connection.getResponseCode();
return connection;
}
private HttpURLConnection createConnection(String url) throws IOException {
URL UniformResourceLocation = new URL(url);
return (HttpURLConnection) UniformResourceLocation.openConnection();
}
当我使用一些标准参数调用EarthImages时,我会得到以下url:
https://api.nasa.gov/planetary/earth/imagery?lon=100.75&lat=1.5&date=2017-01-01&cloud_score=False&api_key=[MY_KEY]
如果我使用curl或浏览器导航到此url,我会得到预期的Json序列化对象,但在我的应用程序中调用时,我会得到指向heroku应用程序的重定向链接(带有301响应代码):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><title>Redirecting...</title><h1>Redirecting...</h1><p>You should be redirected automatically to target URL: <a href="http://earth-imagery-api.herokuapp.com/earth/imagery/?lon=100.75&lat=1.5&date=2017-01-01&cloud_score=False">http://earth-imagery-api.herokuapp.com/earth/imagery/?lon=100.75&lat=1.5&date=2017-01-01&cloud_score=False</a>. If not click the link.
这是因为我需要一个Json对象,但我得到一个字符串(html重定向页面)。如果您希望代码自动遵循重定向,请设置此标志
connection.setFollowRedirects (true);
我使用HttpURLConnection和SSLSocket解决了这个问题。第一个连接获取重定向链接,该链接不是由另一个httpurlconnection访问的,而是使用SSLSocket访问该链接
public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) {
String cs;
if(cloud_score) cs = "True";
else cs = "False";
String url = "https://api.nasa.gov/planetary/earth/imagery?lon="
+ lon
+ "&lat="
+ lat
+ "&date="
+ year+"-"+mon+"-"+day
+ "&cloud_score="
+ cs
+ "&api_key=" + api_key;
try {
HttpURLConnection conn = getConnection(url);
String new_url = conn.getHeaderField("Location");
SSLSocketFactory factory =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket =
(SSLSocket)factory.createSocket("api.nasa.gov", 443);
socket.startHandshake();
socket.getOutputStream().write(("GET "+new_url+"\n").getBytes());
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
sb.append(inputLine);
in.close();
socket.close();
String json = sb.toString();
System.out.println(json);
return gson.fromJson(json, EarthImageryResponseObject.class);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
这正是我所做的,但它返回一条错误消息,告诉参数是错误的。我认为这是因为一次访问提供的url earth-images-api.herokuapp.com就会丢失关于我的api密钥的信息,这是必须的。我以为它在cookies或其他连接参数中,但不是,即使我从第一个连接获取cookies并将它们添加到第二个连接中,它也不会工作。不过,谢谢你
catch(IOException e){…}
-打印statcktrace,不要默默地吞下异常你是对的,我已经多次更改了代码。我在问题中添加了异常堆栈跟踪。这个问题与重定向无关,问题在于JSON解析返回gson.fromJson(JSON,EarthImageryResponseObject.class)代码>首先尝试打印json,以检查json字符串正是字符串“仍在尝试,结果相同”(实际上,此标志默认为true)
public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) {
String cs;
if(cloud_score) cs = "True";
else cs = "False";
String url = "https://api.nasa.gov/planetary/earth/imagery?lon="
+ lon
+ "&lat="
+ lat
+ "&date="
+ year+"-"+mon+"-"+day
+ "&cloud_score="
+ cs
+ "&api_key=" + api_key;
try {
HttpURLConnection conn = getConnection(url);
String new_url = conn.getHeaderField("Location");
SSLSocketFactory factory =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket =
(SSLSocket)factory.createSocket("api.nasa.gov", 443);
socket.startHandshake();
socket.getOutputStream().write(("GET "+new_url+"\n").getBytes());
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
sb.append(inputLine);
in.close();
socket.close();
String json = sb.toString();
System.out.println(json);
return gson.fromJson(json, EarthImageryResponseObject.class);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}