I am doing basic http auth with the HttpURLConnection object in Java.
URL urlUse = new URL(url);
HttpURLConnection conn = null;
conn = (HttpURLConnection) urlUse.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-length", "0");
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setConnectTimeout(timeout);
conn.setReadTimeout(timeout);
conn.connect();
if(conn.getResponseCode()==201 || conn.getResponseCode()==200)
{
success = true;
}
I am expecting a JSON object, or string data in the format of a valid JSON object, or HTML with simple plain text that is valid JSON. How do I access that from the HttpURLConnection after it returns a response?
You can get raw data using below method. BTW, this pattern is for Java 6. If you are using Java 7 or newer, please consider try-with-resources pattern.
public String getJSON(String url, int timeout) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(timeout);
c.setReadTimeout(timeout);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
return sb.toString();
}
} catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
And then you can use returned string with Google Gson to map JSON to object of specified class, like this:
String data = getJSON("http://localhost/authmanager.php");
AuthMsg msg = new Gson().fromJson(data, AuthMsg.class);
System.out.println(msg);
There is a sample of AuthMsg class:
public class AuthMsg {
private int code;
private String message;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
JSON returned by http://localhost/authmanager.php must look like this:
{"code":1,"message":"Logged in"}
Regards
Define the following function (not mine, not sure where I found it long ago):
private static String convertStreamToString(InputStream is) {
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();
}
Then:
String jsonReply;
if(conn.getResponseCode()==201 || conn.getResponseCode()==200)
{
success = true;
InputStream response = conn.getInputStream();
jsonReply = convertStreamToString(response);
// Do JSON handling here....
}
In addition, if you wish to parse your object in case of http error (400-5** codes),
You can use the following code: (just replace 'getInputStream' with 'getErrorStream':
BufferedReader rd = new BufferedReader(
new InputStreamReader(conn.getErrorStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
return sb.toString();
The JSON string will just be the body of the response you get back from the URL you have called. So add this code
...
BufferedReader in = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
That will allow you to see the JSON being returned to the console. The only missing piece you then have is using a JSON library to read that data and provide you with a Java representation.
Here's an example using JSON-LIB
This function will be used get the data from url in form of HttpResponse object.
public HttpResponse getRespose(String url, String your_auth_code){
HttpClient client = new DefaultHttpClient();
HttpPost postForGetMethod = new HttpPost(url);
postForGetMethod.addHeader("Content-type", "Application/JSON");
postForGetMethod.addHeader("Authorization", your_auth_code);
return client.execute(postForGetMethod);
}
Above function is called here and we receive a String form of the json using the Apache library Class.And in following statements we try to make simple pojo out of the json we received.
String jsonString =
EntityUtils.toString(getResponse("http://echo.jsontest.com/title/ipsum/content/ blah","Your_auth_if_you_need_one").getEntity(), "UTF-8");
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(JsonJavaModel .class, new CustomJsonDeserialiser());
final Gson gson = gsonBuilder.create();
JsonElement json = new JsonParser().parse(jsonString);
JsonJavaModel pojoModel = gson.fromJson(
jsonElementForJavaObject, JsonJavaModel.class);
This is a simple java model class for incomming json.
public class JsonJavaModel{
String content;
String title;
}
This is a custom deserialiser:
public class CustomJsonDeserialiserimplements JsonDeserializer<JsonJavaModel> {
#Override
public JsonJavaModel deserialize(JsonElement json, Type type,
JsonDeserializationContext arg2) throws JsonParseException {
final JsonJavaModel jsonJavaModel= new JsonJavaModel();
JsonObject object = json.getAsJsonObject();
try {
jsonJavaModel.content = object.get("Content").getAsString()
jsonJavaModel.title = object.get("Title").getAsString()
} catch (Exception e) {
e.printStackTrace();
}
return jsonJavaModel;
}
Include Gson library and org.apache.http.util.EntityUtils;
Related
I am trying to collect a single piece of data from an API, that being the population of a certain country. Everything works properly except for cutting the population value out of the JSON.
{"Info":[{"area":301336,"nativeName":"Italia","capital":"Rome","demonym":"Italian","flag":"https://restcountries.eu/data/ita.svg","alpha2Code":"IT","languages":[{"nativeName":"Italiano","iso639_2":"ita","name":"Italian","iso639_1":"it"}],"borders":["AUT","FRA","SMR","SVN","CHE","VAT"],"subregion":"Southern Europe","callingCodes":["39"],"regionalBlocs":[{"otherNames":[],"acronym":"EU","name":"European Union","otherAcronyms":[]}],"gini":36,"population":60665551,"numericCode":"380","alpha3Code":"ITA","topLevelDomain":[".it"],"timezones":["UTC+01:00"],"cioc":"ITA","translations":{"br":"Itália","de":"Italien","pt":"Itália","ja":"イタリア","hr":"Italija","it":"Italia","fa":"ایتالیا","fr":"Italie","es":"Italia","nl":"Italië"},"name":"Italy","altSpellings":["IT","Italian Republic","Repubblica italiana"],"region":"Europe","latlng":[42.83333333,12.83333333],"currencies":[{"symbol":"\u20ac","code":"EUR","name":"Euro"}]}]}
Within the JSON, It is called "Population".
This is my user input code
public static String UserInputsDetails() {
System.out.println("Please input the country name");
Scanner in = new Scanner(System.in);
String Input = in.nextLine();
return Input;
}
This is my JSON Getter Code
public static JSONArray MakeConnection(String countryname) {
JSONArray JSON = null;
try {
String url = "https://restcountries.eu/rest/v2/name/" + countryname;
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JSON = new JSONArray(response.toString());
} catch (Exception e) {
System.out.println(e);
}
return JSON;
}
This is my Result code, to get just the population
public static void PrintResult(JSONArray JSON){
String population = null;
try {
JSONObject jobj = new JSONObject();
jobj.put("Info", JSON);
population = jobj.getString("population");
System.out.println(jobj);
System.out.println(population);
} catch (Exception e) {
System.out.println(e);
}
}
And finally, this is my main
public static void main(String []args) {
String Input = UserInput.UserInputsDetails();
JSONArray JSON = Connection.MakeConnection(Input);
Result.PrintResult(JSON);
}
I get the error
org.json.JSONException: JSONObject["population"] not found.
What am I doing wrong?
Delete this part:
JSONObject jobj = new JSONObject();
jobj.put("Info", JSON);
population = jobj.getString("population");
System.out.println(jobj);
System.out.println(population);
JSON is already an array, why are you converting it into a JSONObject?
Change to something like this:
Long population = JSON.getJSONObject(0).getLong("population");
I need to post request to an API inside catch to store some logs.
But when I put it the request inside catch, it returned:
java.io.IOException: Server returned HTTP response code: 500 for URL
Code:
try {
...
} catch (Exception e) {
postRequest(...);
}
Code Post Request to API;
public static Object postRequest(...) throws IOException, ParseException {
URL url = new URL(API + "/" + pathName);
HttpURLConnection connection = getHttpURLConnection(url);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = body.getBytes("utf-8");
os.write(input, 0, input.length);
}
try {
StringBuilder response = new StringBuilder();
InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream(), "utf-8");
BufferedReader br = new BufferedReader(inputStreamReader);
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
JSONParser parser = new JSONParser();
JSONObject obj = (JSONObject) parser.parse(response.toString());
return obj;
} catch (IOException err) {
return null;
}
}
In debugging i can see that it puts everything what i need into the sb StringBuilders, but after the second sb the data just disapears and what was prevously written into the safety_string gets deleted aswell, don't know why.
Here is the whole code, changed it a little since i posted.
Still the same, it's not an out of scope, because the result of getting_kat i do receive, only the result of getting_ter is missing.
#Override
public String doInBackground(String... voids) {
String result="";
result=getting_kat();
result+=getting_ter();
//Making sure it gets put into the safety string
safety_string=result;
return result;
}
public String getting_kat(){
String result="";
String resultkat = null;
String connstr = "My connection string";
try {
URL url = new URL(connstr);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
InputStream ips = http.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(ips, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = "";
//Line by Line reading the data from php
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
//String it together into one line
resultkat = sb.toString();
//Adding a separator for later split
result=resultkat+"#KATEGORIA/TERMEK#";
br.close();
ips.close();
http.disconnect();
} catch (MalformedURLException e) {
result = e.getMessage();
} catch (IOException e) {
result = e.getMessage();
}
return result;
}
public String getting_ter(){
String result="";
String resultter=null;
String connstr2 = "My connection string 2";
try {
URL url = new URL(connstr2);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
InputStream ips = http.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(ips, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = "";
//Line by Line reading the data from php
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
//String it together into one line
resultter = sb.toString();
result=resultter;
br.close();
ips.close();
http.disconnect();
} catch (MalformedURLException e) {
result = e.getMessage();
} catch (IOException e) {
result = e.getMessage();
}
return result;
}
I can't see bug in the code. I cleaned it up a bit for you but it should work both before and after my changes. You don't describe what is actually going wrong with it. In debugging you may just be getting timeout on your connection.
public String doInBackground(String... voids) {
String result = getting_kat() + "#KATEGORIA/TERMEK#" + getting_ter();
//Making sure it gets put into the safety string
safety_string = result;
return result;
}
public String getting_kat() {
String result = "";
String connstr = "My connection string";
try {
HttpURLConnection http = connect(connstr);
result = readFromPhp(http);
http.disconnect();
} catch (MalformedURLException e) {
result = e.getMessage();
} catch (IOException e) {
result = e.getMessage();
}
return result;
}
public String getting_ter() {
String result = "";
String connstr = "My connection string 2";
try {
HttpURLConnection http = connect(connstr);
result = readFromPhp(http);
http.disconnect();
} catch (MalformedURLException e) {
result = e.getMessage();
} catch (IOException e) {
result = e.getMessage();
}
return result;
}
private HttpURLConnection connect(String connstr) throws IOException {
URL url = new URL(connstr);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
return http;
}
private String readFromPhp(HttpURLConnection http) throws IOException {
// try-with-resources - so you don't have to call close()
try (
InputStream ips = http.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(ips, "UTF-8"), 8)
) {
StringBuilder sb = new StringBuilder();
String line;
//Line by Line reading the data from php
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
//String it together into one line
return sb.toString();
}
}
I get Data from Json in android,date get and save in String Variable.but when use DecodeUrl its error:
Error: java.lang.IllegalArgumentException: Invalid % sequence at 40:
my code:
#SuppressLint("NewApi")
public String JsonReguest(String url) {
String json = "";
String result = "";
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet(url);
httpget.setHeader("Accept", "application/json");
httpget.setHeader("Content-Type", "application/json");
HttpResponse response;
try {
response = httpclient.execute(httpget);
response.setHeader("Content-Type","UTF-8");
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
InputStream stream = new ByteArrayInputStream(result.getBytes("UTF-8"));
result = convertStreamToString(stream);
// String encode_url=URLEncoder.encode(result,"UTF-8");
// String decode_url=URLDecoder.decode(encode_url,"UTF-8");
//result=decode_url;
//String decodedUrl = URLDecoder.decode(result, "UTF-8");
result=URLDecoder.decode(result);
}
} catch (Exception e) {
Log.e("Error", e.toString());
}
return result;
}
public static String convertStreamToString(InputStream is) {
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();
}
simple text of json :
{"CategoryID":11,"ParentID":0,"Title":"%u062E%u0648%u062F%u0631%u0648","PicAddress":""},{"CategoryID":16,"ParentID":0,"Title":"%u0627%u0645%u0644%u0627%u0643%20","PicAddress":""}
this line crashed : result=URLDecoder.decode(result);
how to Resolve Problems.
first decode specifing your encoding
String result = URLDecoder.decode(url, "UTF-8");
and then go to http://json.org/, scroll down and choose one of the supported json parsing Java libraries
As Selvin commented %uxxxx is not a standard Url encoded string , so it's obvious to get an error
you have 2 options:
Contact the service provider to fix her url encoded strings and use URLDecoder.decode in your code
write a custom decoder for such strings
P.S. ask your questions more clear to avoid getting negative points
I am not sure why this url is throwing a MalformedURL exception: http%3A%2F%2Fapi.themoviedb.org%2F3%2Fsearch%2Fperson%3Fapi_key%3secret%26query%3Dchristopher_guest
This is the url required by the api that I need to use. http://api.themoviedb.org/3/search/person?api_key=secret&query=christopher_guest
I have been getting target host must not be null errors using this url then I changed my coded to what you are seeing below. Not sure whats going on here although I have heard urls that contain underscores dont validate outside of web browsers and cause these types of situations.
Any ideas around this?
This is where I build the url
package com.tot.tipofthetongue;
import android.widget.EditText;
public class getName {
static String nameOne = null;
static String nameTwo = null;
static StringBuilder personURLOne = new StringBuilder();
static StringBuilder personURLTwo = new StringBuilder();
public static String personURL = "http://api.themoviedb.org/3/search/person?api_key=secret&query=";
public static StringBuilder getName1(EditText searchOne){
nameOne = searchOne.getText().toString();
nameOne = nameOne.replace(" ", "_");
personURLOne.append(personURL);
personURLOne = personURLOne.append(nameOne);
return personURLOne;
}
And this is my jsonparser that I pass that url to.
public class JSONParser extends AsyncTask<String, Void, JSONObject> {
static InputStream inputStream = null;
static JSONObject jObject = null;
static String jSon = "";
public String myURL;
String host;
HttpRequest request;
protected JSONObject doInBackground(String... url) {
// TODO Auto-generated method stub
//Make HTTP Request
try {
//defaultHttpClient
for(int i = 0; i < url.length; i++){
myURL = url[0];
myURL = URLEncoder.encode(myURL, "utf-8");
}
HttpGet httpGet = new HttpGet(myURL);
//header
httpGet.setHeader("Accept", "application/json");
HttpResponse httpResponse = new DefaultHttpClient().execute(new HttpHost(new URL(myURL).getHost()), request);
HttpEntity httpEntity = httpResponse.getEntity();
inputStream = httpEntity.getContent();
} catch (UnsupportedEncodingException e){
e.printStackTrace();
} catch (ClientProtocolException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null){
stringBuilder.append(line + "\n");
}
Log.d("JSON Contents", stringBuilder.toString());
inputStream.close();
jSon = stringBuilder.toString();
} catch (Exception e){
Log.e("Buffer Error", "Error converting result " + e.toString());
}
//try to parse the string to JSON Object
try {
jObject = new JSONObject(jSon);
} catch (JSONException e){
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
//return JSON String
return jObject;
}
}
Print the String you formed before final submission to form Uri. And attach this to your question. It would be much easier to answer.
Try using HttpGet(URI uri) instead of HttpGet(String uri)
The reason is pretty simple. If you are using Uri, you will get immediately the Exception.
Hope this will help you to debug quickly.