JSON file reading from Hadoop HDFS using C#.NET - json

I am trying to read json file from HDFS to file stream and i am getting exception.
private string ReadHadoopJasonFiles(){//set variables string destFolderName = "/demo/ufo/in";
string destFileName = "admingroups_metadata.json";
//connect to hadoop cluster
Uri myUri = new Uri("http://localhost:50070");
string userName = "hadoop";
string srcFilename = destFolderName + "/" + destFileName;
//string srcFilename = #"C:\FilesForHadoopJason\admingroups_metadata.xml";
WebHDFSClient myClient = new WebHDFSClient(Convert.ToString(myUri), userName);
FileStream fs = new FileStream(srcFilename, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
string json;
try
{
json = sr.ReadToEnd();
string repalcedjson = json.Replace("\"", "'");
return repalcedjson;
}
catch (Exception)
{
return null;
}
finally
{
sr.Close();
fs.Dispose();
}
}
Exception:
System.IO.DirectoryNotFoundException was unhandled
HResult=-2147024893
Message=Could not find a part of the path 'C:\user\projects\PoC_\challengeOpenDump20140701160001_admingroups.json'.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
at ConsoleApplication1.HadoopJsonToRdbms.ReadHadoopJasonFiles() in c:\Users\DXG8488\Documents\Visual Studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 111
at ConsoleApplication1.HadoopJsonToRdbms.JsonToRDBMSControler() in c:\Users\DXG8488\Documents\Visual Studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 29
at ConsoleApplication1.HadoopJsonToRdbms.Main(String[] args) in c:\Users\DXG8488\Documents\Visual Studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 24
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

I use Sharphadoop
here is an example of a reading a Json Hadoop REST API
HttpWebRequest req = WebRequest.Create(url_path) as HttpWebRequest;
req.Method = WebRequestMethods.Http.Get; // Get method
req.Accept = "application/json"; // accept json
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
StreamReader reader = new StreamReader(resp.GetResponseStream());
string result = reader.ReadToEnd();
return result;

Related

Spring boot fromJson errors with com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line

I get a JSON like below from a call to an api:
{"birthDate":"2002-06-09T22:57:10.0756471Z","created":"2022-06-09T22:57:10.0756471Z","idNumber":"1234567","lastName":"Tester"}
I have confirmed that the JSON is correct, I validated it online and it validates.
My application gets this response and handles it properly without any issues. So does Postman.
However, MockMvc test in Springboot fails when converting this Json response string to my class with error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 15 path $.birthDate
I do conversion like:
MockHttpServletResponse response = mvc.perform(
post("/examples")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(String.valueOf(postData)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn()
.getResponse();
String responseString = response.getContentAsString(); // returns string like "{"birthDate":"2002-06-09....}"
Gson gson = new Gson();
ExampleResponse exampleResponse = gson.fromJson(responseString, ExampleResponse.class); // this line fails
My ExampleResponse class is:
public class ExampleResponse {
private String idNumber;
private String lastName;
private OffsetDateTime birthDate;
private OffsetDateTime created;
/// getters and setters
}
I dont understand why is the fromJson call failing.
Figured it out. Need to register OffsetDateTime with GsonBuilder like:
Add a class like:
public class OffsetDateTimeDeserializer implements JsonDeserializer<OffsetDateTime> {
#Override
public OffsetDateTime deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
return OffsetDateTime.parse(jsonElement.getAsString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
}
, then modify code above that uses Gson to convert Json string to model class to following:
MockHttpServletResponse response = mvc.perform(
post("/examples")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(String.valueOf(postData)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn()
.getResponse();
String responseString = response.getContentAsString();
String responseString = response.getContentAsString();
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeDeserializer());
Gson gson = gsonBuilder.setPrettyPrinting().create();
ExampleResponse exampleResponse = gson.fromJson(responseString, ExampleResponse.class); // NOW IT WORKS!!!

Spring Boot - Encrypt JSON data

In our application we have to encrypt/decrypt the Json property values (not the property name) for each request and response.
Example,
{"userName":"encrypted value", "email":"encrypted value"}
We use Sprint boot 1.3 and we are using #RequestBody and #ResponseBody annotations to bind the request json with the object and serialise the response object as JSON.
We don't want to call encrypt/decrypt method in our each controller method. Is there any way we can instruct sprint to decrypt the json values before binding with the request object? Similarly, to encrypt the response object field values before converting them to json? Or customising Jackson may help us?
Thanks!
You can write your own http message converter. Since you are using spring boot it would be quite easy: just extend your custom converter from AbstractHttpMessageConverter and mark the class with #Component annotation.
From spring docs:
You can contribute additional converters by simply adding beans of that type in a Spring Boot context. If a bean you add is of a type that would have been included by default anyway (like MappingJackson2HttpMessageConverter for JSON conversions) then it will replace the default value.
And here is a simple example:
#Component
public class Converter extends AbstractHttpMessageConverter<Object> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
#Inject
private ObjectMapper objectMapper;
public Converter(){
super(MediaType.APPLICATION_JSON_UTF8,
new MediaType("application", "*+json", DEFAULT_CHARSET));
}
#Override
protected boolean supports(Class<?> clazz) {
return true;
}
#Override
protected Object readInternal(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return objectMapper.readValue(decrypt(inputMessage.getBody()), clazz);
}
#Override
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
outputMessage.getBody().write(encrypt(objectMapper.writeValueAsBytes(o)));
}
private InputStream decrypt(InputStream inputStream){
// do your decryption here
return inputStream;
}
private byte[] encrypt(byte[] bytesToEncrypt){
// do your encryption here
return bytesToEncrypt;
}
}
Okay, so I used #eparvan 's answer and made few modifications.
Create a component that encrypts the JSON response and decrypt the request params from frontend.
I am fetching request params in encrypted format in "data" object something like this and also sending the encrypted response in the same way data object.
reference response:
{"data":"requestOrResponseInEncryptedUsingPrivateKey"}
#Component
public class Converter extends AbstractHttpMessageConverter<Object> {
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
#Autowired
private ObjectMapper objectMapper;
public Converter() {
super(MediaType.APPLICATION_JSON,
new MediaType("application", "*+json", DEFAULT_CHARSET));
}
#Override
protected boolean supports(Class<?> clazz) {
return true;
}
#Override
protected Object readInternal(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return objectMapper.readValue(decrypt(inputMessage.getBody()), clazz);
}
#Override
protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
outputMessage.getBody().write(encrypt(objectMapper.writeValueAsBytes(o)));
}
/**
* requests params of any API
*
* #param inputStream inputStream
* #return inputStream
*/
private InputStream decrypt(InputStream inputStream) {
//this is API request params
StringBuilder requestParamString = new StringBuilder();
try (Reader reader = new BufferedReader(new InputStreamReader
(inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
int c;
while ((c = reader.read()) != -1) {
requestParamString.append((char) c);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
//replacing /n if available in request param json string
//reference request: {"data":"thisisencryptedstringwithexpirytime"}
JSONObject requestJsonObject = new
JSONObject(requestParamString.toString().replace("\n", ""));
String decryptRequestString = EncryptDecrypt.decrypt(requestJsonObject.getString("data"));
System.out.println("decryptRequestString: " + decryptRequestString);
if (decryptRequestString != null) {
return new ByteArrayInputStream(decryptRequestString.getBytes(StandardCharsets.UTF_8));
} else {
return inputStream;
}
} catch (JSONException err) {
Log.d("Error", err.toString());
return inputStream;
}
}
/**
* response of API
*
* #param bytesToEncrypt byte array of response
* #return byte array of response
*/
private byte[] encrypt(byte[] bytesToEncrypt) {
// do your encryption here
String apiJsonResponse = new String(bytesToEncrypt);
String encryptedString = EncryptDecrypt.encrypt(apiJsonResponse);
if (encryptedString != null) {
//sending encoded json response in data object as follows
//reference response: {"data":"thisisencryptedstringresponse"}
Map<String, String> hashMap = new HashMap<>();
hashMap.put("data", encryptedString);
JSONObject jsob = new JSONObject(hashMap);
return jsob.toString().getBytes();
} else
return bytesToEncrypt;
}
}
Here is my EncryptDecrypt class where encryption and decryption is going on
class EncryptDecrypt {
static String encrypt(String value) {
try {
IvParameterSpec iv = new IvParameterSpec(Constants.Encryption.INIT_VECTOR.getBytes(StandardCharsets.UTF_8));
SecretKeySpec skeySpec = new
SecretKeySpec("PRIVATE_KEY_FOR_ENCRYPTION_OR_DECRYPTION"
.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
byte[] original = Base64.getEncoder().encode(encrypted);
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
static String decrypt(String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(Constants.Encryption.INIT_VECTOR
.getBytes(StandardCharsets.UTF_8));
SecretKeySpec skeySpec = new SecretKeySpec("PRIVATE_KEY_FOR_ENCRYPTION_OR_DECRYPTION".
getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
And you're done!

Restlet accepts JSON input from client and respond with POST

I am writing a program which accepts a JSON input with the following format from client:
{
"campaignID": 1,
"clientID": 1,
"pmapID": 1,
"ward": "1-Bedded (Private)",
"age": 20,
"attr1": "EXA1(A)",
"attr2": "EO",
"attr3": "11/02/2012",
"attr4": "SIN",
"attr5": "N",
"attr6": "Y"
}
I'd like to read the JSON input, save all the attributes into local variables (String, int, ...) and finally respond with a POST("JSON") which will return a single float/double value (e.g. {"PMC": 30.12} ).
public class RestletApplication extends Application
{
#Override
public synchronized Restlet createInboundRoot()
{
Router router = new Router(getContext());
router.attach("/pmc/calculate", PMCResource.class);
return router;
}
}
I have written the function so far but am lost how to read the JSON input:
public class PMCResource extends ServerResource
{
#Post("JSON")
public Representation post(Representation entity) throws ResourceException {
try {
if (entity.getMediaType().isCompatible(MediaType.APPLICATION_JSON))
{
// Read JSON file and parse onto local variables
// Do processing & return a float value
}
} catch (Exception e) {
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
}
}
5 May 2016 - Edited the resource class
// Imports
public class PMCResource extends ServerResource
{
static Logger LOGGER = LoggerFactory.getLogger(PMCResource.class);
#Override
#Post("JSON")
public Representation post(Representation entity) throws ResourceException
{
PMCMatrixDAO matrix = new PMCMatrixDAOImpl();
JsonObjectBuilder response = Json.createObjectBuilder();
try
{
if (entity.getMediaType().isCompatible(MediaType.APPLICATION_JSON))
{
InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());
try (JsonReader reader = Json.createReader(is)) {
JsonObject obj = reader.readObject();
double result = matrix.calculatePMC(obj);
response.add("PMC", result);
}
}
} catch (Exception e) {
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
return new StringRepresentation(response.build().toString());
}
}
The Implementation class
public class PMCMatrixDAOImpl implements PMCMatrixDAO
{
public double calculatePMC(JsonObject obj)
{
int campaignID = obj.getInt("campaignID");
int clientID = obj.getInt("clientID");
int pmapID = obj.getInt("pmapID");
String ward = obj.getString("ward");
int age = obj.getInt("age");
String attr1 = obj.getString("attr1");
String attr2 = obj.getString("attr2");
String attr3 = obj.getString("attr3");
String attr4 = obj.getString("attr4");
String attr5 = obj.getString("attr5");
String attr6 = obj.getString("attr6");
// SQL processing
double dPMC = sqlQueryCall(...);
return dPMC;
}
}
In order to parse your JSON file, and since you're using Maven I'll assume you have it on your classpath, you can do it using a FileInputStream or a FileReader. So, assuming your JSON file is called input.json and it is on the root of your src/main/resources folder, you can load it the following way:
using a FileInputStream:
InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());
try (JsonReader reader = Json.createReader(is)) {
// file processing is done here
}
using a FileReader:
FileReader fr = new FileReader(getClass().getResource("/input.json").getFile());
try (JsonReader reader = Json.createReader(fr)) {
// file processing is done here
}
Ok, so now that we have our JsonReader created, lets retrieve the contents of our JSON file:
InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());
try (JsonReader reader = Json.createReader(is)) {
JsonObject obj = reader.readObject();
// retrieve JSON contents
int campaingID = obj.getInt("campaignID");
int clientID = obj.getInt("clientID");
int pmapID = obj.getInt("pmapID");
String ward = obj.getString("ward");
int age = obj.getInt("age");
String attr1 = obj.getString("attr1");
String attr2 = obj.getString("attr2");
String attr3 = obj.getString("attr3");
String attr4 = obj.getString("attr4");
String attr5 = obj.getString("attr5");
String attr6 = obj.getString("attr6");
}
As an alternative of having several variables across your method, you could create a simple POJO, having those variable as attributes, and then populate it using Jackson:
public class MyPojo {
private int campaingID;
private int clientID;
private int pmapID;
private String ward;
private int age;
private String attr1;
private String attr2;
private String attr3;
private String attr4;
private String attr5;
private String attr6;
// getters & setters
}
Finally, in order to send the response back to your client, you could do this:
JsonObject response = Json.createObjectBuilder().add("PMC", 30.12).build();
return new StringRepresentation(response.toString());
So, the entire solution could look like this:
#Override
#Post("JSON")
public Representation post(Representation entity) throws ResourceException {
JsonObjectBuilder response = Json.createObjectBuilder();
try {
if (entity.getMediaType().isCompatible(MediaType.APPLICATION_JSON)) {
InputStream is = new FileInputStream(getClass().getResource("/input.json").getFile());
try (JsonReader reader = Json.createReader(is)) {
JsonObject obj = reader.readObject();
// retrieve JSON contents
int campaingID = obj.getInt("campaignID");
int clientID = obj.getInt("clientID");
int pmapID = obj.getInt("pmapID");
String ward = obj.getString("ward");
int age = obj.getInt("age");
String attr1 = obj.getString("attr1");
String attr2 = obj.getString("attr2");
String attr3 = obj.getString("attr3");
String attr4 = obj.getString("attr4");
String attr5 = obj.getString("attr5");
String attr6 = obj.getString("attr6");
}
// Do processing & execute your SQL query call here
double result = sqlQueryCall(...);
response.add("PMC", result);
}
} catch (Exception e) {
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
return new StringRepresentation(response.build().toString());
}
As a side note, the JsonReader class belongs to the Java EE API which, for compiling purposes it's okay. Although, for running purposes, one requires the declaration of a JSON-API implementation dependency in one's Maven project. For instance:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
Below is the way one can communicate to the REST web service through a client:
Create a simple POJO object that will contain the information to send, as mentioned above (MyPojo).
Your REST service would look something like this:
public class PMCResource extends ServerResource {
static Logger LOGGER = Logger.getLogger(RestletMain.class.getName());
#Post("JSON")
public Representation post(MyPojo entity) throws ResourceException {
PMCMatrixDAO matrix = new PMCMatrixDAOImpl();
JsonObjectBuilder response = Json.createObjectBuilder();
try {
double result = matrix.calculatePMC(entity);
response.add("PMC", result);
} catch (Exception e) {
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
return new StringRepresentation(response.build().toString());
}
}
Modify your PMCMatrixDAOImpl in order to process your POJO:
public double calculatePMC(MyPojo pojo) {
(...)
}
Create a client that allows you to test your REST service:
public class PMCResourceMain {
public static void main(String[] args) {
// take into account the context-root, if exists, and path to your REST service
ClientResource resource = new ClientResource("http://<host>:<port>");
MyPojo myPojo = new MyPojo();
myPojo.setCampaingID(1);
myPojo.setClientID(1);
myPojo.setPmapID(1);
myPojo.setWard("1-Bedded (Private)");
myPojo.setAge(20);
myPojo.setAttr1("EXA1(A)");
myPojo.setAttr2("EO");
myPojo.setAttr3("11/02/2012");
myPojo.setAttr4("SIN");
myPojo.setAttr5("N");
myPojo.setAttr6("Y");
try {
resource.post(myPojo, MediaType.APPLICATION_JSON).write(System.out);
} catch (ResourceException | IOException e) {
e.printStackTrace();
}
}
}
Full Restlet documentation can be found here.
For the benefit of those who landed in the same situation as me, here's my solution:
Resource class
#Override
#Post("JSON")
public Representation post(Representation entity) throws ResourceException
{
PMCMatrixDAO matrix = new PMCMatrixDAOImpl();
JsonObjectBuilder response = Json.createObjectBuilder();
try {
String json = entity.getText(); // Get JSON input from client
Map<String, Object> map = JsonUtils.toMap(json); // Convert input into Map
double result = matrix.calculatePMC(map);
response.add("PMC", result);
} catch (IOException e) {
LOGGER.error(this.getClass() + " - IOException - " + e);
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
return new StringRepresentation(response.build().toString());
}
JSON conversion utility class
public class JsonUtils {
private static final Logger LOG = LoggerFactory.getLogger(JsonUtils.class);
private JsonUtils() {
}
public static String toJson(Object object) {
String jsonString = null;
ObjectMapper mapper = new ObjectMapper();
try {
jsonString = mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
LOG.error(e.getMessage(), e);
}
return jsonString;
}
public static Map<String, Object> toMap(String jsonString) {
Map<String, Object> map = new ConcurrentHashMap<>();
ObjectMapper mapper = new ObjectMapper();
try {
map = mapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {
});
} catch (IOException e) {
LOG.error(e.getMessage(), e);
}
return map;
}
}
And the implementation class which handles all the processing
public class PMCMatrixDAOImpl implements PMCMatrixDAO
{
public double calculatePMC(Map<String, Object> map)
{
int campaignID = (int) map.get("campaignID");
int clientID = (int) map.get("clientID");
int pmapID = (int) map.get("pmapID");
String ward = (String) map.get("ward");
int age = (int) map.get("age");
String attr1 = (String) map.get("attr1");
String attr2 = (String) map.get("attr2");
String attr3 = (String) map.get("attr3");
String attr4 = (String) map.get("attr4");
String attr5 = (String) map.get("attr5");
String attr6 = (String) map.get("attr6");
// SQL processing
double dPMC = sqlQueryCall(...);
return dPMC;
}
}

android-studio JSON ERROR [ java.util.List.size()' on a null object reference]

I have a big error..
i don't know why i have that...
my code :
public class MainActivity extends ListActivity {
// URL to get contacts JSON
private static String url = "https://jordyruiz.herokuapp.com/clubs.json";
// JSON Node names
private static final String TAG_Allclub = "Allclub";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "NomClub";
private static final String TAG_LIGUE = "Ligue";
private static final String TAG_DISTRICT = "District";
private static final String TAG_NOMBREEQUIPE = "NombreEquipe";
private static final String TAG_CORRESPONDANT = "Correspondant";
private static final String TAG_ADRESSE = "Adresse";
private static final String TAG_EMAIL = "Email";
private static final String TAG_TELEPHONE = "Telephone";
private static final String TAG_LATITUDE = "Latitude";
private static final String TAG_LONGITUDE = "Longitude";
private static final String TAG_URL = "url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Calling async task to get json
new GetClubs().execute();
}
/**
* Async task class to get json by making HTTP call
*/
private class GetClubs extends AsyncTask<Void, Void, Void> {
// Hashmap for ListView
ArrayList<HashMap<String, String>> clubList;
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Chargement...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
WebRequest webreq = new WebRequest();
// Making a request to url and getting response
String jsonStr = webreq.makeWebServiceCall(url, WebRequest.GET);
Log.d("Response: ", "> " + jsonStr);
clubList = ParseJSON(jsonStr);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, clubList,
R.layout.list_item, new String[]{TAG_NAME, TAG_LIGUE,
TAG_DISTRICT, TAG_NOMBREEQUIPE}, new int[]{R.id.name,
R.id.Ligue, R.id.district, R.id.nombreequipe});
setListAdapter(adapter);
}
}
private ArrayList<HashMap<String, String>> ParseJSON(String json) {
if (json != null) {
try {
// Hashmap for ListView
ArrayList<HashMap<String, String>> clubList = new ArrayList<HashMap<String, String>>();
JSONObject jsonObj = new JSONObject(json);
// Getting JSON Array node
JSONArray clubs = jsonObj.getJSONArray(TAG_Allclub);
// looping through All clubs
for (int i = 0; i < clubs.length(); i++) {
JSONObject c = clubs.getJSONObject(i);
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String ligue = c.getString(TAG_LIGUE);
String district = c.getString(TAG_DISTRICT);
String nombreequipe = c.getString(TAG_NOMBREEQUIPE);
String correspondant = c.getString(TAG_CORRESPONDANT);
String adresse = c.getString(TAG_ADRESSE);
String email = c.getString(TAG_EMAIL);
String telephone = c.getString(TAG_TELEPHONE);
String latitude = c.getString(TAG_LATITUDE);
String longitude = c.getString(TAG_LONGITUDE);
String urlweb = c.getString(TAG_URL);
// Phone node is JSON Object
// JSONObject phone = c.getJSONObject(TAG_PHONE);
// String mobile = phone.getString(TAG_PHONE_MOBILE);
// String home = phone.getString(TAG_PHONE_HOME);
// tmp hashmap for single club
HashMap<String, String> club = new HashMap<String, String>();
// adding each child node to HashMap key => value
club.put(TAG_ID, id);
club.put(TAG_NAME, name);
club.put(TAG_LIGUE, ligue);
club.put(TAG_DISTRICT, district);
club.put(TAG_NOMBREEQUIPE, nombreequipe);
// adding club to clubs list
clubList.add(club);
}
return clubList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
return null;
}
}
}
and my json :
{
"Allclub":[{
"id": ​1,
"NomClub": "Alfortville US",
"Ligue": " LIGUE DE PARIS ILE DE FRANCE",
"District": "DISTRICT VAL DE MARNE",
"NombreEquipe": ​23,
"Correspondant": "SAMIR ABDELAZIZ",
"Adresse": "COMPLEXE VAL DE SEINE-Parc Sport, 4 allée Jean Baptiste Preux, - 94140 - ALFORTVILLE",
"Email": "usalfortville#lpiff.fr",
"Telephone": ​148935240,
"Latitude": ​48.7781247,
"Longitude": ​2.42247699999996,
"url": "https://jordyruiz.herokuapp.com/clubs/1.json"},
{ "id": ​2,
"NomClub": "PEROU UNI F.C.",
"Ligue": "LIGUE DE PARIS ILE DE FRANCE",
"District": "DISTRICT DES HAUTS-DE-SEINE",
"NombreEquipe": ​1,
"Correspondant": "CLAVO DIAZ HUGO",
"Adresse": "2 RUE LOUIS ARMAND - 75015 - PARIS 15",
"Email": "clavodiaz15#hotmail.com",
"Telephone": ​672803527,
"Latitude": ​48.8325026,
"Longitude": ​2.2759969,
"url": "https://jordyruiz.herokuapp.com/clubs/2.json"
}
]}
Error Log :
12-28 12:36:41.751 32074-32074/? E/SELinux: [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: FATAL EXCEPTION: main
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: Process: org.esiea.jordy_ruiz_elisabeth_duong.footballclub, PID: 32074
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.widget.SimpleAdapter.getCount(SimpleAdapter.java:93)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.widget.ListView.setAdapter(ListView.java:502)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.app.ListActivity.setListAdapter(ListActivity.java:265)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at org.esiea.jordy_ruiz_elisabeth_duong.footballclub.MainActivity$GetClubs.onPostExecute(MainActivity.java:97)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at org.esiea.jordy_ruiz_elisabeth_duong.footballclub.MainActivity$GetClubs.onPostExecute(MainActivity.java:50)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.os.AsyncTask.finish(AsyncTask.java:636)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.os.AsyncTask.access$500(AsyncTask.java:177)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.os.Looper.loop(Looper.java:145)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6837)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
12-28 12:36:46.041 32074-32074/org.esiea.jordy_ruiz_elisabeth_duong.footballclub E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
please can you help me...
thanks
jordy
For parsing JSON String I would recommand the excellent JsonReader.
It's part of an API created by Google, called GSON and is available as of Android 3.0. Should you need to use it on earlier Android version, you may use the standalone JAR file. More details here : https://stackoverflow.com/a/10174066/3535408
As for code, this is a short example of a json parser using GSON :
private static final String TAG_Allclub = "Allclub";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "NomClub";
private static final String TAG_LIGUE = "Ligue";
private static final String TAG_DISTRICT = "District";
private static final String TAG_NOMBREEQUIPE = "NombreEquipe";
private static final String TAG_CORRESPONDANT = "Correspondant";
private static final String TAG_ADRESSE = "Adresse";
private static final String TAG_EMAIL = "Email";
private static final String TAG_TELEPHONE = "Telephone";
private static final String TAG_LATITUDE = "Latitude";
private static final String TAG_LONGITUDE = "Longitude";
private static final String TAG_URL = "url";
public final static ArrayList<HashMap<String, String>> parseClubJson(final String json) {
if (TextUtils.isEmpty(json)) // checks if string is null or empty
throw new IllegalArgumentException("json MUST NOT be NULL or EMPTY!");
try {
final InputStreamReader inputStreamReader = new InputStreamReader(new ByteArrayInputStream(json.getBytes("UTF-8")));
final JsonReader jsonReader = new JsonReader(inputStreamReader);
final ArrayList<HashMap<String, String>> allClubs = new ArrayList<HashMap<String, String>>();
jsonReader.beginObject(); // if the json starts with a JSON Object
while (jsonReader.hasNext()){
// declare the values here, they will be initialized later
String id;
String name;
String ligue;
String district;
String nombreequipe;
String correspondant;
String adresse;
String email;
String telephone;
String latitude;
String longitude;
String urlweb;
final String node = jsonReader.nextName(); // get the next available JSON node
if (node.equals(TAG_Allclub)) {// according to your JSON this looks like an array of JSON Object
jsonReader.beginArray(); // so we begin a new array
while (jsonReader.hasNext()) { // while there are nodes inside this array
jsonReader.beginObject(); // we know it's an array of json objects
final String subNode = jsonReader.nextName();
if (subNode.equals(TAG_ID))
id = jsonReader.nextString(); // we retrieve the value of this node as a String
else if (subNode.equals(TAG_NAME))
name = jsonReader.nextString();
else if (subNode.equals(TAG_LIGUE))
ligue = jsonReader.nextString();
// etc -> keep checking for each single possible value
// don't forget to add an else in case of an unexpected node ...
else
jsonReader.skipValue(); // ... that we can safely skip
jsonReader.endObject(); //once we are over with this object, we close it
}
jsonReader.endArray(); // never forget to close the array
}
// Once done parsing through current club :
final HashMap<String, String> currentClub = new HashMap<>();
// put values here
allClubs.add(currentClub);
}
jsonReader.endObject(); // never forget to close an object
// Once you are done with parsing the json you can build your return your ArrayList of HasMap here
// Exception Catching requiered
} catch (final UnsupportedEncodingException uee) { // in case json.getBytes fails
Log.e(TAG, "Error while parsing JSON - Wrong Encoding! ->\n" + uee.getMessage());
Log.getStackTraceString(uee);
return null;
} catch (final IOException ioe) { // might VERY RARELY occur while reading the current stream.
Log.e(TAG, "Error while converting from JSON ->\n" + ioe.getMessage());
return null;
}
}
Don't forget to add compile 'com.google.code.gson:gson:2.3.1' in your build.gradle file or use import android.util.JsonReader
Note : using HasMap is resource expensive and ArrayList uses lot's of RAM depending on the number of objects to hold (here HashMaps). You'd be better off with POJO so that the end you have something like Club[];
Hope it helped !
Cheers from IN'TECH ;-)
1) In " Void doInBackground "clublist= pareJson(jsonStr) doesent work.what I can change in doInBackground ?
2) in " onPostExecute " it's correct ?
3) for put values its code : "currentClub.put(TAG_ID, id);" ?
4) in " Log.e(TAG,...) doesent work : Error:(165, 19) error: cannot find symbol variable TAG.
public class MainActivity extends ListActivity {
// URL to get contacts JSON
private static String url = "https://jordyruiz.herokuapp.com/clubs.json";
// JSON Node names
private static final String TAG_Allclub = "Allclub";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "NomClub";
private static final String TAG_LIGUE = "Ligue";
private static final String TAG_DISTRICT = "District";
private static final String TAG_NOMBREEQUIPE = "NombreEquipe";
private static final String TAG_CORRESPONDANT = "Correspondant";
private static final String TAG_ADRESSE = "Adresse";
private static final String TAG_EMAIL = "Email";
private static final String TAG_TELEPHONE = "Telephone";
private static final String TAG_LATITUDE = "Latitude";
private static final String TAG_LONGITUDE = "Longitude";
private static final String TAG_URL = "url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Calling async task to get json
new GetClubs().execute();
}
/**
* Async task class to get json by making HTTP call
*/
private class GetClubs extends AsyncTask<Void, Void, Void> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Chargement...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
WebRequest webreq = new WebRequest();
// Making a request to url and getting response
String jsonStr = webreq.makeWebServiceCall(url, WebRequest.GET);
Log.d("Response: ", "> " + jsonStr);
// clubList = ParseJSON(jsonStr);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, parseClubJson(TAG_ID),
R.layout.list_item, new String[]{TAG_NAME, TAG_LIGUE,
TAG_DISTRICT, TAG_NOMBREEQUIPE}, new int[]{R.id.name,
R.id.Ligue, R.id.district, R.id.nombreequipe});
setListAdapter(adapter);
}
}
public final static ArrayList<HashMap<String, String>> parseClubJson(final String json) {
if (TextUtils.isEmpty(json)) // checks if string is null or empty
throw new IllegalArgumentException("json MUST NOT be NULL or EMPTY!");
try {
final InputStreamReader inputStreamReader = new InputStreamReader(new ByteArrayInputStream(json.getBytes("UTF-8")));
final JsonReader jsonReader = new JsonReader(inputStreamReader);
final ArrayList<HashMap<String, String>> allClubs = new ArrayList<HashMap<String, String>>();
jsonReader.beginObject(); // if the json starts with a JSON Object
while (jsonReader.hasNext()){
// declare the values here, they will be initialized later
String id;
String name;
String ligue;
String district;
String nombreequipe;
String correspondant;
String adresse;
String email;
String telephone;
String latitude;
String longitude;
String urlweb;
final String node = jsonReader.nextName(); // get the next available JSON node
if (node.equals(TAG_Allclub)) {// according to your JSON this looks like an array of JSON Object
jsonReader.beginArray(); // so we begin a new array
while (jsonReader.hasNext()) { // while there are nodes inside this array
jsonReader.beginObject(); // we know it's an array of json objects
final String subNode = jsonReader.nextName();
if (subNode.equals(TAG_ID))
id = jsonReader.nextString(); // we retrieve the value of this node as a String
else if (subNode.equals(TAG_NAME))
name = jsonReader.nextString();
else if (subNode.equals(TAG_LIGUE))
ligue = jsonReader.nextString();
// etc -> keep checking for each single possible value
// don't forget to add an else in case of an unexpected node ...
else
jsonReader.skipValue(); // ... that we can safely skip
jsonReader.endObject(); //once we are over with this object, we close it
}
jsonReader.endArray(); // never forget to close the array
}
// Once done parsing through current club :
final HashMap<String, String> currentClub = new HashMap<>();
// put values here
currentClub.put(TAG_ID, id);
currentClub.put(TAG_ID, name);
currentClub.put(TAG_ID, ligue);
allClubs.add(currentClub);
}
jsonReader.endObject(); // never forget to close an object
// Once you are done with parsing the json you can build your return your ArrayList of HasMap here
// Exception Catching requiered
} catch (final UnsupportedEncodingException uee) { // in case json.getBytes fails
Log.e(TAG, "Error while parsing JSON - Wrong Encoding! ->\n" + uee.getMessage());
Log.getStackTraceString(uee);
return null;
} catch (final IOException ioe) { // might VERY RARELY occur while reading the current stream.
Log.e(TAG, "Error while converting from JSON ->\n" + ioe.getMessage());
return null;
}
}}
thanks a lot!
Cheers from ESIEA
jordy

parsing boolean value with Json

I'm using json to send objects from Android application to Web Api application.
When i try to send an object which contains boolean value its value will be deserialized into false even if its true in json !
Here is an exemple :
public class myObject{
public boolean value1;
public String value2;
}
And I have this method to my object to the server :
public String PostObject(String url, Object obj) throws ParseException, IOException {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
StringEntity stringEntity = new StringEntity(new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create().toJson(obj));
httpPost.setEntity(stringEntity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
httpPost.setHeader("Accept-Encoding", "gzip");
HttpResponse httpResponse = client.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
String resp = EntityUtils.toString(httpEntity);
return resp;
}
And finally here I'm sending my object to the server :
myObject obj = new myObject();
obj.value1 = true;
obj.value2 = "testing";
JSONHttpClient jsonHttpClient = new JSONHttpClient();
String response = jsonHttpClient.PostObject(myURL, obj);
And here my code from server side :
[AcceptVerbs("POST")]
public string test(myObject obj)
{
//obj.value1 = false !!!
}