How To Access Data With Java
The following Java code example demonstrates how to configure a connection to download data from an Earthdata Login enabled server. Note that you will need a secure way to configure the Earthdata Login username and password.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.Base64;
public class test
{
/*
* Prefix used to identify redirects to URS for the purpose of
* adding authentication headers. For test, this should be:
* https://uat.urs.earthdata.nasa.gov for test
*/
static String URS = "https://urs.earthdata.nasa.gov";
/*
* Simple test.
*/
public static void main( String[] args )
{
String resource = "<url of resource>";
String username = "<URS user ID>";
String password = "<URS user password>";
System.out.println("Accessing resource " + resource);
try
{
/*
* Set up a cookie handler to maintain session cookies. A custom
* CookiePolicy could be used to limit cookies to just the resource
* server and URS.
*/
CookieHandler.setDefault(
new CookieManager(null, CookiePolicy.ACCEPT_ALL));
/* Retreve a stream for the resource */
InputStream in = getResource(resource, username, password);
/* Dump the resource out (not a good idea for binary data) */
BufferedReader bin = new BufferedReader(
new InputStreamReader(in));
String line;
while( (line = bin.readLine()) != null)
{
System.out.println(line);
}
bin.close();
}
catch( Exception t)
{
System.out.println("ERROR: Failed to retrieve resource");
System.out.println(t.getMessage());
t.printStackTrace();
}
}
/*
* Returns an input stream for a designated resource on a URS
* authenticated remote server.
*
*/
public static InputStream getResource(
String resource, String username, String password) throws Exception
{
int redirects = 0;
/* Place an upper limit on the number of redirects we will follow */
while( redirects < 10 )
{
++redirects;
/*
* Configure a connection to the resource server and submit the
* request for our resource.
*/
URL url = new URL(resource);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setInstanceFollowRedirects(false);
connection.setUseCaches(false);
connection.setDoInput(true);
/*
* If this is the URS server, add in the authentication header.
*/
if( resource.startsWith(URS) )
{
connection.setDoOutput(true);
connection.setRequestProperty(
"Authorization",
"Basic " + Base64.getEncoder().encodeToString(
(username + ":" + password).getBytes()));
}
/*
* Execute the request and get the response status code.
* A return status of 200 means is good - it means that we
* have got our resource. We can return the input stream
* so it can be read (may want to return additional header
* information, such as the mime type or size ).
*/
int status = connection.getResponseCode();
if( status == 200 )
{
return connection.getInputStream();
}
/*
* Any value other than 302 (a redirect) will need some custom
* handling. A 401 from URS means that the credentials
* are invalid, while a 403 means that the user has not authorized
* the application.
*/
if( status != 302 )
{
throw new Exception(
"Invalid response from server - status " + status);
}
/*
* Get the redirection location and continue. This should really
* have a null check, just in case.
*/
resource = connection.getHeaderField("Location");
}
/*
* If we get here, we exceeded our redirect limit. This is most likely
* a configuration problem somewhere in the remote server.
*/
throw new Exception("Redirection limit exceeded");
}
}