Getting empty JSON using Jackson [duplicate] - java

This question already exists:
How to use Jackson Serializer when you don't know the property names [duplicate]
Closed 4 years ago.
Right now I'm trying to parse incoming JSON that is in this format:
{
<email>: {
<name>: <string>, # setting value
...
},
...
}
For example:
{
"aaa#example.com": {
"statement": true
},
"bbb#example.com": {
"statement": false
}
}
I also will not know how many emails will be in this JSON. I am a little befuddled as to how you could get all these emails with Jackson without knowing the property name for this, and I was wondering if it was possible.
Here is my code so far:
public class GDPRConsent extends Model {
#JsonIgnore
private static final String GDPR_CONSENT = "gdprConsent";
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty
private ArrayList<String> emails;
#JsonProperty("serviceDataCollection")
private String dataCollection;
#JsonProperty("serviceDataCollection")
public String getDataCollectionConsent() {
return dataCollection;
}
#JsonProperty
public ArrayList<String> getEmails() {
return emails;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#Override
public String getId() {
return GDPR_CONSENT;
}
}
Here is my parser:
public static <T> T parseObject(String sourceJson, Class<T> classToParse) {
T parsedObject = null;
try {
parsedObject = sObjectMapper.readValue(sourceJson, classToParse);
} catch (JsonParseException e) {
LogUtils.d(LOG_TAG, "parseObject JsonParseException: " + e.toString());
} catch (JsonMappingException e) {
LogUtils.d(LOG_TAG, "parseObject JsonMappingException: " + e.toString());
} catch (IOException e) {
LogUtils.d(LOG_TAG, "parseObject IOException: " + e.toString());
}
return parsedObject;
}
I am currently getting an empty result returned even though I know the JSON is being passed in.

If your JSON only includes the data given in your example, then it corresponds to a TypeReference<Map<String, Map<String, Boolean>>>, which is basically a mapping of strings to a mapping of strings to booleans. An example parser looks like this (no extra POJOs required):
import java.io.IOException;
import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONParser {
static final String TEST_JSON = "{"
+" \"aaa#example.com\": {"
+" \"statement\": true"
+"},"
+"\"bbb#example.com\": {"
+" \"statement\": false"
+"}"
+"}";
public static void main (String... args) {
ObjectMapper mapper = new ObjectMapper();
try {
Map<String, Map<String, Boolean>> jsonAsNestedMap = mapper.readValue(
TEST_JSON, new TypeReference<Map<String, Map<String, Boolean>>>() {
});
System.out.println(jsonAsNestedMap);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
This will print out
{aaa#example.com={statement=true}, bbb#example.com={statement=false}}
If the innermost values of your JSON are more complex, then you can use TypeReference<Map<String, Map<String, Object>>>:
static final String TEST_JSON = "{"
+" \"aaa#example.com\": {"
+" \"statement\": true,"
+" \"another_property\" : \"value 1\""
+"},"
+"\"bbb#example.com\": {"
+" \"statement\": false,"
+" \"another_property\" : \"value 2\""
+"}"
+"}";
//...
public static void main (String... args) {
//...
Map<String, Map<String, Object>> jsonAsNestedMap = mapper.readValue(
TEST_JSON, new TypeReference<Map<String, Map<String, Object>>>() {
});
//...
}
Accessing individual properties is possible through normal map iteration and accessor methods:
for (Entry<String, Map<String, Object>> e : jsonAsNestedMap.entrySet()) {
System.out.println("email:" + e.getKey() + ", another_property: "
+ e.getValue().get("another_property"));
}
which would give
email:aaa#example.com, another_property: value 1
email:bbb#example.com, another_property: value 2

I'm trying to parse incoming JSON that is in this format
As already explained in your duplicate question, you can parse into a Map.
public class EmailData {
private boolean statement;
public boolean isStatement() {
return this.statement;
}
public void setStatement(boolean statement) {
this.statement = statement;
}
#Override
public String toString() {
return "EmailData[statement=" + this.statement + "]";
}
}
Test
String json = "{" +
"\"aaa#example.com\": {" +
"\"statement\": true" +
"}," +
"\"bbb#example.com\": {" +
"\"statement\": false" +
"}" +
"}";
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, EmailData>> typeRef = new TypeReference<>() {/**/};
HashMap<String, EmailData> emails = mapper.readValue(json, typeRef);
System.out.println(emails);
Output
{aaa#example.com=EmailData[statement=true], bbb#example.com=EmailData[statement=false]}
If you prefer the #JsonAnySetter approach, you can do something like this:
public class Content {
private List<EmailData> emailData = new ArrayList<>();
#JsonAnySetter
public void addEmail(String name, EmailData value) {
value.setEmail(name);
this.emailData.add(value);
}
#Override
public String toString() {
return this.emailData.toString();
}
}
public class EmailData {
private String email;
private boolean statement;
#JsonIgnore
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isStatement() {
return this.statement;
}
public void setStatement(boolean statement) {
this.statement = statement;
}
#Override
public String toString() {
return "EmailData[email=" + this.email + ", statement=" + this.statement + "]";
}
}
Test
String json = "{" +
"\"aaa#example.com\": {" +
"\"statement\": true" +
"}," +
"\"bbb#example.com\": {" +
"\"statement\": false" +
"}" +
"}";
ObjectMapper mapper = new ObjectMapper();
Content content = mapper.readValue(json, Content.class);
System.out.println(content);
Output
[EmailData[email=aaa#example.com, statement=true], EmailData[email=bbb#example.com, statement=false]]

Related

How to put Json object through loop

I want to loop through the questionnaires by using the for loop to set the value of the EMAIL_TO_CLIENT_IND.
The value inside the "path" is QUESTIONNAIRES/SUB_QUESTION/EMAIL_TO_CLIENT_IND.
The first "if" is if the level path in JSON is just one Ex. "Questionnaires". And the "else" is for the path more than 1 Ex. "Questionnaires/Question".
My current idea is put the jObject.getJSONObject() inside the "else" for loop.
You can use the JSONArray as follows
String json="{\"QUESTIONNAIRES\":[{\n" +
" \"SUB_QUESTION\":[{\n" +
" \"EMAIL_TO_CLIENT_IND\":\"N\"\n" +
" }]\n" +
"}]}";
try {
JSONObject mainObject=new JSONObject(json);
JSONArray questionnairesArray=mainObject.getJSONArray("QUESTIONNAIRES");
for (int i=0;i<questionnairesArray.length();i++){
JSONObject questionnairesObject= (JSONObject) questionnairesArray.get(i);
JSONArray subQuestionArray=questionnairesObject.getJSONArray("SUB_QUESTION");
for (int j=0;j<subQuestionArray.length();j++){
JSONObject subQuestionObject= (JSONObject) subQuestionArray.get(i);
subQuestionObject.put("EMAIL_TO_CLIENT_IND","Y");
}
}
Log.e("Output",mainObject.toString());
} catch (JSONException e) {
Log.e("Exception",e.getMessage());
}
Edited
can be solved using GSON library also
//frame data classes
class Response {
#SerializedName("QUESTIONNAIRES")
private List<Questionaire> questionaireList;
public List<Questionaire> getQuestionaireList() {
return questionaireList;
}
public void setQuestionaireList(List<Questionaire> questionaireList) {
this.questionaireList = questionaireList;
}
}
class Questionaire {
#SerializedName("SUB_QUESTION")
private List<SubQuestion> subQuestionList;
public List<SubQuestion> getSubQuestionList() {
return subQuestionList;
}
public void setSubQuestionList(List<SubQuestion> subQuestionList) {
this.subQuestionList = subQuestionList;
}
}
class SubQuestion {
#SerializedName("EMAIL_TO_CLIENT_IND")
private String emailToClientId;
public String getEmailToClientId() {
return emailToClientId;
}
public void setEmailToClientId(String emailToClientId) {
this.emailToClientId = emailToClientId;
}
}
//loop through data using GSON
Gson gson = new Gson();
String json = "{\"QUESTIONNAIRES\":[{\n" +
" \"SUB_QUESTION\":[{\n" +
" \"EMAIL_TO_CLIENT_IND\":\"N\"\n" +
" }]\n" +
"}]}";
Response response = gson.fromJson(json, Response.class);
for (Questionaire questionnaire : response.getQuestionaireList()) {
for (SubQuestion subQuestion : questionnaire.getSubQuestionList()) {
subQuestion.setEmailToClientId("Y");
}
}
Log.e("Output", gson.toJson(response));

Getting null pointer while reading the fileds from JSON to POJO

I have my json as given below which is coming as string. I want to map only two fields in SEGMENT object ex:(TYPE and UN_NUM) to a pojo. I used the following code which is returning null values.
test.json
{
"TEST": {
"NAME": "PART_TRAN",
"VERSION": "9.0",
"ID": "----",
"SEGMENT": {
"TYPE": "R",
"CLIENT_ID": "----",
"UN_NUM": "UN"
}
}
}
test.java
process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
String data = exchange.getIn().getBody(String.class);
try{
XmlMapper xmlMapper = new XmlMapper();
JsonNode jsonNode = xmlMapper.readTree(data.toString());
ObjectMapper objectMapper = new ObjectMapper();
String value = objectMapper.writeValueAsString(jsonNode);
logger.info("Converting XML to JSON {}" , value);
SEGMENT seg = objectMapper.readValue(value, SEGMENT.class);
Test test = new Test(seg);
logger.info("Test Object {}" , test);
}catch (JsonParseException e){
e.printStackTrace();
}catch (JsonMappingException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}).
SEGMENT.java
#Data
#JsonIgnoreProperties
public class SEGMENT {
#JsonIgnore
private String TYPE;
#JsonIgnore
private String CLIENT_ID;
#JsonIgnore
private String UN_NUM;
}
Test.java
#Data
public class Test {
private String NAME;
private String VERSION;
private String ID;
private SEGMENT segment;
}
Logs:
: Test Object Test(SEGMENT=SEGMENT(TYPE=null, CLIENT_ID =null,UN_NUM =null))
I just added the SEGMENT class which I'm using to map the json.
There is underscore-java library with methods U.fromJsonMap(json) and U.get(map, path). I am the maintainer of the project.
String jsonData = "{\n"
+ " \"TEST\": {\n"
+ " \"NAME\": \"PART_TRAN\",\n"
+ " \"VERSION\": \"9.0\",\n"
+ " \"ID\": \"----\",\n"
+ " \"SEGMENT\": {\n"
+ " \"TYPE\": \"R\",\n"
+ " \"CLIENT_ID\": \"----\",\n"
+ " \"UN_NUM\": \"UN\"\n"
+ " }"
+ " }"
+ "}";
Map<String, Object> jsonObject = U.fromJsonMap(jsonData);
String type = U.<String>get(jsonObject, "TEST.SEGMENT.TYPE");
String unNum = U.<String>get(jsonObject, "TEST.SEGMENT.UN_NUM");
System.out.println(type);
System.out.println(unNum);
Output:
R
UN

How do I save values submitted from form in activejdbc?

#Override
public Long createPost(Request request) {
Base.open();
ObjectMapper mapper = new ObjectMapper();
try {
Post newPost = mapper.readValue(request.body(), Post.class);
// Map values = ... initialize map
// newPost.saveIt();
} catch (IOException ex) {
Logger.getLogger(PostServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
}
Base.close();
return 1L;
}
From the official docs, this Map values = ... initialize map is not clear. I can do newPost.set("first_name", "Sam") but is there a better way instead of setting values likes this?
I'm not familiar with Spark (I'm the author of ActiveWeb ), but you can use filters to open/close connections instead of polluting your service classes:
http://sparkjava.com/documentation.html#filters
Additionally, if you can convert your request parameters into a java.util.Map, you then do this:
Post post = new Post();
post.fromMap(parameters);
if(post.save()){
//display success
}else{
Errors errors = post.errors();
//display errors
}
This is an example from ActiveWeb, but will help you with Spark too:
https://github.com/javalite/activeweb-simple/blob/master/src/main/java/app/controllers/BooksController.java
If I'm understanding correctly, you are looking at how to take values from a POST request and then use ActiveJDBC to save those values. I'm quite new as well and we are in the beginning stages of our app, but we are using SparkJava with ActiveJDBC.
The example is actual code, I didn't have time to simplify it. But basically we created a POJO for the model class. We originally extended the org.javalite.activejdbc.Model but we needed to handle audit fields (create, update user/time) and help translate from JSON, so we extended this with a custom class called CecilModel. But CecilModel extends the Model class.
We have a controller that receives the request. The request comes in as JSON that matches the field names of our model class. In our custom CecilModel class we map the JSON to a Map which then we use Model.fromMap method to hyrdrate the fields and puts it into our custom model POJO. We don't need the getters or setters, it's more for convenience. We just need our JSON request to have the same names as in our model.
Below is our code but maybe you can peek through it to see how we are doing it.
Our table model pojo.
package com.brookdale.model;
import java.sql.Timestamp;
import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.annotations.BelongsTo;
import org.javalite.activejdbc.annotations.BelongsToParents;
import org.javalite.activejdbc.annotations.IdGenerator;
import org.javalite.activejdbc.annotations.IdName;
import org.javalite.activejdbc.annotations.Table;
import com.brookdale.model.activejdbc.CecilModel;
// This class handles mapping of data from the database to objects
// and back, including custom selection queries.
#Table("RECURRINGITEMSCHEDULE")
#BelongsToParents({
#BelongsTo(foreignKeyName="itemID",parent=Item.class),
#BelongsTo(foreignKeyName="contactAgreementID",parent=ContactAgreement.class),
#BelongsTo(foreignKeyName="unitOfMeasureCode",parent=UnitOfMeasure.class)
})
#IdGenerator("SQ_RECURRINGITEMSCHEDULE.nextVal")
#IdName("recurringItemScheduleID")
public class RecurringItem extends CecilModel {
public Long getRecurringItemScheduleID() {
return getLong("recurringItemScheduleID");
}
public void setRecurringItemScheduleID(Long recurringItemScheduleID) {
set("recurringItemScheduleID",recurringItemScheduleID);
}
public Long getContactAgreementID() {
return getLong("contactAgreementID");
}
public void setContactAgreementID(Long contactAgreementID) {
set("contactAgreementID",contactAgreementID);
}
public Long getItemID() {
return getLong("itemID");
}
public void setItemID(Long itemID) {
set("itemID",itemID);
}
public Double getUnitChargeAmt() {
return getDouble("unitChargeAmt");
}
public void setUnitChargeAmt(Double unitChargeAmt) {
set("unitChargeAmt",unitChargeAmt);
}
public Integer getUnitQty() {
return getInteger("unitQty");
}
public void setUnitQty(Integer unitQty) {
set("unitQty",unitQty);
}
public String getUnitOfMeasureCode() {
return getString("unitOfMeasureCode");
}
public void setUnitOfMeasureCode(String unitOfMeasureCode) {
set("unitOfMeasureCode",unitOfMeasureCode);
}
public Timestamp getLastGeneratedPeriodEndDate() {
return getTimestamp("lastGeneratedPeriodEndDate");
}
public void setLastGeneratedPeriodEndDate(Timestamp lastGeneratedPeriodEndDate) {
set("lastGeneratedPeriodEndDate",lastGeneratedPeriodEndDate);
}
public Timestamp getEffEndDate() {
return getTimestamp("effEndDate");
}
public void setEffEndDate(Timestamp effEndDate) {
set("effEndDate",effEndDate);
}
public Timestamp getEffStartDate() {
return getTimestamp("effStartDate");
}
public void setEffStartDate(Timestamp effStartDate) {
set("effStartDate",effStartDate);
}
#Override
public void validate() {
validatePresenceOf("unitofmeasurecode","itemid","unitqty","effstartdate","unitChargeAmt","contactAgreementID");
validateNumericalityOf("itemid","unitQty","contactAgreementID");
// check to make sure this is an update operation
if (!this.isNew()) {
RecurringItem ridb = RecurringItem.findById(this.getId());
if (ridb.getLastGeneratedPeriodEndDate() != null) {
if (this.getItemID() != ridb.getItemID())
this.addError("itemid", "Item can not be updated once a charge has been created.");
if (!this.getEffStartDate().equals(ridb.getEffStartDate()))
this.addError("effstartdate", "Effective start date can not be updated once a charge has been created.");
if (this.getUnitChargeAmt() != ridb.getUnitChargeAmt())
this.addError("unitchargeamt", "Unit charge amount can not be updated after last generated period end date has been set.");
if (this.getUnitQty() != ridb.getUnitQty())
this.addError("unitqty", "Unit quantity can not be updated after last generated period end date has been set.");
if (!this.getUnitOfMeasureCode().equals(ridb.getUnitOfMeasureCode()))
this.addError("", "Unit of measure can not be updated after last generated period end date has been set.");
}
}
if (this.getEffEndDate() != null && this.getEffStartDate().compareTo(this.getEffEndDate()) >= 0) {
this.addError("effenddate", "Effective end date can not come before the start date.");
}
}
}
Extends our custom Model class. This will extend the actual ActiveJDBC Model class.
package com.brookdale.model.activejdbc;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.validation.ValidationBuilder;
import org.javalite.activejdbc.validation.ValidatorAdapter;
import com.brookdale.core.CLArgs;
import com.brookdale.security.bo.User;
public abstract class CecilModel extends Model {
private static final transient TypeReference<HashMap<String, Object>> mapType = new TypeReference<HashMap<String, Object>>() {};
private static final transient TypeReference<LinkedList<HashMap<String, Object>>> listMapType = new TypeReference<LinkedList<HashMap<String, Object>>>() {};
private static final transient SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
public Timestamp getUpdateDateTime() {
return getTimestamp("updateDateTime");
}
public void setUpdateDateTime(LocalDateTime updateDateTime) {
set("updateDateTime",updateDateTime == null ? null : Timestamp.valueOf(updateDateTime));
}
public Timestamp getCreateDateTime() {
return getTimestamp("createDateTime");
}
public void setCreateDateTime(LocalDateTime createDateTime) {
set("createDateTime",createDateTime == null ? null : Timestamp.valueOf(createDateTime));
}
public String getUpdateUsername() {
return getString("updateUsername");
}
public void setUpdateUsername(String updateUsername) {
set("updateUsername",updateUsername);
}
public String getCreateUsername() {
return getString("createUsername");
}
public void setCreateUsername(String createUsername) {
set("createUsername",createUsername);
}
public Long getUpdateTimeId() {
return getLong("updateTimeId");
}
public void setUpdateTimeId(Long updateTimeId) {
set("updateTimeId",updateTimeId);
}
public boolean save(User user) {
String userId = (CLArgs.args.isAuthenabled()) ? user.getUserid() : "TEST_MODE";
// insert
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
if (this.getId() == null || this.getId().toString().equals("0")) {
this.setId(null);
this.set("createDateTime", now);
this.set("createUsername", userId);
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", 1);
}
// update
else {
Long updatetimeid = this.getLong("updateTimeid");
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", updatetimeid == null ? 1 : updatetimeid + 1);
}
return super.save();
}
public boolean saveIt(User user) {
String userId = (CLArgs.args.isAuthenabled()) ? user.getUserid() : "TEST_MODE";
// insert
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
if (this.isNew()) {
this.setId(null);
this.set("createDateTime", now);
this.set("createUsername", userId);
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", 1);
}
// update
else {
Long updatetimeid = this.getLong("updateTimeid");
this.set("updateDateTime", now);
this.set("updateUsername", userId);
this.set("updateTimeId", updatetimeid == null ? 1 : updatetimeid + 1);
}
return super.saveIt();
}
public boolean saveModel(User user, boolean insert) {
if(insert){
this.insertIt(user);
}else{
this.updateIt(user);
}
return super.saveIt();
}
public boolean insertIt(User user) {
// insert
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
this.setId(null);
this.set("createDateTime", now);
this.set("createUsername", user.getUserid());
this.set("updateDateTime", now);
this.set("updateUsername", user.getUserid());
this.set("updateTimeId", 1);
return super.saveIt();
}
public boolean updateIt(User user) {
// insert
java.sql.Timestamp now = java.sql.Timestamp.valueOf(java.time.LocalDateTime.now());
Long updatetimeid = this.getLong("updateTimeid");
this.set("updateDateTime", now);
this.set("updateUsername", user.getUserid());
this.set("updateTimeId", updatetimeid == null ? 1 : updatetimeid + 1);
return super.saveIt();
}
// Convert a single ActiveJdbc Object to a json string
#SuppressWarnings("unchecked")
public String toJson() {
Map<String, Object> objMap = this.toMap();
try {
if (objMap.containsKey("parents")) {
Map<String, ?> parentsMap = (Map<String, ?>) objMap.get("parents");
for (String key: parentsMap.keySet()) {
objMap.put(key, parentsMap.get(key));
}
objMap.remove("parents");
}
if (objMap.containsKey("children")) {
Map<String, ?> childrenMap = (Map<String, ?>) objMap.get("children");
for (String key: childrenMap.keySet()) {
objMap.put(key, childrenMap.get(key));
}
objMap.remove("children");
}
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(jsonDateFormat);
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(objMap);
} catch (Exception e) { throw new RuntimeException(e); }
}
// Converts a single json object into an ActiveJdbc Model
public <T extends CecilModel> T toObj(String json) {
try {
Map<String, Object> objMap = toMap(json);
convertDatesToTimestamp(objMap);
return this.fromMap(objMap);
} catch (Exception e) { throw new RuntimeException(e); }
}
// STATIC CONVERTERS FOR COLLECTIONS OF OBJECTS
// Convert an ActiveJdbc LazyList Collection to a JSON string
public static <T extends Model> String toJson(Collection<T> objCollection) {
//objCollection.load();
StringBuffer json = new StringBuffer("[ ");
for (T obj: objCollection) {
if (CecilModel.class.isInstance(obj)) {
json.append(((CecilModel)obj).toJson() + ",");
} else {
try {
json.append(new ObjectMapper().writeValueAsString(obj));
} catch (Exception e) {
e.printStackTrace();
}
}
}
return json.substring(0, json.length()-1) + "]";
}
// Converts an array of json objects into a list of ActiveJdbc Models
public static <T extends Model> List<T> toObjList(String json, Class<T> cls) {
List<T> results = new LinkedList<T>();
try {
List<Map<String, Object>> objMapList = toMaps(json);
for (Map<String, Object> objMap: objMapList) {
convertDatesToTimestamp(objMap);
T obj = cls.newInstance().fromMap(objMap);
results.add(obj);
}
} catch (Exception e) { throw new RuntimeException(e); }
return results;
}
// Converts a single json object into a map of key:value pairs
private static Map<String, Object> toMap(String json) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(json, mapType);
} catch (IOException e) { throw new RuntimeException(e); }
}
// Converts an array of json objects into a list of maps
private static List<Map<String, Object>> toMaps(String json) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(json, listMapType);
} catch (IOException e) { throw new RuntimeException(e); }
}
// checks for Strings that are formatted in 'yyyy-MM-ddTHH:mm:ss.SSSZ' format
// if found it will replace the String value with a java.sql.Timestamp value in the objMap
private static final Map<String,Object> convertDatesToTimestamp(Map<String, Object> objMap) {
// attempt to convert all dates to java.sql.Timestamp
for (String key: objMap.keySet()) {
Object value = objMap.get(key);
System.out.println("Checking if '" + key + "=" + (value == null ? "null" : value.toString()) +"' is a date...");
if (value instanceof String && ((String) value).matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$")) {
String valuestr = (String) value;
System.out.println("DATE FOUND FOR '" + key + "' " + value);
objMap.put(key, Timestamp.valueOf(ZonedDateTime.parse(valuestr).toLocalDateTime()));
}
}
return objMap;
}
public static ValidationBuilder<?> validateAbsenceOf(String ... attributes) {
return validateWith(new ValidatorAdapter() {
#Override
public void validate(Model m) {
boolean containsAttribute = false;
for(String attribute:attributes) {
if(m.attributeNames().contains(attribute)) {
//model contains attribute, invalidate now !
m.addValidator(this, attribute);
break;
}
}
}
});
}
}
Our Controller
package com.brookdale.controller;
import static spark.Spark.get;
import static spark.Spark.post;
import static spark.Spark.put;
import org.codehaus.jackson.map.ObjectMapper;
import com.brookdale.model.RecurringItem;
import com.brookdale.model.activejdbc.CecilModel;
import com.brookdale.security.bo.User;
import com.brookdale.service.RecurringItemService;
public class RecurringItemController {
public RecurringItemController(final RecurringItemService service) {
// get list of recurring items based on the agreementid
get("/api/recurring/list/:agreementid", (req,res)-> {
String all = req.queryParams("all");
Long agreementid = Long.parseLong(req.params(":agreementid"));
//return RecurringItemAPI.searchByAgreement(Long.parseLong(req.params(":agreementid"))).toJson(true);
return CecilModel.toJson(service.findByAgreementId(agreementid, all != null));
});
// insert
post("/api/recurring/save", (req,res)-> {
//RecurringItem ri = ActiveJdbcJson.toObj(req.body(), RecurringItem.class);
RecurringItem ri = new RecurringItem().toObj(req.body());
// set unitqty to '1' since the field is not nullable, but not used
if (ri.getUnitQty() == null)
ri.setUnitQty(1);
System.out.println("ri to insert: " + new ObjectMapper().writeValueAsString(ri));
return service.saveRecurringItem(ri, (User) req.attribute("user")).toJson();
});
// update
put("/api/recurring/save", (req,res)-> {
//RecurringItem ri = ActiveJdbcJson.toObj(req.body(), RecurringItem.class);
RecurringItem ri = new RecurringItem().toObj(req.body());
System.out.println("ri to update: " + new ObjectMapper().writeValueAsString(ri));
return service.saveRecurringItem(ri, (User) req.attribute("user")).toJson();
});
}
}
Which calls our service layer to do the save.
package com.brookdale.service;
import org.javalite.activejdbc.LazyList;
import org.javalite.activejdbc.Model;
import com.brookdale.model.RecurringItem;
import com.brookdale.security.bo.User;
public class RecurringItemService {
public RecurringItemService() { }
public LazyList<Model> findByAgreementId(Long agreementId, boolean includeAll) {
if (includeAll)
return RecurringItem.find("contactAgreementID = ?", agreementId).orderBy("effstartdate desc");
else
return RecurringItem.find("contactAgreementID = ? and effenddate is null", agreementId).orderBy("effstartdate desc");
}
public RecurringItem saveRecurringItem(RecurringItem ri, User user) {
ri.saveIt(user);
return ri;
}
}

Gson to parse string of arrays

I need to parse the below JSON content. Currently I have stored it inflat file and reading it. I have given the sample POJO classes which are created and the code which I tried below.
Tried two different approach and both are giving the following error
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 3 path $
Json file
{
"DeviceCommon": {
"ASIdentifier": "123",
"DatadeliveyMechanism": "notify",
"MobileOriginatorCallbackReference": {
"url": "http://application.example.com/inbound/notifications/modatanotification/"
},
"AccessiblityCallbackReference": {
"url": "http://application.example.com/inbound/notifications/accessibilitystatusnotification"
}
},
"DeviceList": [{
"ExternalIdentifer": "123456#mydomain.com",
"msisdn": "123456",
"senderName": "Device1",
"MobileOriginatorCallbackReference": {
"notifyURL": "http://application.example.com/inbound/notifications/modatanotification/"
},
"ConfigurationResultCallbackReference": {
"notifyURL": "http://application.example.com/inbound/notifications/configurationResult"
},
"ASreferenceID": "AS000001",
"NIDDduration": "1d"
}]
}
POJO classes:
Note: I have mentioned only two classes here.
package com.As.jsonmodel.configrequest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class ConfigurationRequest
{
private DeviceList[] DeviceList;
private DeviceCommon DeviceCommon;
public DeviceList[] getDeviceList ()
{
return DeviceList;
}
public void setDeviceList (DeviceList[] DeviceList)
{
this.DeviceList = DeviceList;
}
public DeviceCommon getDeviceCommon ()
{
return DeviceCommon;
}
public void setDeviceCommon (DeviceCommon DeviceCommon)
{
this.DeviceCommon = DeviceCommon;
}
#Override
public String toString()
{
return "ClassPojo [DeviceList = "+DeviceList+", DeviceCommon = "+DeviceCommon+"]";
}
}
package com.As.jsonmodel.configrequest;
public class DeviceList
{
private MobileOriginatorCallbackReference MobileOriginatorCallbackReference;
private String NIDDduration;
private String ASreferenceID;
private String senderName;
private String ExternalIdentifer;
private String msisdn;
private ConfigurationResultCallbackReference ConfigurationResultCallbackReference;
public MobileOriginatorCallbackReference getMobileOriginatorCallbackReference ()
{
return MobileOriginatorCallbackReference;
}
public void setMobileOriginatorCallbackReference (MobileOriginatorCallbackReference MobileOriginatorCallbackReference)
{
this.MobileOriginatorCallbackReference = MobileOriginatorCallbackReference;
}
public String getNIDDduration ()
{
return NIDDduration;
}
public void setNIDDduration (String NIDDduration)
{
this.NIDDduration = NIDDduration;
}
public String getASreferenceID ()
{
return ASreferenceID;
}
public void setASreferenceID (String ASreferenceID)
{
this.ASreferenceID = ASreferenceID;
}
public String getSenderName ()
{
return senderName;
}
public void setSenderName (String senderName)
{
this.senderName = senderName;
}
public String getExternalIdentifer ()
{
return ExternalIdentifer;
}
public void setExternalIdentifer (String ExternalIdentifer)
{
this.ExternalIdentifer = ExternalIdentifer;
}
public String getMsisdn ()
{
return msisdn;
}
public void setMsisdn (String msisdn)
{
this.msisdn = msisdn;
}
public ConfigurationResultCallbackReference getConfigurationResultCallbackReference ()
{
return ConfigurationResultCallbackReference;
}
public void setConfigurationResultCallbackReference (ConfigurationResultCallbackReference ConfigurationResultCallbackReference)
{
this.ConfigurationResultCallbackReference = ConfigurationResultCallbackReference;
}
#Override
public String toString()
{
return "ClassPojo [MobileOriginatorCallbackReference = "+MobileOriginatorCallbackReference+", NIDD duration = "+NIDDduration+", AS referenceID = "+ASreferenceID+", senderName = "+senderName+", ExternalIdentifer = "+ExternalIdentifer+", msisdn = "+msisdn+", ConfigurationResultCallbackReference = "+ConfigurationResultCallbackReference+"]";
}
}
Json Reader
Approach1:
BufferedReader br = null;
try {
br = new BufferedReader(
new FileReader("/home/raj/apache-tomcat-8.0.3/webapps/file.json"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JsonReader jsonReader = new JsonReader(new FileReader("/home/raj/apache-tomcat-8.0.3/webapps/file.json"));
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
if (name.equals("DeviceCommon")) {
readApp(jsonReader);
}
}
jsonReader.endObject();
jsonReader.close();
}
public static void readApp(JsonReader jsonReader) throws IOException{
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
System.out.println(name);
if (name.contains("ASIdentifier")){
jsonReader.beginObject();
while (jsonReader.hasNext()) {
String n = jsonReader.nextName();
if (n.equals("MobileOriginatorCallbackReference")){
System.out.println(jsonReader.nextString());
}
if (n.equals("AccessiblityCallbackReference")){
System.out.println(jsonReader.nextInt());
}
if (n.equals("DeviceList")){
jsonReader.beginArray();
while (jsonReader.hasNext()) {
System.out.println(jsonReader.nextString());
}
jsonReader.endArray();
}
}
jsonReader.endObject();
}
}
jsonReader.endObject();
}
// TODO Auto-generated method stub
Aproach2:
Gson gson = new Gson();
DeviceList [] myTypes = gson.fromJson(new FileReader("/home/raj/apache-tomcat-8.0.3/webapps/file.json"), DeviceList[].class);
System.out.println(gson.toJson(myTypes));
Any pointers on how to parse this file will be helpful.
Here's how to do it with Gson:
import java.io.FileReader;
import java.util.Arrays;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
public class Main {
public static void main(String[] args) throws Exception {
Data data = new Gson().fromJson(new FileReader("data.json"), Data.class);
System.out.println(data);
}
}
class Data {
#SerializedName("DeviceCommon")
DeviceCommon deviceCommon;
#SerializedName("DeviceList")
DeviceListEntry[] deviceList;
#Override
public String toString() {
return "Data{" +
"\n deviceCommon=" + deviceCommon +
"\n deviceList=" + Arrays.toString(deviceList) +
"\n}";
}
}
class DeviceCommon {
#SerializedName("ASIdentifier")
String asIdentifier;
#SerializedName("DatadeliveyMechanism")
String datadeliveyMechanism;
#SerializedName("MobileOriginatorCallbackReference")
Url mobileOriginatorCallbackReference;
#SerializedName("AccessiblityCallbackReference")
Url accessiblityCallbackReference;
#Override
public String toString() {
return "DeviceCommon{" +
"\n asIdentifier='" + asIdentifier + '\'' +
"\n datadeliveyMechanism='" + datadeliveyMechanism + '\'' +
"\n mobileOriginatorCallbackReference=" + mobileOriginatorCallbackReference +
"\n accessiblityCallbackReference=" + accessiblityCallbackReference +
"\n }";
}
}
class DeviceListEntry {
#SerializedName("ExternalIdentifer")
String externalIdentifer;
String msisdn;
String senderName;
#SerializedName("MobileOriginatorCallbackReference")
NotifyUrl mobileOriginatorCallbackReference;
#SerializedName("ConfigurationResultCallbackReference")
NotifyUrl configurationResultCallbackReference;
#SerializedName("ASreferenceID")
String asReferenceID;
#SerializedName("NIDDduration")
String nidDduration;
#Override
public String toString() {
return "DeviceListEntry{" +
"\n externalIdentifer='" + externalIdentifer + '\'' +
"\n msisdn='" + msisdn + '\'' +
"\n senderName='" + senderName + '\'' +
"\n mobileOriginatorCallbackReference=" + mobileOriginatorCallbackReference +
"\n configurationResultCallbackReference=" + configurationResultCallbackReference +
"\n asReferenceID='" + asReferenceID + '\'' +
"\n nidDduration='" + nidDduration + '\'' +
"\n }";
}
}
class Url {
String url;
#Override
public String toString() {
return url;
}
}
class NotifyUrl {
String notifyURL;
#Override
public String toString() {
return notifyURL;
}
}
Running Main will result in the following output:
Data{
deviceCommon=DeviceCommon{
asIdentifier='123'
datadeliveyMechanism='notify'
mobileOriginatorCallbackReference=http://application.example.com/inbound/notifications/modatanotification/
accessiblityCallbackReference=http://application.example.com/inbound/notifications/accessibilitystatusnotification
}
deviceList=[DeviceListEntry{
externalIdentifer='123456#mydomain.com'
msisdn='123456'
senderName='Device1'
mobileOriginatorCallbackReference=http://application.example.com/inbound/notifications/modatanotification/
configurationResultCallbackReference=http://application.example.com/inbound/notifications/configurationResult
asReferenceID='AS000001'
nidDduration='1d'
}]
}

I want a method to extract Values that may sometimes contain "& and =" from URL parameters in Java

package com.bml.icbs.ws.param;
import java.util.HashMap;
public class RequestParameter {
private String param;
private HashMap<String, String> hashmap;
public RequestParameter(String param){
this.param=param;
this.hashmap = new HashMap<String, String>();
Integer i;
String key,value;
String myArray[] = this.param.split("&");
for (i=0;i<myArray.length;i++){
key=myArray[i].substring(0,myArray[i].indexOf("="));
value=myArray[i].substring(myArray[i].indexOf("=")+1);
this.hashmap.put(key,value);
}
}
public String getParameterValue(String key){
return this.hashmap.get(key);
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public HashMap<String, String> getHashmap() {
return hashmap;
}
public void setHashmap(HashMap<String, String> hashmap) {
this.hashmap = hashmap;
}
}
When I Test the above method in case the URL is "param2=ffffhhh&param1=oooo&param3=pppp&param4=iiii&param5=kkkkk"
The result is:
SIZE 5
URL param2=ffffhhh&param1=oooo&param3=pppp&param4=iiii&param5=kkkkk
HASHMAP {param1=oooo, param2=ffffhhh, param3=pppp, param4=iiii, param5=kkkkk}
PARAM1 = oooo
which is correct
public static void main(String[] args) {
RequestParameter reqParam = new RequestParameter("param2=ffffhhh&param1=oooo&param3=pppp&param4=iiii&param5=kkkkk");
System.out.println("SIZE " + reqParam.getHashmap().size());
System.out.println("URL " + reqParam.getParam());
System.out.println("HASHMAP " + reqParam.getHashmap());
System.out.println("PARAM1 = " reqParam.getParameterValue("param1"));
}
but In case I pass the URL as the following one:
"param2=ffff&&&hhh=&param1=oooo=&&param3=pppp&param4=iiii&&yy=&param5=kkkkk"
public static void main(String[] args) {
RequestParameter reqParam = new RequestParameter("param2=ffff&&&hhh=&param1=oooo=&&param3=pppp&param4=iiii&&yy=&param5=kkkkk");
System.out.println("SIZE " + reqParam.getHashmap().size());
System.out.println("URL " + reqParam.getParam());
System.out.println("HASHMAP " + reqParam.getHashmap());
System.out.println("PARAM1 = " reqParam.getParameterValue("param1"));
}
it throws the following exception: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1937)
at com.bml.icbs.ws.param.RequestParameter.(RequestParameter.java:188)
at com.bml.icbs.ws.param.main.main(main.java:9)
make sure array element !empy.
for (i=0;i<myArray.length;i++){
if(myArray[i] == null || myArray[i].length()==0){
continue;
}
key=myArray[i].substring(0,myArray[i].indexOf("="));
value=myArray[i].substring(myArray[i].indexOf("=")+1);
this.hashmap.put(key,value);
}

Categories

Resources