Pretty print String to JSON format - java

I execute an AWS command to retrieve the spot price history.
DescribeSpotPriceHistoryRequest request = new DescribeSpotPriceHistoryRequest().withEndTime(start)
.withInstanceTypes("m1.xlarge").withProductDescriptions("Linux/UNIX (Amazon VPC)").withStartTime(end);
DescribeSpotPriceHistoryResult response = client.describeSpotPriceHistory(request);
System.out.println(response.toString());
I obtained the result in json format but I receive it in String like:
{SpotPriceHistory: [{AvailabilityZone: us-east-1d,InstanceType: m1.xlarge,ProductDescription: Linux/UNIX,SpotPrice: 0.035000,Timestamp: Wed Nov 07 00:18:50 CET 2018}, {AvailabilityZone: us-east-1c,InstanceType: m1.xlarge,ProductDescription: Linux/UNIX,SpotPrice: 0.035000,Timestamp: Wed Nov 07 00:18:50 CET 2018}, {AvailabilityZone: us-east-1b,InstanceType: m1.xlarge,ProductDescription: Linux/UNIX,SpotPrice: 0.035000,Timestamp: Wed Nov 07 00:18:50 CET 2018}, {AvailabilityZone: us-east-1a,InstanceType: m1.xlarge,ProductDescription: Linux/UNIX,SpotPrice: 0.035000,Timestamp: Wed Nov 07 00:18:50 CET 2018}, {AvailabilityZone: us-east-1e,InstanceType: m1.xlarge,ProductDescription: Linux/UNIX,SpotPrice: 0.350000,Timestamp: Thu Sep 20 01:08:39 CEST 2018}]}
my question is: How can I improve the displaying of the results ? like
{
"Timestamp": "2018-09-08T17:07:14.000Z",
"AvailabilityZone": "us-east-1d",
"InstanceType": "p2.16xlarge",
"ProductDescription": "Linux/UNIX",
"SpotPrice": "4.320000"
},
{
"Timestamp": "2018-09-08T17:07:14.000Z",
"AvailabilityZone": "us-east-1c",
"InstanceType": "p2.16xlarge",
"ProductDescription": "Linux/UNIX",
"SpotPrice": "4.320000"
},
{
"Timestamp": "2018-09-08T17:07:14.000Z",
"AvailabilityZone": "us-east-1b",
"InstanceType": "p2.16xlarge",
"ProductDescription": "Linux/UNIX",
"SpotPrice": "4.320000"
},
{
"Timestamp": "2018-09-08T12:32:28.000Z",
"AvailabilityZone": "us-east-1e",
"InstanceType": "p2.16xlarge",
"ProductDescription": "Linux/UNIX",
"SpotPrice": "4.320000"
}
]
}

You're calling the .toString() on the response object, just be careful with this as there is no guarantee that will always be json, as you're seeing above, it's not even valid json as it's missing quotes around the attribute names and values.
One option to get what you want is to call response.getSpotPriceHistory() to get you the array of spot prices, then pass that thru ObjectMapper and write it as a pretty string, like so:
public static void main(String[] args) throws IOException {
AmazonEC2 client = AmazonEC2Client.builder().build();
DescribeSpotPriceHistoryRequest request = new DescribeSpotPriceHistoryRequest()
.withEndTime(new Date())
.withInstanceTypes("m1.xlarge").withProductDescriptions("Linux/UNIX (Amazon VPC)")
.withStartTime(new Date());
DescribeSpotPriceHistoryResult response = client.describeSpotPriceHistory(request);
ObjectMapper mapper = new ObjectMapper();
String asPrettyJSon = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(response.getSpotPriceHistory());
System.out.println(asPrettyJSon);
}

Both represent a json array containing jsonObjects of same structure.
Displaying result will depend on your front implementation not the layaout of your jsonRespense.

Related

Grails loosing time information of a Date when parsing JSON

