I have a problem with parsing an JSON object inside a JSON object, this is how my JSON file looks like:
{
"index":1,
"name":"Peter",
"status":"Student",
"traditional":true,
"address":
{
"street":"Street1",
"city":"City1",
"ZIP":11000
},
"phoneNumbers":[1231123,123111],
"role":"Programmer"
}
And the parseJson() method:
public String parseJson() {
Integer rbr = 0;
StringReader stringReader = new StringReader(jsonStr);
JsonParser jsonParser = Json.createParser(stringReader);
Map<String, Object> jsonMap = new HashMap<>();
String jsonKeyNm = null;
Object jsonVal = null;
while (jsonParser.hasNext()) {
JsonParser.Event event = jsonParser.next();
if (event.equals(Event.KEY_NAME)) {
jsonKeyNm = jsonParser.getString();
}
else if (event.equals(Event.VALUE_STRING)) {
jsonVal = jsonParser.getString();
}
else if (event.equals(Event.VALUE_NUMBER)) {
jsonVal = jsonParser.getInt();
}
**else if (event.equals(Event.START_OBJECT)) {
if(rbr == 0){
//The rbr is used, since when first time when it starts going through json it will be an *START_OBJECT* event too.
rbr++;
continue;
}
jsonVal = jsonParser.getClass();
}**
else if (event.equals(Event.VALUE_TRUE)) {
jsonVal = (Boolean) true;
}
else if (event.equals(Event.VALUE_FALSE)) {
jsonVal = (Boolean) false;
}
**else if (event.equals(Event.START_ARRAY)) {
jsonVal = event.VALUE_STRING;
}**
else if (event.equals(Event.END_ARRAY)) {
jsonVal = event.VALUE_STRING;
}
jsonMap.put(jsonKeyNm, jsonVal);
}
student.setName((String)jsonMap.get("name"));
student.setIndex((Integer)jsonMap.get("index"));
student.setStatus((String)jsonMap.get("status"));
student.setTraditional((Boolean)jsonMap.get("traditional"));
Address address1 = (Address) jsonMap.get("address");
// Tried this too
//Address address =(Address) jsonMap.get("address").getClass().cast(Adress.class);
}
What it actually returns me when I execute jsonMap.get("address") is Java.util.class type. And I am stuck again, can't manage to extract any data from that.
Any help how I could accept and work with the object I get or any other way I could use to read all the data properly?
Also I have a problem reading Array from JSON, since the methods that JsonParser has are only:
.getBigDecimail()
.getInt()
.getLocation()
.getLong()
.getString()
.getClass()
I have to say that I have done it using The JSON-P object model API, but for my project for my university they are asking me to work with The JSON-P streaming API.
Thanks in advance!
public static String parseJson(InputStream in) {
String key = "student";
Deque<String> stack = new LinkedList<>();
Map<String, Object> map = new HashMap<>();
Object obj = null;
JsonParser parser = Json.createParser(in);
while (parser.hasNext()) {
Event event = parser.next();
if (event == Event.START_OBJECT) {
map.putIfAbsent(key, new HashMap<>());
obj = map.get(key);
stack.push(key);
} else if (event == Event.END_OBJECT) {
stack.pop();
obj = stack.isEmpty() ? null : map.get(stack.element());
} else if (event == Event.START_ARRAY) {
Object tmp = new ArrayList<>();
setValue(obj, key, tmp);
obj = tmp;
} else if (event == Event.END_ARRAY)
obj = stack.isEmpty() ? null : map.get(stack.element());
else if (event == Event.KEY_NAME)
key = parser.getString().toLowerCase();
else {
Object value = null;
if (event == Event.VALUE_STRING)
value = parser.getString();
else if (event == Event.VALUE_NUMBER)
value = parser.getInt();
else if (event == Event.VALUE_TRUE)
value = true;
else if (event == Event.VALUE_FALSE)
value = false;
setValue(obj, key, value);
}
}
Student student = new Student();
student.setName(getMapValue(map, "student", "name"));
student.setIndex(getMapValue(map, "student", "index"));
student.setStatus(getMapValue(map, "student", "status"));
student.setTraditional(getMapValue(map, "student", "traditional"));
student.setRole(getMapValue(map, "student", "role"));
student.setPhoneNumbers(getMapValue(map, "student", "phoneNumbers"));
Address address = new Address();
address.setStreet(getMapValue(map, "address", "street"));
address.setCity(getMapValue(map, "address", "city"));
address.setZip(getMapValue(map, "address", "zip"));
return "";
}
private static void setValue(Object obj, String key, Object value) {
if (obj instanceof Map)
((Map<String, Object>)obj).put(key, value);
else
((Collection<Object>)obj).add(value);
}
private static <T> T getMapValue(Map<String, Object> map, String obj, String key) {
Map<String, Object> m = (Map<String, Object>)map.get(obj.toLowerCase());
return m != null ? (T)m.get(key.toLowerCase()) : null;
}
I'm trying to refactoring this code
private void validate(Customer customer) {
List<String> errors = new ArrayList<>();
if (customer == null) {
errors.add("Customer must not be null");
}
if (customer != null && customer.getName() == null) {
errors.add("Name must not be null");
}
if (customer != null && customer.getName().isEmpty()) {
errors.add("Name must not be empty");
}
if (customer != null) {
Customer customerFromDb = customerRepository.findByName(customer.getName());
if (customerFromDb != null) {
errors.add("Customer already present on db");
}
}
if (!errors.isEmpty()) {
throw new ValidationException(errors);
}
}
I read this post Business logic validation patterns & advices
I'd like to build a generic validator for my entities and fields of the entity, I wrote this
private void validate(Customer customer) {
List<ValidationRule> validationRules = new ArrayList<>();
validationRules.add(new NotNullValidationRule(customer));
validationRules.add(new NotNullValidationRule(customer, Customer::getName));
validationRules.add(new NotEmptyValidationRule(customer, Customer::getName));
validationRules.add(new NotExistValidationRule(customer -> customerRepository.findByName(customer.getName())));
Validator.validate(validationRules);
}
and the Validator class
public class Validator {
public static void validate(List<ValidationRule> validationRules) {
final List<String> errors = new ArrayList<>();
for (final ValidationRule rule : validationRules) {
final Optional<String> error = rule.validate();
if (error.isPresent()) {
errors.add(error.get());
}
}
if (!errors.isEmpty()) {
throw new ValidationException(errors);
}
}
}
but I don't know how to implement the interface ValidationRule and other classes (NotNullValidationRule, NotEmptyValidationRule, NotExistValidationRule)
I would write something like :
CommonValidations.notNull(errors, customer);
if (customer != null) {
CommonValidations.notEmpty(errors, customer.getName());
}
customerCustomeBeanValidations.validName(errors, customer.getName());
customerCustomeBeanValidations.notExist(errors, customer.getName());
In the link you reference, the accepted answer suggested using the Strategy design pattern, and then gave an example of both an interface and implementation. In your case, you would create a new interface ValidationRule, with at least one method validate(), and then you would create concrete classes that each implementat that interface (NotNullValidationRule, NotEmptyValidationRule, AlreadyExistValidationRule).
I found this solution:
I create an interface ValidationRule
import java.util.Optional;
public interface ValidationRule {
Optional<ValidationError> validate();
}
And some classes that implement the behaviours
public class NotNullValidationRule implements ValidationRule {
private Object object;
private String field;
public NotNullValidationRule(Object object, String field) {
this.object = object;
if (field == null || field.isEmpty()) {
throw new IllegalArgumentException("field must not be null or emtpy");
}
this.field = field;
}
#Override public Optional<ValidationError> validate() {
if (object == null) {
return Optional.empty();
}
try {
Object value = new PropertyDescriptor(field, object.getClass()).getReadMethod().invoke(object);
if (value == null) {
ValidationError validationError = new ValidationError();
validationError.setName(object.getClass().getSimpleName() + "." + field);
validationError.setError("Field " + field + " is null");
return Optional.of(validationError);
}
}
catch (Exception e) {
throw new IllegalStateException("error during retrieve of field value");
}
return Optional.empty();
}
}
Another where I pass a method to call:
package it.winetsolutions.winactitime.core.service.validation;
import java.beans.PropertyDescriptor;
import java.util.Optional;
import java.util.function.Function;
public class NotExistValidationRule implements ValidationRule {
Object object;
String field;
Function<? super String, ? super Object> function;
public NotExistValidationRule(Object object, String field, Function<? super String, ? super Object> function) {
this.object = object;
if (field == null || field.isEmpty() || function == null) {
throw new IllegalArgumentException("field and function must not be null or emtpy");
}
this.field = field;
this.function = function;
}
#Override public Optional<ValidationError> validate() {
if (object == null) {
return Optional.empty();
}
try {
Object value = new PropertyDescriptor(field, object.getClass()).getReadMethod().invoke(object);
Long id = (Long) new PropertyDescriptor("id", object.getClass()).getReadMethod().invoke(object);
Object result = function.apply(value == null ? (String) value : ((String) value).trim());
if (result != null &&
!id.equals((Long) new PropertyDescriptor("id", result.getClass()).getReadMethod().invoke(result))) {
ValidationError validationError = new ValidationError();
validationError.setName(object.getClass().getSimpleName() + "." + field);
validationError.setError("Element with " + field +": " + value + " already exists");
return Optional.of(validationError);
}
}
catch (Exception e) {
throw new IllegalStateException("error during retrieve of field value");
}
return Optional.empty();
}
}
is there any other different solution for this code.
for every pojo class we have to check that modified data coming from browser and we will store only modified data into the database.
see below billingTax obj is coming from browser which is updated data
and billingtaxDbObject obj is retrieved from database and we will check with if condition whether updated data is changed or not
if pojo class has 20 fields, we have to write 20 if conditions
if pojo class has 5 fields, we have to write 5 if conditions
instead of writing if conditions for checking wheter data is modified or nor is there any other simplest way?
#Override
public BillingTax update(BillingTax billingTax) throws DataInsufficientException, RecordNotFoundException {
log.debug("BillingTaxServiceImpl.update()....................");
try {
if (billingTax == null)
throw new DataInsufficientException("billingTax object is null");
BillingTax billingtaxDbObject = get(billingTax.getId());
if (billingtaxDbObject == null)
throw new RecordNotFoundException("billingTax object is not found in database");
if (billingTax.getTaxApplyType() != null
&& !billingTax.getTaxApplyType().equals(billingtaxDbObject.getTaxApplyType()))
billingtaxDbObject.setTaxApplyType(billingTax.getTaxApplyType());
if (billingTax.getCode() != null && !billingTax.getCode().trim().equalsIgnoreCase("null")
&& !billingTax.getCode().equalsIgnoreCase(billingtaxDbObject.getCode()))
billingtaxDbObject.setCode(billingTax.getCode());
if (billingTax.getName() != null && !billingTax.getName().trim().equalsIgnoreCase("null")
&& !billingTax.getName().equalsIgnoreCase(billingtaxDbObject.getName()))
billingtaxDbObject.setName(billingTax.getName());
if (billingTax.getDescription() != null && !billingTax.getDescription().trim().equalsIgnoreCase("null")
&& !billingTax.getDescription().equalsIgnoreCase(billingtaxDbObject.getDescription()))
billingtaxDbObject.setDescription(billingTax.getDescription());
if (billingTax.getServiceTypeForTax() != null
&& !billingTax.getServiceTypeForTax().equals(billingtaxDbObject.getServiceTypeForTax()))
billingtaxDbObject.setServiceTypeForTax(billingTax.getServiceTypeForTax());
if (billingTax.getTaxValue() != null && !billingTax.getTaxValue().equals("null")
&& !billingTax.getTaxValue().equals(billingtaxDbObject.getTaxValue()))
billingtaxDbObject.setTaxValue(billingTax.getTaxValue());
if (billingTax.getStatus() != null && !billingTax.getStatus().equals(billingtaxDbObject.getStatus()))
billingtaxDbObject.setStatus(billingTax.getStatus());
if (billingTax.getOrderNo() != null && !billingTax.getOrderNo().equals("null")
&& !billingTax.getOrderNo().equals(billingtaxDbObject.getOrderNo()))
billingtaxDbObject.setOrderNo(billingTax.getOrderNo());
if (billingTax.getId() != null && !billingTax.getId().trim().equalsIgnoreCase(billingtaxDbObject.getId())
&& !billingTax.getId().equalsIgnoreCase(billingtaxDbObject.getId()))
billingtaxDbObject.setId(billingTax.getId());
if (billingTax.getStartDate()!= null && !billingTax.getStartDate().equals(billingtaxDbObject.getStartDate()))
billingtaxDbObject.setStartDate(billingTax.getStartDate());
if (billingTax.getEndDate()!= null && !billingTax.getEndDate().equals(billingtaxDbObject.getEndDate()))
billingtaxDbObject.setEndDate(billingTax.getEndDate());
billingtaxDbObject.setUpdatedDate(new Date());
return billingTaxDAO.update(billingtaxDbObject);
} catch (Exception e) {
log.error("BillingTaxServiceImpl.update()....................exception:" + e.getMessage());
throw e;
}
}
You can do it with Dynamic updates for hibernate if you can avoid check changes among dto and entity and update all fields that come from web. If you need check dto from web and entity you can use apache bean util to find all changed values (or use spring util if you have or reflection from java...) and update it with dynamic updates.
see : BeanUtils
BeanUtils.copyProperties() // there are 3 methods.
check how it works in source code .
Create your own util method , similar to BeanUtils.copyProperties() , but with logic that you need (not null and not equal with source-entity value ).
Also use method from BeanUtils , to get PropertyDescriptor :
public static PropertyDescriptor[] getPropertyDescriptors(Class clazz)
throws BeansException
iterate over array of PropertyDescriptor and do check that you need (set value into source with ReflectionUtils).
with this approach you populate only properties that are not null and changed( if you need it) into billingtaxDbObject and update it.
You can put your copy / merge method into some util class and reuse it for all place where you need copy from dto into entity with some checks.
this is developed by getting all the fields/properties from the pojo class and checking with wheter null data or modified data.
below is the code:
copyProperties(billingTax, billingtaxDbObject);
public void copyProperties(BillingTax source, BillingTax dest) throws Exception{
if (source == null)
throw new DataInsufficientException("billingTax object is null");
if (dest == null)
throw new RecordNotFoundException("billingtaxDbObject object is not found in database");
try{
for (Field field : source.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object sourceValue = field.get(source);
Object destValue=field.get(dest);
if(sourceValue!=null && sourceValue!="" && sourceValue!="null"){
if(sourceValue instanceof String){
if(!sourceValue.toString().trim().equalsIgnoreCase("null")){
if(!sourceValue.toString().equalsIgnoreCase(destValue.toString())){
field.set(dest, sourceValue);
System.err.println(field.getName()+" is modified:"+field.get(dest));
}
}
}
else{
if(!sourceValue.equals("null") && !sourceValue.equals(destValue)){
field.set(dest, sourceValue);
System.err.println(field.getName()+" is modified:"+field.get(dest));
}
}
}
}
System.out.println();
}catch (Exception e) {
throw e;
}
}
public class CopyConverter<T> {
private List<String> errorMessages = new ArrayList<>();
private int countSuccess = 0;
public CopyConverter<T> convert(T source, T target, Set<String> ignoreFields){
copyProperties(source,target,ignoreFields);
return this;
}
public boolean hasError(){
return errorMessages.isEmpty();
}
public List<String> getErrorMessages(){
return errorMessages;
}
private boolean copyProperties(T source ,T target , Set<String> ignoreFields) {
Objects.requireNonNull(source , "..error message...");
Objects.requireNonNull(target , "..error message...");
try {
Map<String, Field> fieldNameMapping = buildFiledMap(target.getClass().
getDeclaredFields());
ignoreFields = (ignoreFields == null ? new HashSet<>() : ignoreFields);
for (Map.Entry<String, Field> fieldEntry : fieldNameMapping.entrySet()) {
if (ignoreFields.contains(fieldEntry.getKey())) {
continue;
}
Field field = fieldEntry.getValue();
field.setAccessible(true);
Object sourceValue = field.get(source);
Object targetValue = field.get(source);
if (isChangedAsString(sourceValue, targetValue)) {
field.set(target, sourceValue);
continue;
}
if (isChangedAsObject(sourceValue, targetValue)) {
field.set(target, sourceValue);
}
countSuccess++;
}
} catch (Exception e) {
errorMessages.add(".......");
log.info(....);
}
return countSuccess == 0;
}
private Map<String, Field> buildFiledMap(Field[] fields) {
Map<String, Field> fieldMap = new HashMap<>(fields.length);
//Stream.of(fields).collect(Collectors.toMap())
for (Field field : fields) {
fieldMap.put(field.getName(), field);
}
return fieldMap;
}
private boolean isChangedAsObject(Object obj1, Object obj2) {
return (obj1 == null && obj2 != null) || (obj1 != null && !obj1.equals(obj1));
}
private boolean isChangedAsString(Object obj1, Object obj2) {
if (obj1 instanceof String && obj2 instanceof String) {
String value1 = (String) obj1;
String value2 = (String) obj2;
return value1 != null &&
!value1.trim().equalsIgnoreCase("null") &&//strange check
!value1.equalsIgnoreCase(value2);
}
return false;
}
}
I'm using Java, and I have a String which is JSON:
{
"name" : "abc" ,
"email id " : ["abc#gmail.com","def#gmail.com","ghi#gmail.com"]
}
Then my Map in Java:
Map<String, Object> retMap = new HashMap<String, Object>();
I want to store all the data from the JSONObject in that HashMap.
Can anyone provide code for this? I want to use the org.json library.
In recursive way:
public static Map<String, Object> jsonToMap(JSONObject json) throws JSONException {
Map<String, Object> retMap = new HashMap<String, Object>();
if(json != JSONObject.NULL) {
retMap = toMap(json);
}
return retMap;
}
public static Map<String, Object> toMap(JSONObject object) throws JSONException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keys();
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
if(value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if(value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
map.put(key, value);
}
return map;
}
public static List<Object> toList(JSONArray array) throws JSONException {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
if(value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if(value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
list.add(value);
}
return list;
}
Using Jackson library:
import com.fasterxml.jackson.databind.ObjectMapper;
Map<String, Object> mapping = new ObjectMapper().readValue(jsonStr, HashMap.class);
Using Gson, you can do the following:
Map<String, Object> retMap = new Gson().fromJson(
jsonString, new TypeToken<HashMap<String, Object>>() {}.getType()
);
Hope this will work, try this:
import com.fasterxml.jackson.databind.ObjectMapper;
Map<String, Object> response = new ObjectMapper().readValue(str, HashMap.class);
str, your JSON String
As Simple as this, if you want emailid,
String emailIds = response.get("email id").toString();
I just used Gson
HashMap<String, Object> map = new Gson().fromJson(json.toString(), HashMap.class);
Here is Vikas's code ported to JSR 353:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.json.JsonArray;
import javax.json.JsonException;
import javax.json.JsonObject;
public class JsonUtils {
public static Map<String, Object> jsonToMap(JsonObject json) {
Map<String, Object> retMap = new HashMap<String, Object>();
if(json != JsonObject.NULL) {
retMap = toMap(json);
}
return retMap;
}
public static Map<String, Object> toMap(JsonObject object) throws JsonException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keySet().iterator();
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
if(value instanceof JsonArray) {
value = toList((JsonArray) value);
}
else if(value instanceof JsonObject) {
value = toMap((JsonObject) value);
}
map.put(key, value);
}
return map;
}
public static List<Object> toList(JsonArray array) {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.size(); i++) {
Object value = array.get(i);
if(value instanceof JsonArray) {
value = toList((JsonArray) value);
}
else if(value instanceof JsonObject) {
value = toMap((JsonObject) value);
}
list.add(value);
}
return list;
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class JsonUtils {
public static Map<String, Object> jsonToMap(JSONObject json) {
Map<String, Object> retMap = new HashMap<String, Object>();
if(json != null) {
retMap = toMap(json);
}
return retMap;
}
public static Map<String, Object> toMap(JSONObject object) {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keySet().iterator();
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
if(value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if(value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
map.put(key, value);
}
return map;
}
public static List<Object> toList(JSONArray array) {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.size(); i++) {
Object value = array.get(i);
if(value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if(value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
list.add(value);
}
return list;
}
}
try this code :
Map<String, String> params = new HashMap<String, String>();
try
{
Iterator<?> keys = jsonObject.keys();
while (keys.hasNext())
{
String key = (String) keys.next();
String value = jsonObject.getString(key);
params.put(key, value);
}
}
catch (Exception xx)
{
xx.toString();
}
Latest Update: I have used FasterXML Jackson Databind2.12.3 to Convert JSON string to Map, Map to JSON string.
// javax.ws.rs.core.Response clientresponse = null; // Read JSON with Jersey 2.0 (JAX-RS 2.0)
// String json_string = clientresponse.readEntity(String.class);
String json_string = "[\r\n"
+ "{\"domain\":\"stackoverflow.com\", \"userId\":5081877, \"userName\":\"Yash\"},\r\n"
+ "{\"domain\":\"stackoverflow.com\", \"userId\":6575754, \"userName\":\"Yash\"}\r\n"
+ "]";
System.out.println("Input/Response JSON string:"+json_string);
ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
//java.util.Map<String, String> map = mapper.readValue(json_string, java.util.Map.class);
List<Map<String, Object>> listOfMaps = mapper.readValue(json_string, new com.fasterxml.jackson.core.type.TypeReference< List<Map<String, Object>>>() {});
System.out.println("fasterxml JSON string to List of Map:"+listOfMaps);
String json = mapper.writeValueAsString(listOfMaps);
System.out.println("fasterxml List of Map to JSON string:[compact-print]"+json);
json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(listOfMaps);
System.out.println("fasterxml List of Map to JSON string:[pretty-print]"+json);
output:
Input/Response JSON string:[
{"domain":"stackoverflow.com", "userId":5081877, "userName":"Yash"},
{"domain":"stackoverflow.com", "userId":6575754, "userName":"Yash"}
]
fasterxml JSON string to List of Map:[{domain=stackoverflow.com, userId=5081877, userName=Yash}, {domain=stackoverflow.com, userId=6575754, userName=Yash}]
fasterxml List of Map to JSON string:[compact-print][{"domain":"stackoverflow.com","userId":5081877,"userName":"Yash"},{"domain":"stackoverflow.com","userId":6575754,"userName":"Yash"}]
fasterxml List of Map to JSON string:[pretty-print][ {
"domain" : "stackoverflow.com",
"userId" : 5081877,
"userName" : "Yash"
}, {
"domain" : "stackoverflow.com",
"userId" : 6575754,
"userName" : "Yash"
} ]
Converting a JSON String to Map
public static java.util.Map<String, Object> jsonString2Map( String jsonString ) throws org.json.JSONException {
Map<String, Object> keys = new HashMap<String, Object>();
org.json.JSONObject jsonObject = new org.json.JSONObject( jsonString ); // HashMap
java.util.Iterator<?> keyset = jsonObject.keys(); // HM
while (keyset.hasNext()) {
String key = (String) keyset.next();
Object value = jsonObject.get(key);
System.out.print("\n Key : "+key);
if ( value instanceof org.json.JSONObject ) {
System.out.println("Incomin value is of JSONObject : ");
keys.put( key, jsonString2Map( value.toString() ));
} else if ( value instanceof org.json.JSONArray) {
org.json.JSONArray jsonArray = jsonObject.getJSONArray(key);
//JSONArray jsonArray = new JSONArray(value.toString());
keys.put( key, jsonArray2List( jsonArray ));
} else {
keyNode( value);
keys.put( key, value );
}
}
return keys;
}
Converting JSON Array to List
public static java.util.List<Object> jsonArray2List( org.json.JSONArray arrayOFKeys ) throws org.json.JSONException {
System.out.println("Incoming value is of JSONArray : =========");
java.util.List<Object> array2List = new java.util.ArrayList<Object>();
for ( int i = 0; i < arrayOFKeys.length(); i++ ) {
if ( arrayOFKeys.opt(i) instanceof org.json.JSONObject ) {
Map<String, Object> subObj2Map = jsonString2Map(arrayOFKeys.opt(i).toString());
array2List.add(subObj2Map);
} else if ( arrayOFKeys.opt(i) instanceof org.json.JSONArray ) {
java.util.List<Object> subarray2List = jsonArray2List((org.json.JSONArray) arrayOFKeys.opt(i));
array2List.add(subarray2List);
} else {
keyNode( arrayOFKeys.opt(i) );
array2List.add( arrayOFKeys.opt(i) );
}
}
return array2List;
}
public static Object keyNode(Object o) {
if (o instanceof String || o instanceof Character) return (String) o;
else if (o instanceof Number) return (Number) o;
else return o;
}
Display JSON of Any Format
public static void displayJSONMAP( Map<String, Object> allKeys ) throws Exception{
Set<String> keyset = allKeys.keySet(); // HM$keyset
if (! keyset.isEmpty()) {
Iterator<String> keys = keyset.iterator(); // HM$keysIterator
while (keys.hasNext()) {
String key = keys.next();
Object value = allKeys.get( key );
if ( value instanceof Map ) {
System.out.println("\n Object Key : "+key);
displayJSONMAP(jsonString2Map(value.toString()));
}else if ( value instanceof List ) {
System.out.println("\n Array Key : "+key);
JSONArray jsonArray = new JSONArray(value.toString());
jsonArray2List(jsonArray);
}else {
System.out.println("key : "+key+" value : "+value);
}
}
}
}
Google.gson to HashMap.
Convert using Jackson :
JSONObject obj = new JSONObject().put("abc", "pqr").put("xyz", 5);
Map<String, Object> map = new ObjectMapper().readValue(obj.toString(), new TypeReference<Map<String, Object>>() {});
You can convert any JSON to map by using Jackson library as below:
String json = "{\r\n\"name\" : \"abc\" ,\r\n\"email id \" : [\"abc#gmail.com\",\"def#gmail.com\",\"ghi#gmail.com\"]\r\n}";
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<String, Object>();
// convert JSON string to Map
map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
System.out.println(map);
Maven Dependencies for Jackson :
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
<scope>compile</scope>
</dependency>
Hope this will help. Happy coding :)
You can use Jackson API as well for this :
final String json = "....your json...";
final ObjectMapper mapper = new ObjectMapper();
final MapType type = mapper.getTypeFactory().constructMapType(
Map.class, String.class, Object.class);
final Map<String, Object> data = mapper.readValue(json, type);
If you hate recursion - using a Stack and javax.json to convert a Json String into a List of Maps:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import javax.json.Json;
import javax.json.stream.JsonParser;
public class TestCreateObjFromJson {
public static List<Map<String,Object>> extract(InputStream is) {
List extracted = new ArrayList<>();
JsonParser parser = Json.createParser(is);
String nextKey = "";
Object nextval = "";
Stack s = new Stack<>();
while(parser.hasNext()) {
JsonParser.Event event = parser.next();
switch(event) {
case START_ARRAY : List nextList = new ArrayList<>();
if(!s.empty()) {
// If this is not the root object, add it to tbe parent object
setValue(s,nextKey,nextList);
}
s.push(nextList);
break;
case START_OBJECT : Map<String,Object> nextMap = new HashMap<>();
if(!s.empty()) {
// If this is not the root object, add it to tbe parent object
setValue(s,nextKey,nextMap);
}
s.push(nextMap);
break;
case KEY_NAME : nextKey = parser.getString();
break;
case VALUE_STRING : setValue(s,nextKey,parser.getString());
break;
case VALUE_NUMBER : setValue(s,nextKey,parser.getLong());
break;
case VALUE_TRUE : setValue(s,nextKey,true);
break;
case VALUE_FALSE : setValue(s,nextKey,false);
break;
case VALUE_NULL : setValue(s,nextKey,"");
break;
case END_OBJECT :
case END_ARRAY : if(s.size() > 1) {
// If this is not a root object, move up
s.pop();
} else {
// If this is a root object, add ir ro rhw final
extracted.add(s.pop());
}
default : break;
}
}
return extracted;
}
private static void setValue(Stack s, String nextKey, Object v) {
if(Map.class.isAssignableFrom(s.peek().getClass()) ) ((Map)s.peek()).put(nextKey, v);
else ((List)s.peek()).add(v);
}
}
There’s an older answer using javax.json posted here, however it only converts JsonArray and JsonObject, but there are still JsonString, JsonNumber, and JsonValue wrapper classes in the output. If you want to get rid of these, here’s my solution which will unwrap everything.
Beside that, it makes use of Java 8 streams and is contained in a single method.
/**
* Convert a JsonValue into a “plain” Java structure (using Map and List).
*
* #param value The JsonValue, not <code>null</code>.
* #return Map, List, String, Number, Boolean, or <code>null</code>.
*/
public static Object toObject(JsonValue value) {
Objects.requireNonNull(value, "value was null");
switch (value.getValueType()) {
case ARRAY:
return ((JsonArray) value)
.stream()
.map(JsonUtils::toObject)
.collect(Collectors.toList());
case OBJECT:
return ((JsonObject) value)
.entrySet()
.stream()
.collect(Collectors.toMap(
Entry::getKey,
e -> toObject(e.getValue())));
case STRING:
return ((JsonString) value).getString();
case NUMBER:
return ((JsonNumber) value).numberValue();
case TRUE:
return Boolean.TRUE;
case FALSE:
return Boolean.FALSE;
case NULL:
return null;
default:
throw new IllegalArgumentException("Unexpected type: " + value.getValueType());
}
}
You can use google gson library to convert json object.
https://code.google.com/p/google-gson/
Other librarys like Jackson are also available.
This won't convert it to a map. But you can do all things which you want.
Brief and Useful:
/**
* #param jsonThing can be a <code>JsonObject</code>, a <code>JsonArray</code>,
* a <code>Boolean</code>, a <code>Number</code>,
* a <code>null</code> or a <code>JSONObject.NULL</code>.
* #return <i>Appropriate Java Object</i>, that may be a <code>Map</code>, a <code>List</code>,
* a <code>Boolean</code>, a <code>Number</code> or a <code>null</code>.
*/
public static Object jsonThingToAppropriateJavaObject(Object jsonThing) throws JSONException {
if (jsonThing instanceof JSONArray) {
final ArrayList<Object> list = new ArrayList<>();
final JSONArray jsonArray = (JSONArray) jsonThing;
final int l = jsonArray.length();
for (int i = 0; i < l; ++i) list.add(jsonThingToAppropriateJavaObject(jsonArray.get(i)));
return list;
}
if (jsonThing instanceof JSONObject) {
final HashMap<String, Object> map = new HashMap<>();
final Iterator<String> keysItr = ((JSONObject) jsonThing).keys();
while (keysItr.hasNext()) {
final String key = keysItr.next();
map.put(key, jsonThingToAppropriateJavaObject(((JSONObject) jsonThing).get(key)));
}
return map;
}
if (JSONObject.NULL.equals(jsonThing)) return null;
return jsonThing;
}
Thank #Vikas Gupta.
The following parser reads a file, parses it into a generic JsonElement, using Google's JsonParser.parse method, and then converts all the items in the generated JSON into a native Java List<object> or Map<String, Object>.
Note: The code below is based off of Vikas Gupta's answer.
GsonParser.java
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
public class GsonParser {
public static void main(String[] args) {
try {
print(loadJsonArray("data_array.json", true));
print(loadJsonObject("data_object.json", true));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void print(Object object) {
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(object).toString());
}
public static Map<String, Object> loadJsonObject(String filename, boolean isResource)
throws UnsupportedEncodingException, FileNotFoundException, JsonIOException, JsonSyntaxException, MalformedURLException {
return jsonToMap(loadJson(filename, isResource).getAsJsonObject());
}
public static List<Object> loadJsonArray(String filename, boolean isResource)
throws UnsupportedEncodingException, FileNotFoundException, JsonIOException, JsonSyntaxException, MalformedURLException {
return jsonToList(loadJson(filename, isResource).getAsJsonArray());
}
private static JsonElement loadJson(String filename, boolean isResource) throws UnsupportedEncodingException, FileNotFoundException, JsonIOException, JsonSyntaxException, MalformedURLException {
return new JsonParser().parse(new InputStreamReader(FileLoader.openInputStream(filename, isResource), "UTF-8"));
}
public static Object parse(JsonElement json) {
if (json.isJsonObject()) {
return jsonToMap((JsonObject) json);
} else if (json.isJsonArray()) {
return jsonToList((JsonArray) json);
}
return null;
}
public static Map<String, Object> jsonToMap(JsonObject jsonObject) {
if (jsonObject.isJsonNull()) {
return new HashMap<String, Object>();
}
return toMap(jsonObject);
}
public static List<Object> jsonToList(JsonArray jsonArray) {
if (jsonArray.isJsonNull()) {
return new ArrayList<Object>();
}
return toList(jsonArray);
}
private static final Map<String, Object> toMap(JsonObject object) {
Map<String, Object> map = new HashMap<String, Object>();
for (Entry<String, JsonElement> pair : object.entrySet()) {
map.put(pair.getKey(), toValue(pair.getValue()));
}
return map;
}
private static final List<Object> toList(JsonArray array) {
List<Object> list = new ArrayList<Object>();
for (JsonElement element : array) {
list.add(toValue(element));
}
return list;
}
private static final Object toPrimitive(JsonPrimitive value) {
if (value.isBoolean()) {
return value.getAsBoolean();
} else if (value.isString()) {
return value.getAsString();
} else if (value.isNumber()){
return value.getAsNumber();
}
return null;
}
private static final Object toValue(JsonElement value) {
if (value.isJsonNull()) {
return null;
} else if (value.isJsonArray()) {
return toList((JsonArray) value);
} else if (value.isJsonObject()) {
return toMap((JsonObject) value);
} else if (value.isJsonPrimitive()) {
return toPrimitive((JsonPrimitive) value);
}
return null;
}
}
FileLoader.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;
public class FileLoader {
public static Reader openReader(String filename, boolean isResource) throws UnsupportedEncodingException, FileNotFoundException, MalformedURLException {
return openReader(filename, isResource, "UTF-8");
}
public static Reader openReader(String filename, boolean isResource, String charset) throws UnsupportedEncodingException, FileNotFoundException, MalformedURLException {
return new InputStreamReader(openInputStream(filename, isResource), charset);
}
public static InputStream openInputStream(String filename, boolean isResource) throws FileNotFoundException, MalformedURLException {
if (isResource) {
return FileLoader.class.getClassLoader().getResourceAsStream(filename);
}
return new FileInputStream(load(filename, isResource));
}
public static String read(String path, boolean isResource) throws IOException {
return read(path, isResource, "UTF-8");
}
public static String read(String path, boolean isResource, String charset) throws IOException {
return read(pathToUrl(path, isResource), charset);
}
#SuppressWarnings("resource")
protected static String read(URL url, String charset) throws IOException {
return new Scanner(url.openStream(), charset).useDelimiter("\\A").next();
}
protected static File load(String path, boolean isResource) throws MalformedURLException {
return load(pathToUrl(path, isResource));
}
protected static File load(URL url) {
try {
return new File(url.toURI());
} catch (URISyntaxException e) {
return new File(url.getPath());
}
}
private static final URL pathToUrl(String path, boolean isResource) throws MalformedURLException {
if (isResource) {
return FileLoader.class.getClassLoader().getResource(path);
}
return new URL("file:/" + path);
}
}
If you want no-lib version, here is the solution with regex:
public static HashMap<String, String> jsonStringToMap(String inputJsonString) {
final String regex = "(?:\\\"|\\')(?<key>[\\w\\d]+)(?:\\\"|\\')(?:\\:\\s*)(?:\\\"|\\')?(?<value>[\\w\\s-]*)(?:\\\"|\\')?";
HashMap<String, String> map = new HashMap<>();
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(inputJsonString);
while (matcher.find()) {
for (int i = 1; i <= matcher.groupCount(); i++) {
map.put(matcher.group("key"), matcher.group("value"));
}
}
return map;
}
Imagine u have a list of email like below. not constrained to any programming language,
emailsList = ["abc#gmail.com","def#gmail.com","ghi#gmail.com"]
Now following is JAVA code - for converting json to map
JSONObject jsonObj = new JSONObject().put("name","abc").put("email id",emailsList);
Map<String, Object> s = jsonObj.getMap();
This is an old question and maybe still relate to someone.
Let's say you have string HashMap hash and JsonObject jsonObject.
1) Define key-list.
Example:
ArrayList<String> keyArrayList = new ArrayList<>();
keyArrayList.add("key0");
keyArrayList.add("key1");
2) Create foreach loop, add hash from jsonObject with:
for(String key : keyArrayList){
hash.put(key, jsonObject.getString(key));
}
That's my approach, hope it answer the question.
Using json-simple you can convert data JSON to Map and Map to JSON.
try
{
JSONObject obj11 = new JSONObject();
obj11.put(1, "Kishan");
obj11.put(2, "Radhesh");
obj11.put(3, "Sonal");
obj11.put(4, "Madhu");
Map map = new HashMap();
obj11.toJSONString();
map = obj11;
System.out.println(map.get(1));
JSONObject obj12 = new JSONObject();
obj12 = (JSONObject) map;
System.out.println(obj12.get(1));
}
catch(Exception e)
{
System.err.println("EROR : 01 :"+e);
}