How can I make a request to get/download http://coolsite.com/coolstuff.json in Java/Android
Android supports all the standard java.net classes. The simplest way to retrieve content via HTTP is to call openStream() on your URL and read it:
URL url = new URL("http://coolsite.com/coolstuff.js");
InputStream in = url.openStream();
InputStreamReader reader = new InputStreamReader(in);
// read the JSON data
There are libraries for reading JSON in Java (see http://json.org/java), but since the format is really simple, you can parse it easily.
From a cached copy of:
How-to: Android as a RESTful Client
This is a how-to focused on creating a RESTful java object at Android. I’ve used HTTPClient, HTTPEntry, HTTPGet, HTTPResponse, JSONArray and JSONObject classes. I think it’ll be useful if we need to use a web-service from client application.
I’ve implemented a simple Java Object called RestClient which connects to a given Rest-JSON service. After connection, this object prints response content. Using this content, a JSONObject created. Then, RestClient prints the JSONObject’s content, parses all values of this object and prints them as well. And as a last job, RestClient pushes a sample value to the JSONObject.
I’ve uploaded RestClient. Hope it’ll be useful.
P.s: To get access to internet at Android, following field must be included to AndroidManifest.xml file of the project.
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
RestClient code:
package praeda.muzikmekan;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class RestClient {
private static String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
/* This is a test function which will connects to a given
* rest service and prints it's response to Android Log with
* labels "Praeda".
*/
public static void connect(String url)
{
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet(url);
// Execute the request
HttpResponse response;
try {
response = httpclient.execute(httpget);
// Examine the response status
Log.i("Praeda",response.getStatusLine().toString());
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
if (entity != null) {
// A Simple JSON Response Read
InputStream instream = entity.getContent();
String result= convertStreamToString(instream);
Log.i("Praeda",result);
// A Simple JSONObject Creation
JSONObject json=new JSONObject(result);
Log.i("Praeda","<jsonobject>\n"+json.toString()+"\n</jsonobject>");
// A Simple JSONObject Parsing
JSONArray nameArray=json.names();
JSONArray valArray=json.toJSONArray(nameArray);
for(int i=0;i<valArray.length();i++)
{
Log.i("Praeda","<jsonname"+i+">\n"+nameArray.getString(i)+"\n</jsonname"+i+">\n"
+"<jsonvalue"+i+">\n"+valArray.getString(i)+"\n</jsonvalue"+i+">");
}
// A Simple JSONObject Value Pushing
json.put("sample key", "sample value");
Log.i("Praeda","<jsonobject>\n"+json.toString()+"\n</jsonobject>");
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Related
I am working on a proof of concept to see if I can parse the response of X URL. I get an array of JSON objects Whenever I hit this URL on the browser, but I get an empty JSON array whenever I try to parse the same URL using the below Java code. I wonder if that is a normal behavior? Is there any explanation for it ? Am I using the right approach to get the data ?
{
"campaigns": [
]
};
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class HTTPGetTest {
public static void main(String[] args) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://XXXX");
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httpGet);
String jSONString= EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println("jSONString : "+ jSONString);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The following code I have (below) works and gets the job done just fine. But what I'd really like to do is make my REST call, internally parse(if needed), and grab/apply my JSONObject values from there without having to first write my JSON return results to a text file. Basically I'd like to get the same result with out having to Write and Read the JSON from a text file in the middle of my process.
It seems like there are several options to do this. But none I've tried so far work or are out of my grasp of understanding. There may be a simple fix to this too with in the current libraries that I'm just not aware of. Any help to show me how I could alter my code to accomplish this would be appreciated.
Code:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.commons.io.output.TeeOutputStream;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class Account {
public static void main(String[] args) {
File f = new File(
"/Users/name/restLog.txt");
if (!f.exists()) {
try {
f.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
try {
FileOutputStream fos = new FileOutputStream(f);
TeeOutputStream myOut = new TeeOutputStream(System.out, fos);
PrintStream ps = new PrintStream(myOut);
System.setOut(ps);
} catch (Exception e) {
e.printStackTrace();
}
try {
// create HTTP Client
HttpClient httpClient = HttpClientBuilder.create().build();
// create new getRequest
HttpGet getRequest = new HttpGet(
"http://www.asite.com");
HttpResponse response = httpClient.execute(getRequest);
// check 200 response was successful
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
// Get-Capture Complete application/JSON body response
BufferedReader br = new BufferedReader(new InputStreamReader(
(response.getEntity().getContent())));
String output;
// Simply iterate through JSON response and show on console.
while ((output = br.readLine()) != null) {
System.out.println(output);
JSONParser parser = new JSONParser();
Object obj = parser
.parse(new FileReader(
"/Users/name/restLog.txt"));
JSONObject jsonObject = (JSONObject) obj;
JSONObject accountObject = (JSONObject) jsonObject
.get("account");
String email = (String) accountObject.get("email");
Long id = (Long) accountObject.get("id");
System.out.println("My id is " + id);
System.out.println("My email is " + email);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
You have to implement your own object modell to be able to parse the respone with the ObjectMapper like:
ObjectMapper mapper = new ObjectMapper();
YourObject object = mapper.readValue(response.getEntity().getContent());
This object has to contain JSON annotated fields like:
#JsonProperty("userName")
private String userName;
Then you can generate getter/setter pair for your fields. If the json property is a json array then you have to create a java list object. If you work in Java EE you even do not need the annotations, the mapping happens without the need to annotate the fields. Also have a look at Jackson.
I am making the following curl request successfully to my API:
curl -v -X GET -H "Content-Type: application/json" -d {'"query":"some text","mode":"0"'} http://host.domain.abc.com:23423/api/start-trial-api/
I would like to know how can i make this request from inside JAVA code. I have tried searching through Google and stack overflow for the solution. All i have found is how to send data through a query string or how to send JSON data through a POST request.
Thanks
Using below code you should be able to invoke any rest API.
Make a class called RestClient.java which will have method for get and post
package test;
import java.io.IOException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import com.javamad.utils.JsonUtils;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
public class RestClient {
public static <T> T post(String url,T data,T t){
try {
Client client = Client.create();
WebResource webResource = client.resource(url);
ClientResponse response = webResource.type("application/json").post(ClientResponse.class, JsonUtils.javaToJson(data));
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}
String output = response.getEntity(String.class);
System.out.println("Response===post="+output);
t=(T)JsonUtils.jsonToJavaObject(output, t.getClass());
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
public static <T> T get(String url,T t)
{
try {
Client client = Client.create();
WebResource webResource = client.resource(url);
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}
String output = response.getEntity(String.class);
System.out.println("Response===get="+output);
t=(T)JsonUtils.jsonToJavaObject(output, t.getClass());
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
}
invoke the get and post method
public class QuestionAnswerService {
static String baseUrl="http://javamad.com/javamad-webservices-1.0";
//final String baseUrl="http://javamad.com/javamad-webservices-1.0";
#Test
public void getQuestions(){
System.out.println("javamad.baseurl="+baseUrl);
GetQuestionResponse gqResponse=new GetQuestionResponse();
gqResponse =RestClient.get(baseUrl+"/v1/questionAnswerService/getQuestions?questionType=2",gqResponse);
List qList=new ArrayList<QuestionDetails>();
qList=(List) gqResponse.getQuestionList();
//System.out.println(gqResponse);
}
public void postQuestions(){
PostQuestionResponse pqResponse=new PostQuestionResponse();
PostQuestionRequest pqRequest=new PostQuestionRequest();
pqRequest.setQuestion("maybe working");
pqRequest.setQuestionType("2");
pqRequest.setUser_id("2");
//Map m= new HashMap();
pqResponse =(PostQuestionResponse) RestClient.post(baseUrl+"/v1/questionAnswerService/postQuestion",pqRequest,pqResponse);
}
}
Make your own Request and response class.
for json to java and java to json use below class
package com.javamad.utils;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
public class JsonUtils {
private static Logger logger = Logger.getLogger(JsonUtils.class.getName());
public static <T> T jsonToJavaObject(String jsonRequest, Class<T> valueType)
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE,false);
T finalJavaRequest = objectMapper.readValue(jsonRequest, valueType);
return finalJavaRequest;
}
public static String javaToJson(Object o) {
String jsonString = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE,true);
jsonString = objectMapper.writeValueAsString(o);
} catch (JsonGenerationException e) {
logger.error(e);
} catch (JsonMappingException e) {
logger.error(e);
} catch (IOException e) {
logger.error(e);
}
return jsonString;
}
}
I wrote the RestClient.java class , to reuse the get and post methods. similarly you can write other methods like put and delete...
Hope it will help you.
Spring's RESTTemplate is also useful for sending all REST requests i.e. GET , PUT , POST , DELETE
By using Spring REST template, You can pass JSON request with POST like below,
You can pass JSON representation serialized into java Object using JSON serializer such as jackson
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(list);
Person person = new Person();
String url = "http://localhost:8080/add";
HttpEntity<Person> entity = new HttpEntity<Person>(person);
// Call to Restful web services with person serialized as object using jackson
ResponseEntity<Person> response = restTemplate.postForEntity( url, entity, Person.class);
Person person = response.getBody();
You could use the Jersey client library, if your project is a Maven one just include in your pom.xml the jersey-client and jersey-json artifacts from the com.sun.jersey group id.
To connect to a web service you need a WebResource object:
WebResource resource =
ClientHelper.createClient().resource(UriBuilder.fromUri("http://host.domain.abc.com:23423/api/").build());
To make a call sending a payload you can model the payload as a POJO, i.e.
class Payload {
private String query;
private int mode;
... get and set methods
}
and then call the call using the resource object:
Payload payload = new Payload();
payload.setQuery("some text"); payload.setMode(0);
ResultType result = service
.path("start-trial-api").
.type(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.get(ResultType.class, payload);
where ResultType is the Java mapped return type of the called service, in case it's a JSON object, otherwise you can remove the accept call and just put String.class as the get parameter and assign the return value to a plain string.
Struggled on the same question and found a nice solution using the gson.
The code:
// this method is based on gson (see below) and is used to parse Strings to json objects
public static JsonParser jsonParser = new JsonParser();
public static void getJsonFromAPI() {
// the protocol is important
String urlString = "http://localhost:8082/v1.0/Datastreams"
StringBuilder result = new StringBuilder();
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line; // reading the lines into the result
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
// parse the String to a jsonElement
JsonElement jsonObject = jsonParser.parse(result.toString());
System.out.println(jsonObject.getAsJsonObject() // object is a mapping
.get("value").getAsJsonArray() // value is an array
.get(3).getAsJsonObject() // the fourth item is a mapping
.get("name").getAsString()); // name is a String
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The packages:
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
My pom.xml:
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
I hope this helps you!
I have a JSONParser class that would enable me to make HTTPRequests. So here is the class
package com.thesis.menubook;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
Log.d("URL",url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line+ "n" );
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
Log.e("JSON Parser", "json string :" +json);
}
// return JSON String
return jObj;
}
}
I access it like this.
params.add(new BasicNameValuePair("category", "MAIN DISH"));
JSONObject json = jsonParser.makeHttpRequest("http://"+ipaddress+"/MenuBook/selectMenu.php", "GET", params);
I would like to keep the format of the parameter as such, MAIN DISH. but when I look into my LogCat it returns a url formed like this.
http://192.168.10.149:80/MenuBook/selectMenu.php?category=MAIN+DISH
which then causes my application to fail and force close since I have no category like MAIN+DISH
I would like my URL to be formed like this.
http://192.168.10.149:80/MenuBook/selectMenu.php?category='MAIN DISH'
which would then return the proper results. I searched around in the net and only found solutions to make white spaces + and %20 which would not return the proper result.
Any solutions you can suggest?
Your question embodies a contradiction in terms. URL-encoding (actually form-encoding) is already defined, and it is already defined to replace spaces with '+', not to quote the value elements concerned. The server-side software needs to understand that and behave accordingly. All the server-side software provided by Java, e.g. HttpServletRequest, already does that. If your code doesn't comply with the RFCs, fix it so it does.
I solved it by hardcoding it with 'MAIN+DISH'
I need to develop an helper class on top of org.apache.httpclient for my android application. Following code works fine for android, but not for JavaSE 1.6 in my PC.
Question is: Can I use org.apache.httpclient both for android and for PC? If I cant: what is your http client library advise?
I want to develop one helper class and use it at all.
Here is the code that works fine in android but some classes cannot be resolved for on Java SE 1.6.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class HTTPClient {
public static void connect(String url)
{
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet(url);
// Execute the request
HttpResponse response;
try {
response = httpclient.execute(httpget);
// Examine the response status
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
if (entity != null) {
// A Simple JSON Response Read
InputStream instream = entity.getContent();
String result= convertStreamToString(instream);
// now you have the string representation of the HTML request
instream.close();
}
} catch (Exception e) {}
}
private static String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
Yes you can, you should avoid naming your client helper class as the same thing as an already defined class. Although Java is case sensitive, it is confusing will trip you up when you least expect it. It may even be guilty for causing this problem. Why not call it HttpClientHelper as that is what it truly is.
Here's an example of HttpClient http://hc.apache.org/httpclient-3.x/tutorial.html