My grails API is getting the time string but is loosing the seconds info.
I receive "16/02/2023 17:52:31" and results in a Date object with "16/02/2023 17:52:00"
class SampleObject {
static hasOne = [timeObject: TimeObject]
}
class TimeObject {
Date begin
Date end
static belongsTo = [sampleObject: SampleObject]
static constraints = {
begin nullable: true
end nullable: true
sampleObject nullable: false, unique: true
}
}
def controllerMethod() {
def bodyJSON = request.reader.text
def sampleObject = new SampleObject (JSON.parse(bodyJSON))
println sampleObject
}
In this sample above I send:
{
sampleObject: {
"begin": "16/02/2023 17:52:31",
"end": "16/02/2023 17:53:12"
}
}
Result:
begin= {Date#16875} "Thu Feb 16 17:52:00 BRT 2023"
end= {Date#16876} "Thu Feb 16 17:53:00 BRT 2023"
In my application.groovy I have:
grails.databinding.dateFormats = ['dd/MM/yyyy HH:mm', 'dd/MM/yyyy HH:mm:ss', 'yyyy-MM-dd HH:mm:ss.S', "yyyy-MM-dd'T'hh:mm:ss'Z'"]
PS: I'm using grails 3.1
The problem was in the "grails.databinding.dateFormats" order.
I solve changing to this:
grails.databinding.dateFormats = ['dd/MM/yyyy HH:mm:ss', 'dd/MM/yyyy HH:mm', 'yyyy-MM-dd HH:mm:ss.S', "yyyy-MM-dd'T'hh:mm:ss'Z'"]

Google Calendar API v3 always returns BadRequest when creating events

I created a shared calendar and want to add events to the calendar.
I created a project and set up a Service Account xxx#xxx.iam.gserviceaccount.com.
Then I shared the calendar to the Service Account as owner.
Then I noticed
Service Account must manually add shared calendar
as described here
https://stackoverflow.com/a/62232361/298430 and https://issuetracker.google.com/issues/148804709
So I wrote a code:
#Test
fun addCalendarToServiceAccount() {
val calList1: CalendarList = calendar.calendarList().list().execute()
logger.info("calList1 = {}", calList1)
val inserted = calendar.calendarList().insert(CalendarListEntry().setId(calendarId)).execute()
logger.info("inserted = {}", inserted)
val calList2: CalendarList = calendar.calendarList().list().execute()
logger.info("calList2 = {}", calList2)
}
It works perfectly. When first called, I can see calList1 is empty, and calList2 contains something.
Then I manually insert one event to the calendar (with google calendar WEB UI), I want to check if I can retrieve the event:
#Test
fun listEvents() {
val events: Events = calendar.events().list(calendarId).execute()
logger.info("events = {}", events)
events.items.forEachIndexed { index, e ->
logger.info("Event [index = {}] , event = {}", index, e)
}
}
It also works.
{
"accessRole":"owner",
"defaultReminders":[
],
"etag":"\"xxx\"",
"items":[
{
"created":"2020-08-17T17:51:21.000Z",
"creator":{
"email":"xxx#gmail.com"
},
"end":{
"date":"2020-08-20"
},
"etag":"\"xxx\"",
"htmlLink":"https://www.google.com/calendar/event?eid=xxx",
"iCalUID":"xxx#google.com",
"id":"xxx",
"kind":"calendar#event",
"organizer":{
"displayName":"xxx",
"email":"xxx#group.calendar.google.com",
"self":true
},
"reminders":{
"useDefault":false
},
"sequence":0,
"start":{
"date":"2020-08-19"
},
"status":"confirmed",
"summary":"xxx test1",
"transparency":"transparent",
"updated":"2020-08-18T01:07:54.441Z"
}
],
"kind":"calendar#events",
"nextSyncToken":"xxx",
"summary":"xxx",
"timeZone":"Asia/Taipei",
"updated":"2020-08-18T01:07:54.688Z"
}
Then I want to programmatically insert something, like the API example shows:
#Test
fun testInsertEvent() {
val now = LocalDateTime.now().withSecond(0).withNano(0)
val zoneId = ZoneId.of("Asia/Taipei")
val fromDate = Date.from(now.atZone(zoneId).toInstant())
val endDate = Date.from(now.plusMinutes(60).atZone(zoneId).toInstant())
val event = Event()
.setSummary("Google I/O 2015")
.setLocation("800 Howard St., San Francisco, CA 94103")
.setDescription("A chance to hear more about Google's developer products.")
.setStart(EventDateTime().setDate(DateTime(fromDate, TimeZone.getTimeZone(zoneId))))
.setEnd(EventDateTime().setDate(DateTime(endDate, TimeZone.getTimeZone(zoneId))))
logger.info("before insert event : {}", event)
val eventResult: Event = calendar.events().insert(calendarId, event).execute()
logger.info("eventResult = {}", eventResult)
}
I can see the client truly POST to google'e endpoint:
The body is:
{
"description":"A chance to hear more about Google's developer products.",
"end":{
"date":"2020-08-18T11:32:00.000+08:00"
},
"location":"800 Howard St., San Francisco, CA 94103",
"start":{
"date":"2020-08-18T10:32:00.000+08:00"
},
"summary":"Google I/O 2015"
}
But google just replied 400 BadRequest, without any further description:
2020-08-18 10:32:15.974 [main] INFO c.g.a.c.h.HttpResponse - -------------- RESPONSE --------------
HTTP/1.1 400 Bad Request
Transfer-Encoding: chunked
Alt-Svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
Server: ESF
X-Content-Type-Options: nosniff
Pragma: no-cache
Date: Tue, 18 Aug 2020 02:32:15 GMT
X-Frame-Options: SAMEORIGIN
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Vary: Referer
Vary: X-Origin
Vary: Origin
Expires: Mon, 01 Jan 1990 00:00:00 GMT
X-XSS-Protection: 0
Content-Type: application/json; charset=UTF-8
2020-08-18 10:32:15.980 [main] INFO c.g.a.c.u.LoggingByteArrayOutputStream - Total: 171 bytes
2020-08-18 10:32:15.980 [main] INFO c.g.a.c.u.LoggingByteArrayOutputStream - {
"error": {
"errors": [
{
"domain": "global",
"reason": "badRequest",
"message": "Bad Request"
}
],
"code": 400,
"message": "Bad Request"
}
}
I am using the same calendar instance, can successfully addCalendarToServiceAccount() (as owner) and listEvents().
But what goes wrong when inserting an event? Did I miss anything?
Other fields are initialized as follows:
#Value("\${google.calendar.id}")
private lateinit var calendarId: String
#Value("\${google.calendar.apiKey}")
private lateinit var apiKey : String
private val httpTransport: HttpTransport by lazy {
GoogleNetHttpTransport.newTrustedTransport()
}
private val jacksonFactory: JsonFactory by lazy {
JacksonFactory.getDefaultInstance()
}
private val saCredentials: GoogleCredentials by lazy {
javaClass.getResourceAsStream("/chancer-d1de03c4c25a.json").use { iStream ->
ServiceAccountCredentials.fromStream(iStream)
.createScoped(listOf(
"https://www.googleapis.com/auth/cloud-platform",
*CalendarScopes.all().toTypedArray()
))
}.apply {
refreshIfExpired()
}
}
private val requestInitializer: HttpRequestInitializer by lazy {
HttpCredentialsAdapter(saCredentials)
}
private val calendar: Calendar by lazy {
Calendar.Builder(httpTransport, jacksonFactory, requestInitializer)
.build()
}
Environments:
<java.version>1.8</java.version>
<kotlin.version>1.4.0</kotlin.version>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.30.10</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-calendar</artifactId>
<version>v3-rev20200610-1.30.10</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.21.1</version>
</dependency>
Answer:
You need to use start.dateTime and end.dateTime rather than start.date and end.date
Fix:
As per the documentation:
end.date: The date, in the format "yyyy-mm-dd", if this is an all-day event.
end.dateTime: The time, as a combined date-time value (formatted according to RFC3339). A time zone offset is required unless a time zone is explicitly specified in timeZone.
start.date: The date, in the format "yyyy-mm-dd", if this is an all-day event.
start.dateTime: The time, as a combined date-time value (formatted according to RFC3339). A time zone offset is required unless a time zone is explicitly specified in timeZone.
Therefore, you need to change your date & time setting method from:
EventDateTime().setDate(DateTime(fromDate, TimeZone.getTimeZone(zoneId))))
to:
EventDateTime().setDateTime(DateTime(fromDate, TimeZone.getTimeZone(zoneId))))
Which will change the request body to:
{
"description": "A chance to hear more about Google's developer products.",
"end": {
"dateTime": "2020-08-18T11:32:00.000+08:00" // modified
},
"location": "800 Howard St., San Francisco, CA 94103",
"start": {
"dateTime": "2020-08-18T10:32:00.000+08:00" // modified
},
"summary": "Google I/O 2015"
}
You can see the documentation for this method here.
References:
Events: insert | Calendar API | Google Developers
RFC 3339 - Date and Time on the Internet: Timestamps
EventDateTime (Calendar API v3-rev20200610-1.30.10)

