How to parse two different objects from the same json file? - java

How to parse two different objects from the same json file knowing that parsing one of them block parsing the other, which means that i have to parse only one of them, this is my code:
try {
time = json1.getJSONObject(TAG_TIME);
String Time2 = time.toString();
deals = json1.getJSONObject(TAG_DEALS);
final String plusinfo = deals.getString(TAG_PLUS_INFO);
String title = deals.getString(TAG_TITLE);
Integer retail = deals.getInt(TAG_RETAIL);
String nretail = Integer.toString(retail);
Integer deal = deals.getInt(TAG_DEAL);
String ndeal = Integer.toString(deal);
String duration = deals.getString(TAG_DURATION);
String image = deals.getString(TAG_IMAGE_URL);
String participant = deals.getString(TAG_PARTICIPANT);
final String details = deals.getString(TAG_DETAILS);
final String name = deals.getString(TAG_ADVERTISER_NAME);
final String adress = deals.getString(TAG_ADVERTISER_ADDRESS);
final String phone = deals.getString(TAG_ADVERTISSER_PHONE);
/*String Time1 = deals.getString(TAG_DATE);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = new GregorianCalendar(0,0,0).getTime();
Date date2 = new GregorianCalendar(0,0,0).getTime();
try {
date1 = sdf.parse(Time1);
date2 = sdf.parse(Time2);
} catch (ParseException e) {
e.printStackTrace();
}
final String precision = deals.getString(TAG_PRECISION);
JSONArray c = deals.getJSONArray(TAG_PRECISION);
ArrayList<String> arrays = new ArrayList<String>();
for(int i = 0; i < c.length(); i++){
precision = c.getString(i);
arrays.add(precision);
}
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_TITLE, title);
map.put(TAG_RETAIL, nretail);
map.put(TAG_DEAL, ndeal);
map.put(TAG_DURATION, duration);
map.put(TAG_IMAGE_URL, image);
map.put(TAG_PARTICIPANT, participant);
map.put(TAG_SERVER_TIME, Time2);
otherdeals.add(map);

What do you mean it gets blocked? I dont see what the issue is with what you have posted. If you wish to parse two different JSON responses, either kick off two background threads (AsyncTask) or just parse them one after the other

Related

unable to redirect response in rest controller

I made two RestController apis. On response of second api I wanted first api's response (which is a json response), so I tried to use HttpServletResponse.redirect. I also set required content type to it. But on second api response I got Unsupported Media Type Content type 'null' not supported.
first API
#GetMapping(value="checkStatus/{msisdn}",consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CoreResponseHandler> fetchOcsByDate2(#PathVariable(value="msisdn",required=true)String msisdn){
long l_time_start = System.currentTimeMillis();
List<Object[]> list = repository.getSingleCallDetail(msisdn);
if(list==null || list.size()==0) {
System.out.println("NO RECORD FOUND");
}
JSONObject objMain = new JSONObject();
for(Object[] objArr: list) {
JSONObject obj = new JSONObject();
String msisdn_ = objArr[0]==null?null:objArr[0].toString();
String songId = objArr[1]==null?null:objArr[1].toString();
String songName = objArr[2]==null?null:objArr[2].toString();
String status = objArr[3]==null?null:objArr[3].toString();
String lang = objArr[4]==null?null:objArr[4].toString();
String startDate = objArr[5]==null?null:objArr[5].toString();
objMain.put("status", status);
objMain.put("language", lang);
obj.put("id", songId);
obj.put("msisdn", msisdn);
obj.put("songName", songName);
objMain.put("subscription", obj);
}
long l_time_end = System.currentTimeMillis();
long l_diff = l_time_end-l_time_start;
if(list!=null && list.size()>0) {
return new ResponseEntity<CoreResponseHandler>(new SuccessResponseBeanRefined(HttpStatus.OK, ResponseStatusEnum.SUCCESSFUL, ApplicationResponse.SUCCESSFUL, objMain,l_diff+" ms"),HttpStatus.OK);
}
if(list==null || list.size()==0) {
return new ResponseEntity<CoreResponseHandler>(new SuccessResponseBeanRefined(HttpStatus.NOT_FOUND, ResponseStatusEnum.FAILED, ApplicationResponse.Failed, "not found",l_diff+" ms"),HttpStatus.NOT_FOUND);
}
return new ResponseEntity<CoreResponseHandler>(new SuccessResponseBeanRefined(HttpStatus.BAD_REQUEST, ResponseStatusEnum.FAILED, ApplicationResponse.Failed," > Bad request",l_diff+" ms"),HttpStatus.BAD_REQUEST);
}
no problem in output. ran smooth
second API
#GetMapping(value="verifyOtp/{msisdn}/{otp}",consumes=MediaType.APPLICATION_JSON_VALUE)
public void verifyOtp(#PathVariable(value="msisdn",required=true)String msisdn,
#PathVariable(value="otp",required=true)String otp,HttpServletResponse response) throws Exception{
long l_time_start = System.currentTimeMillis();
long l_time_end = System.currentTimeMillis();
long l_diff = l_time_end-l_time_start;
List<Object[]> list = repository.verifyOtp(msisdn,otp);
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
if(list!=null && list.size()>0) {
for(Object[] obj:list) {
String strDate = obj[3]==null?null:obj[3].toString();
Date dtDb = sdf.parse(strDate);
Date dtNow = new Date();
String strDtNow = sdf.format(dtNow);
dtNow = sdf.parse(strDtNow);
long ldtDb = dtDb.getTime();
long ldtNow = dtNow.getTime();
if(ldtDb>ldtNow) {
System.out.println("success within time");
int ii = repository.updateIsActive(msisdn);
response.setContentType("application/json");
response.sendRedirect("http://localhost:9393/crbt/api/subscriber/ivr/checkStatus/"+msisdn);
}
else {
System.out.println("failure time over!");
}
}
}
else {
}
}
second Api Response in postman
What I expected was first API's response. But its giving me some 415 content type error
How can I get first API's success json response from second api's response.. I even tried org.springframework.http.HttpHeaders but couldn't get desired output. What changes I had to do in order to get first Api's response in my second api response.
I have a strange feeling answering your questions, because I dislike the solution I'll provided. But it might help, so I'll give a try.
Basically, your Controller are just Spring beans, which means you can do is having a dependency, and second controller will call first controller. This will also change your method verifyOtp to make it change the return type.
Something like that:
...
#Autowired
private FirstController firstController;
...
#GetMapping(value="verifyOtp/{msisdn}/{otp}",consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CoreResponseHandler> verifyOtp(#PathVariable(value="msisdn",required=true)String msisdn,
#PathVariable(value="otp",required=true)String otp,HttpServletResponse response) throws Exception{
long l_time_start = System.currentTimeMillis();
long l_time_end = System.currentTimeMillis();
long l_diff = l_time_end-l_time_start;
List<Object[]> list = repository.verifyOtp(msisdn,otp);
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
if(list!=null && list.size()>0) {
for(Object[] obj:list) {
String strDate = obj[3]==null?null:obj[3].toString();
Date dtDb = sdf.parse(strDate);
Date dtNow = new Date();
String strDtNow = sdf.format(dtNow);
dtNow = sdf.parse(strDtNow);
long ldtDb = dtDb.getTime();
long ldtNow = dtNow.getTime();
if(ldtDb>ldtNow) {
System.out.println("success within time");
int ii = repository.updateIsActive(msisdn);
return firstController.fetchOcsByDate2(msidn);
}
else {
System.out.println("failure time over!");
return null;
}
}
}
else {
return null;
}
}
I think you are trying to achieve something uncommon, and to avoid having this dependency between controller, consider:
Change your use case. Make the second controller returning a HttpStatus.OK, and make the client do the next call to the first controller
Create a service in charge of loading the msidn, which will avoid duplicate code, and keep you in a more standard position to make our evolutions.
The issue occurred due to GetMapping .
#GetMapping(value="checkStatus/{msisdn}",consumes=MediaType.APPLICATION_JSON_VALUE)
replace with below in first Api:
#GetMapping(value="checkStatus/{msisdn}")

Date format gets lost

There have been many posts that covers this topic but however I adjust them to my code I could not find a suitable answer.
try (BufferedReader br = new BufferedReader(new FileReader(path));)
{
String line = "";
Person tempPerson = null;
String dateFormat = "dd-MM-yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
Date tempBirthdayDate = null;
while ((line = br.readLine()) != null)
{
String[] splitFormat = line.split("/");
for (String s : splitFormat)
{
String[] datamember = s.split(", ");
//Some more stuff...
tempBirthdayDate = sdf.parse(datamember[3]);
sdf.format(tempBirthdayDate);
sdf.applyPattern(dateFormat);
//Some more stuff...
}
tempPerson = new Person(...,...,...,tempBirthdayDate,...,...);
}
}
Person.java copy constructor:
public Person(..., ..., ..., Date birthdayDate, ..., ...)
{
this.xxx = ...;
this.xxx = ...;
this.xxx = ...;
this.birthdayDate = birthdayDate;
this.xxx = adresse;
this.xxx = ...;
}
Those "..." are just place holders to shorten the code. In the source file (.txt) the date is in the same format I defined up there. But as soon as I call the toString()-Method on the birthdayDate I get following result for e.g. 05/26/1993:
Wed May 26 00:00:00 CEST 1993. Thank you for helping!
the toString method of a Date object is not affected by SimpleDateFormat you initialized.
You need to create a custom class extending Date and override the toString method
public class CustomDate extends Date {
......
#Override
public String toString(){
return new SimpleDateFormat("dd-MM-yyyy").format(this);
}
}
In Person constructor
public Person(..., ..., ..., CustomDate birthdayDate, ..., ...)
{
this.xxx = ...;
this.xxx = ...;
this.xxx = ...;
this.birthdayDate = birthdayDate;
this.xxx = adresse;
this.xxx = ...;
}
you can now call toString on birthdayDate and get the format you want

Java JsonObjectBuilder adding extra 'metadata' when added as child to JsonObjectBuilder

I have one JsonObjectBuilder that builds my response.
I have a for loop that loops 7 times, during each iteration it builds a new JsonObjectBuilder, adds key/value pairs, then this JsonObjectBuilder instance is added to the parent Builder for my response.
As I understand it, this method should build 7 nested JsonObjects in my response object.
private void addStoreHoursResponse(Map<String,Object> response, AppConfigHelper configHelper) throws IOException {
final String OPEN = "open";
final String CLOSE = "close";
final String NOTES = "notes";
JsonObject storeHours = configHelper.getStoreHours();
Calendar now = DateUtils.getEasternTimeZoneCalendar();
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
JsonObjectBuilder responseBuilder = Json.createObjectBuilder();
String open, close, notes;
for (int i = 0; i < 7; i++) {
JsonObjectBuilder hoursBuilder = Json.createObjectBuilder();
HoursKey hoursKey = HoursKey.getHoursKey(now);
JsonObject hours = storeHours.getJsonObject(hoursKey.toString());
open = hours.isNull(OPEN) ? null : hours.getString(OPEN);
close = hours.isNull(CLOSE) ? null : hours.getString(CLOSE);
notes = hours.isNull(NOTES) ? null : hours.getString(NOTES);
if (open == null || close == null) {
hoursBuilder.add(OPEN, JsonValue.NULL);
hoursBuilder.add(CLOSE, JsonValue.NULL);
hoursBuilder.add(NOTES, JsonValue.NULL);
} else {
hoursBuilder.add(OPEN, DateUtils.getIsoString(setCalendarTime(now, open)));
hoursBuilder.add(CLOSE, DateUtils.getIsoString(setCalendarTime(now, close)));
hoursBuilder.add(NOTES, notes);
}
responseBuilder.add(DateUtils.getIsoString(now), hoursBuilder);
now.add(Calendar.DAY_OF_MONTH, 1);
}
response.put(STORE_HOURS, responseBuilder.build());
}
private Calendar setCalendarTime(Calendar calendar, String time) {
String[] timeArray = time.split(":");
int hour = Integer.parseInt(timeArray[0]);
int minute = Integer.parseInt(timeArray[1]);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
return calendar;
}
My JsonResponse has the 7 JsonObjects, but they should look like the following...
"open" : ISO time string,
"close" : ISO time string,
"notes" : String value
I am getting this as a result, what am I doing wrong?

Facing an issue with hashtable

I am facing an issue with hashtable. I am working with blackberry. In the below code the sysout "vector size info is" shows the data has two but the sysout "size in hashtable" shows the data has one. I do not understand this.
try {
Hashtable listUserEvents = getUserInfo();
Vector listEvents = new Vector();
EventList eventList = (EventList) PIM.getInstance().openPIMList(PIM.EVENT_LIST, PIM.READ_ONLY);
Enumeration events = eventList.items();
while (events.hasMoreElements()) {
System.out.println("in while");
Event event = (Event) events.nextElement();
if (eventList.isSupportedField(Event.START) && event.countValues(Event.START) > 0) {
long start = event.getDate(Event.START, 0);
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm");
String dateString = sdf.formatLocal(start);
SimpleDateFormat sdf1 = new SimpleDateFormat("MMM dd,yyyy");
String date = sdf1.formatLocal(start);
System.out.println("dates are :" +date+ "user" +usrDate);
if (usrDate.equalsIgnoreCase(date)) {
System.out.println("dates are equal:" +date);
EventsBean eventBean = new EventsBean();
if (eventList.isSupportedField(Event.END) && event.countValues(Event.END) > 0) {
long end = event.getDate(Event.END, 0);
SimpleDateFormat sdform = new SimpleDateFormat("MMM dd, yyyy HH:mm");
String dateString1 = sdform.formatLocal(end);
eventBean.setStartDate(dateString);
eventBean.setEndDate(dateString1);
}
listEvents.addElement(eventBean);
if (listUserEvents.containsKey(usrDate)) {
Vector info = (Vector) listUserEvents.get(usrDate);
System.out.println("the size in getEvents is" + info.size());
info.addElement(eventBean);
System.out.println("vector size info is" + info.size());
listUserEvents.put(usrDate, info);
} else {
listUserEvents.put(usrDate, listEvents);
}
}
}
}
System.out.println("size in hashtable "+listUserEvents.size());
Now if i loop over this hashtable using the below code i get the data in vector has one
Enumeration events = listEvent.keys();
while (events.hasMoreElements()) {
String key = (String) events.nextElement();
if (key.equals(label1.getText())) {
Vector object = (Vector) listEvent.get(key);
System.out.println("vector size"+object.size());
Enumeration hashtable = listEvent.keys();
while (hashtable.hasMoreElements()) {
String keys = (String) hashtable.nextElement();
if (keys.equals(label1.getText())) {
Vector data = (Vector) listEvent.get(keys);
the data here gives only one ,but above it shows two.
The size of your hashtable is one, because it only has one entry.
The size of your vector that you store in the hashtable will not be reflected in the size of the hashtable.
There is only one item in Hashtable because you have only inserted one item - a list with two elements.

Check date format before parsing

I am parsing several documments with the field Duration. But in the differents files, it is in differnt formats, ex:
"Duration": "00:43"
"Duration": "113.046"
"Duration": "21.55 s"
I want to parse all of them to the format "Duration": "113.046", how could I check before any parsing in wich format it is??
Some conditions before this piece of code, because this is not right for all of them:
Long duration;
DateFormat sdf = new SimpleDateFormat("hh:mm:ss");
try {
Date durationD = sdf.parse(totalDuration);
Date zeroSec = sdf.parse("00:00:00");
duration = durationD.getTime() - zeroSec.getTime();
} catch (Exception e) {
duration = Long.parseLong(totalDuration);
}
Thanks in advance
You could match the pattern with help of regex and then format accordingly. Here's a kickoff example:
Map<Pattern, DateFormat> dateFormatPatterns = new HashMap<Pattern, DateFormat>();
dateFormatPatterns.put(Pattern.compile("\\d{1,2}:\\d{2}"), new SimpleDateFormat("H:m"));
dateFormatPatterns.put(Pattern.compile("\\d{1,3}\\.\\d{3}"), new SimpleDateFormat("s.S"));
dateFormatPatterns.put(Pattern.compile("\\d{1,2}\\.\\d{2} s"), new SimpleDateFormat("s.S 's'"));
String[] strings = { "00:43", "113.046", "21.55 s" };
DateFormat finalFormat = new SimpleDateFormat("HH:mm:ss");
for (String string : strings) {
for (Pattern pattern : dateFormatPatterns.keySet()) {
if (pattern.matcher(string).matches()) {
Date date = dateFormatPatterns.get(pattern).parse(string);
String formattedTime = finalFormat.format(date);
System.out.println(formattedTime);
break;
}
}
}
This yields here
00:43:00
00:01:53
00:00:21
If these are all your known input formats, then convert your input to your expected date format.
Just string-replace all : with . and remove s.
Do not forget to strip the spaces, too. By the way, "113.046" seems a bit odd date format to me - if I were in your shoes, I would have used some of the standard date time formats and convert the irregular ones.
My solution, not smart at all:
long DurationFixer(String duration){
long durationLong = 0;
if(duration.contains(":")){
DateFormat sdf = new SimpleDateFormat("mm:ss");
try {
Date durationD = sdf.parse(duration);
Date zeroSec = sdf.parse("00:00:00");
durationLong = durationD.getTime() - zeroSec.getTime();
} catch (Exception e) {
durationLong = (Long.parseLong(duration))/1000;
}
}
else{
String r = "";
if(duration.contains("s")){
for (int i = 0; i < duration.length()-2; i ++) {
if ((duration.charAt(i) == '.'))
break;
else
r += duration.charAt(i);
}
}
durationLong = Long.valueOf(r);
}
return durationLong;
}
If someone could find a better solution, please, tell me.
Thanks everybody!

Categories