Question:
I have a Restfull API on the local Apache server that returns a list of users from the database (localhost/api/users).
I'm using JSONLint site to validate my JSON. When accessing via browser I get the result and validate it in JSONLint, which returns me as valid JSON. An example returned by the API:
{
"usuarios": [
{
"id": 167,
"contrato": 1,
"cod": "1212",
"nome": "Marcos Roberto Pavesi",
"email": "marcos@p.com.br",
"senha": "114fdfefd3d69799f0b6f73ef764d405",
"ativo": "S",
"setor": "1",
"max_add": "",
"dealer": 0
},
{
"id": 520,
"contrato": 1,
"cod": "",
"nome": "avaliador",
"email": "avaliador@teste.com.br",
"senha": "e10adc3949ba59abbe56e057f20f883e",
"ativo": "S",
"setor": "2",
"max_add": "",
"dealer": 0
}
]
}
However, I am trying to access my application via Java following this explanation and I am getting the following error:
Exception in thread "main" org.json.JSONException:
A JSONObject text must begin with '{' at 1 [character 2 line 1]at org.json.JSONTokener.syntaxError(JSONTokener.java:433)
at org.json.JSONObject.(JSONObject.java:197)
at org.json.JSONObject.(JSONObject.java:324)
at com.main.Main.main(Main.java:14)
I'm accessing the api with the following code…
public static void main(String[] args) {
JSONObject obj = new JSONObject("http://localhost:8080/api_carmaix/api/usuarios");
JSONArray arr = null;
try {
arr = obj.getJSONArray("usuarios");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < arr.length(); i++)
{
System.out.println(arr.getJSONObject(i).getString("id"));
}
}
}
Answer:
Keep in mind that the classes in this package do not make requests.
They parse some source ( String
, Map
, …) and allow you to manipulate the object like a JSON.
Your code throws a JSONException
because a string starting with " {
" is expected and you are passing a url.
You need to break things down: First make the request to get the response from your API — and here it doesn't have to be anything complex, you can get the response as a string anyway. Once you have the answer in hand, you create a JSONObject
and pass that string as an argument to the constructor.
You can create a method that fetch the JSON in a url:
public String getJSON(String url){
String data = null;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.connect();
if(connection.getResponseCode() == 200){
try (BufferedReader buff = new BufferedReader(new InputStreamReader(connection.getInputStream()))){
String line;
StringBuilder builder = new StringBuilder();
while((line = buff.readLine()) != null)
builder.append(line);
data = builder.toString();
}
}
} catch(Exception err){
// Algum tratamento :)
}
return data;
}
Having this method, you can call it passing the URL that your API returns the JSON with the users. And the return, you can pass in the JSONObject
constructor:
// Resposta da API
String data = getJSON("http://localhost:8080/api_carmaix/api/usuarios");
if (data != null) {
try {
// Usando a resposta da API para criar um objeto JSON:
JSONObject json = new JSONObject(data);
JSONArray jsonArray = json.getJSONArray("usuarios");
for (int i = 0; i < jsonArray.length(); i++)
System.out.println("ID: " + jsonArray.getJSONObject(i).getInt("id"));
} catch (Exception err) {}
}
Also see that when traversing the JSONArray
I used getInt
instead of getString
as you are using. If you try to get the value of "id" as a string a JSONException
will also be thrown containing the message:
JSONObject["id"] not a string.