jHipster: Search criteria "GreaterThan,LessThan" for date time

In my jHipster project I want to search row by datetime range.
The fragments of my code are:
product-inquiry-view.component.html
<div class="input-group date" id='datetimepicker'>
<input id="field_dateStart" #dateStart="ngbDatepicker" [(ngModel)]="criteriaByStartDate"/>
<input id="field_dateEnd" #dateEnd="ngbDatepicker" [(ngModel)]="criteriaByEndDate"/>
<button (click)="findByCriteria()"
</button>
</div>
Component class:
product-inquiry-view.component.ts
export class ProductInquiryViewComponent implements OnInit, OnDestroy {
criteriaByStartDate: string;
criteriaByEndDate: string;
..........
findByCriteria() {
criteriaByStartDate: Date;
criteriaByEndDate: Date;
let criteriaByStartDate = this.criteriaByStartDate;
let criteriaByEndDate = this.criteriaByEndDate
this.productInquiryViewService
.query({
'piDate.greaterThan': criteriaByStartDate,
'piDate.lessThan': criteriaByEndDate,
'piDocnum.contains': this.criteriaByDocnum
}).subscribe(
(res: HttpResponse<IProductInquiryView[]>) => {
this.productInquiryViews = res.body;
},
(res: HttpErrorResponse) => this.onError(res.message)
);
}
Controller:
ProductInquiryViewResource.java
#GetMapping("/product-inquiry-views")
#Timed
public ResponseEntity<List<ProductInquiryViewDTO>> getAllProductInquiryViews(ProductInquiryViewCriteria criteria) {
log.debug("REST request to get ProductInquiryViews by criteria: {}", criteria);
List<ProductInquiryViewDTO> entityList = productInquiryViewQueryService.findByCriteria(criteria);
return ResponseEntity.ok().body(entityList);
}
And I got exception:
2019-04-15 12:48:45.910 WARN 24330 --- [ XNIO-2 task-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by handler execution: org.springframework.validation.BindException:
org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'productInquiryViewCriteria' on field 'piDate.greaterThan': rejected value [Mon Apr 01 2019 00:00:00 GMT 0300]; codes
[typeMismatch.productInquiryViewCriteria.piDate.greaterThan,typeMismatch.piDate.greaterThan,typeMismatch.greaterThan,typeMismatch.java.time.ZonedDateTime,typeMismatch]; arguments
[org.springframework.context.support.DefaultMessageSourceResolvable: codes [productInquiryViewCriteria.piDate.greaterThan,piDate.greaterThan]; arguments [];
default message [piDate.greaterThan]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.ZonedDateTime'
for property 'piDate.greaterThan'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String]
to type [java.time.ZonedDateTime] for value 'Mon Apr 01 2019 00:00:00 GMT 0300'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [Mon Apr 01 2019 00:00:00 GMT 0300]] enter code here
I see that "Mon Apr 01 2019 00:00:00 GMT 0300" is not correst string for parsing to ZoneDateTime, so I tried send criteria in such format :
"2019-04-01T00:15:30+03:00[Europe/Moscow]";
Same result.
Should be :
this.productInquiryViewService
.query({
'piDate.greaterThan': criteriaByStartDate.toISOString(),
'piDate.lessThan': criteriaByEndDate.toISOString(),
...

how to split 1GB JSON file into multiple JSON object file each

I have a JSON file of size 1GB which contains n number of twitter JSON Object tweets.Now I want to split large JSON file into single JSON Object each. But in large file the JSON chunks are space separated but not comma separated.
INPUT :-
{
"created_at": "Tue Aug 06 06:01:00 +0000 2013",
"id": 364627145785487360,
"id_str": "364627145785487360",
"text": "Soo sad right now..",
"filter_level": "medium",
"lang": "en"
}
{
"created_at": "Tue Aug 06 06:01:00 +0000 2013",
"id": 364627145785487360,
"id_str": "364627145785487361",
"text": "الضمير صوت هادىء يخبرك بأن احدا ينظر اليك",
"lang": "en"
}
Now my OUTPUT has to be as shown below
OUTPUT: Test1.json
{
"created_at": "Tue Aug 06 06:01:00 +0000 2013",
"id": 364627145785487360,
"id_str": "364627145785487360",
"text": "Soo sad right now..",
"filter_level": "medium",
"lang": "en"
}
Test2.json
{
"created_at": "Tue Aug 06 06:01:00 +0000 2013",
"id": 364627145785487360,
"id_str": "364627145785487361",
"text": "الضمير صوت هادىء يخبرك بأن احدا ينظر اليك",
"lang": "en"
}
Can anyone help me out to get the above output JSON files i.e, Test1.json, Test2.json
given number of lines (7000 in this case):
command : jq -c -M '.data[]' | split -l 7000

Read a property from a DBObject [duplicate]

This question already has answers here:
MongoDB extracting values from BasicDBObject (Java)
(2 answers)
Closed 5 years ago.
I want to get an JSON array into a var in java. My JSON seems ok but when i try to put a JSOn array into a java array var it does not work.
here the error i get : errororg.json.JSONException: JSONObject["tweets"] is not a JSONArray.
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
DB db = mongoClient.getDB( "test1" );
DBCollection coll = db.getCollection("tweetsCol");
DBCursor cursor = coll.find();
while (cursor.hasNext()) {
BasicDBObject obj = (BasicDBObject) cursor.next();
JSONObject objjj = new JSONObject(obj);
try{
System.out.println("okok "+objjj); // THE JSON I WILL SHOW YOU
JSONArray jsonMainArr = objjj.getJSONArray("tweets");
}catch(JSONException e){
System.out.println("error"+e);
}}
Here's my data in MongoDB:
{
"_id":"5939bc6676abbe186feb73a5",
"user_request_id":"5941903f37aaa6ec55689e85",
"tweets":[
{
"date":"Wed Jun 07 18:32:57 CDT 2017",
"text":"[Earthview Wonders][Video] No.265: Astronaut Thomas Pesquet completed 6-month #MissionProxima. #Neweyes\u2026 ",
"_id":872597276891398144,
"user":"livearthjp"
},
{
"date":"Wed Jun 07 18:16:56 CDT 2017",
"text":"Astronaut Thomas Pesquet #Thom_astro Shares His #Songs4Space ",
"_id":872593245716467712,
"user":"anasia5mice"
},
{
"date":"Wed Jun 07 15:46:03 CDT 2017",
"text":"Thomas Pesquet: Undocking and landing ",
"_id":872555275387117570,
"user":"GRASSIFREE"
},
{
"date":"Wed Jun 21 17:02:37 CDT 2017",
"text":"#Thom_astro #Space_Station And his colleagues said, 'Pesquet, if you play Baker Street one more time...'",
"_id":877647972430823429,
"user":"kimkemmis"
},
{
"date":"Wed Jun 21 17:01:16 CDT 2017",
"text":"[News] ",
"_id":877647632524394497,
"user":"ArthurC2Pouce"
},
{
"date":"Wed Jun 21 11:28:48 CDT 2017",
"text":"Thomas Pesquet's music is OUT THERE! Cool dude. ",
"_id":877563967178104836,
"user":"tiarudd34"
},
{
"date":"Wed Jun 21 11:10:15 CDT 2017",
"text":"jaime thomas pesquet",
"_id":877559296741048320,
"user":"sosthene_maus"
},
{
"date":"Wed Jun 21 10:23:03 CDT 2017",
"text":"French astronaut Thomas Pesquet took some of the most amazing pictures ever while in spce ",
"_id":877547418606329861,
"user":"raygibbs1"
},
{
"date":"Wed Jun 21 10:23:00 CDT 2017",
"text":"French astronaut Thomas Pesquet shares stunning pictures of Earth: via #AOL",
"_id":877547405180157952,
"user":"raygibbs1"
},
{
"date":"Wed Jun 21 08:46:13 CDT 2017",
"text":"Coll Cambuston like Thomas Pesquet! #thomastro #cardierun",
"_id":877523048546676736,
"user":"CambF974"
},
{
"date":"Wed Jun 21 08:00:06 CDT 2017",
"text":"Thomas Pesquet returned to Earth on 2 June 2017 after completion of his six-months long Proxima mission to the... ",
"_id":877511443775619072,
"user":"rospaceagency"
},
{
"date":"Tue Jun 20 23:50:34 CDT 2017",
"text":"Thomas Pesquet #Thom_astro and Messier 83 #Astronauts #ESA #CNES #NASA ✨👨\u200d🚀✨ ",
"_id":877388248368033794,
"user":"AmirAliBehrooz"
}
],
"query_name":"Pesquet",
"active":"true",
"started_at":"2017_06_08"
}
Now I understand better your question thanks to #Neil Lunn, and following his best advice, you have to understand that you are not dealing here with Json, you can directly do:
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
DB db = mongoClient.getDB( "test1" );
DBCollection coll = db.getCollection("tweetsCol");
DBCursor cursor = coll.find();
while (cursor.hasNext()) {
BasicDBObject obj = (BasicDBObject) cursor.next();
try{
System.out.println("okok "+obj); // THE JSON I WILL SHOW YOU
BasicDBList jsonMainArr = obj.get("tweets");
}catch(JSONException e){
System.out.println("error"+e);
}}

Categories