Parsing JSON with Jackson return null - java

I'm training my self on java using API. The subject of my exercise is to ask google books API in order to take some infos about books. I use Jersey as a client and Jackson to parse the JSON.
My problem is that when i run the JerseyVolumeGet() , the response is this one :
Volume{title='null', numberOfPages=null, author='null'}
Why ? Where is my mistake ? I suspect i get wrong when parsing the JSON but don't see where exactly..
Here my getClass ( the search url is barcoded , it's not a problem for me)
public class JerseyVolumeGet {
public static void main(String[] args) {
try {
Client client = Client.create();
WebResource webResource = client
.resource("https://www.googleapis.com/books/v1/volumes?q=1984");
ClientResponse response = webResource.accept("application/json")
.get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Noob you Failed : HTTP error code : "
+ response.getStatus());
}
String output = response.getEntity(String.class);
// read from file, convert it to user class
ObjectMapper mapper = new ObjectMapper();
Volume volume = mapper.readValue(output, Volume.class);
// display to console
System.out.println(volume);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here the JSON result of my query :
{
"kind": "books#volumes",
"totalItems": 641,
"items": [
{
"kind": "books#volume",
"id": "RY8yQWeDVFYC",
"etag": "Lf0P50PVz9c",
"selfLink": "https://www.googleapis.com/books/v1/volumes/RY8yQWeDVFYC",
"volumeInfo": {
"title": "(1984).",
"subtitle": "",
"authors": [
"Guy Serbat",
"Jean Taillardat",
"Gilbert Lazard"
],
"publisher": "Peeters Publishers",
"publishedDate": "1984-01-01",
"description": "(Peeters 1984)",
"industryIdentifiers": [
{
"type": "ISBN_10",
"identifier": "2904685030"
},
{
"type": "ISBN_13",
"identifier": "9782904685033"
}
],
"readingModes": {
"text": false,
"image": true
},
"pageCount": 280,
"printType": "BOOK",
"categories": [
"Language Arts & Disciplines"
],
"contentVersion": "1.1.1.0.preview.1",
"imageLinks": {
"smallThumbnail": "http://bks9.books.google.fr/books?id=RY8yQWeDVFYC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://bks9.books.google.fr/books?id=RY8yQWeDVFYC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
},
"language": "fr",
"previewLink": "http://books.google.fr/books?id=RY8yQWeDVFYC&printsec=frontcover&dq=1984&hl=&cd=1&source=gbs_api",
"infoLink": "http://books.google.fr/books?id=RY8yQWeDVFYC&dq=1984&hl=&source=gbs_api",
"canonicalVolumeLink": "http://books.google.fr/books/about/1984.html?hl=&id=RY8yQWeDVFYC"
},
"saleInfo": {
"country": "FR",
"saleability": "NOT_FOR_SALE",
"isEbook": false
},
"accessInfo": {
"country": "FR",
"viewability": "PARTIAL",
"embeddable": true,
"publicDomain": false,
"textToSpeechPermission": "ALLOWED",
"epub": {
"isAvailable": false
},
"pdf": {
"isAvailable": false
},
"webReaderLink": "http://books.google.fr/books/reader?id=RY8yQWeDVFYC&hl=&printsec=frontcover&output=reader&source=gbs_api",
"accessViewStatus": "SAMPLE",
"quoteSharingAllowed": false
},
"searchInfo": {
"textSnippet": "(Peeters 1984)"
}
},
more items...
}
Then , i've a Volume.class like that :
#JsonIgnoreProperties(ignoreUnknown=true)
public class Volume {
#JsonProperty("title")
String title;
#JsonProperty("pageCount")
Integer pageCount;
#JsonProperty("authors")
String authors;
getters , setters and toString..

You need to model the full JSON structure, something like this:
public class BookData {
String kind;
Integer totalItems;
List<Item> items;
}
public class Item {
String kind;
String id;
//...
Volume volumeInfo;
}
Then you can use ObjectMapper to read the BookData:
BookData bookData = new ObjectMapper().readValue(output, BookData.class);
And pull out the Volume info from each Item in the BookData.

Related

MongoDB Autocomplete index doesn't get result

I have a collection which name called 'airport' and i have Atlas Auto Complete index you can see JSON config below.
{
"mappings": {
"dynamic": false,
"fields": {
"name": [
{
"type": "string"
},
{
"foldDiacritics": false,
"maxGrams": 7,
"minGrams": 2,
"type": "autocomplete"
}
]
}
}
}
and this is my Document record
{
"_id": {
"$oid": "63de588c7154cc3ee5cbabb2"
},
"name": "Antalya Airport",
"code": "AYT",
"country": "TR",
"createdDate": {
"$date": {
"$numberLong": "1675516044323"
}
},
"updatedDate": {
"$date": {
"$numberLong": "1675516044323"
}
},
"updatedBy": "VISITOR",
"createdBy": "VISITOR",
}
And This is my MongoDB Query
public List<Document> autoCompleteAirports(AutoCompleteRequest autoCompleteRequest) {
return database.getCollection(AIRPORT).aggregate(
Arrays.asList(new Document("$search",
new Document("index", "airportAutoCompleteIndex")
.append("text",
new Document("query", autoCompleteRequest.getKeyword())
.append("path", "name")
)))
).into(new ArrayList<>());
}
So, when i type "antalya" or "Antalya", this works. But when i type "Antaly" or "antal" there is no result.
Any solution ?
i tried change min and max grams settings on index

How to read nested Json file using request methods to create endpoints?

I have nested Json file, I would like to read specific objects from Json file using request methods. Mostly to make exacly endpoints I need. I'm trying even to read everything but it doesn't work.
So I need help with this, I mean how to read whole Json file, after that I think I can handle to make endpoints like I need :
/api/category/{categoryName}/books
I arleady tried something like this :
#GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody
Object getBeers() {
ClassPathResource resource = new ClassPathResource("static/books.json");
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(resource.getInputStream(), Object.class);
} catch (IOException e) {
e.printStackTrace();
}
return null; //also tried with path here
}
I have results like this:
(java.io.FileNotFoundException: class path resource [static/books.json] cannot be opened because it does not exist)
I tried write path in all other ways. Not working.
So I'm guessing I'm not doin' it right
Here is whole json if someone needs it:
https://pastebin.com/yruFS5SM
Below is part of my Json, after that it's repeating with similar objects.
{
"requestedUrl": "https://www.googleapis.com/books/v1/volumes?q=java&maxResults=40",
"items": [
{
"kind": "books#volume",
"id": "7tkN1CYzn2cC",
"etag": "pfjjxSpetIM",
"selfLink": "https://www.googleapis.com/books/v1/volumes/7tkN1CYzn2cC",
"volumeInfo": {
"title": "A Hypervista of the Java Landscape",
"publisher": "InfoStrategist.com",
"industryIdentifiers": [
{
"type": "ISBN_13",
"identifier": "9781592432172"
},
{
"type": "ISBN_10",
"identifier": "1592432174"
}
],
"readingModes": {
"text": true,
"image": true
},
"printType": "BOOK",
"maturityRating": "NOT_MATURE",
"allowAnonLogging": false,
"contentVersion": "1.0.1.0.preview.3",
"imageLinks": {
"smallThumbnail": "http://books.google.com/books/content?id=7tkN1CYzn2cC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://books.google.com/books/content?id=7tkN1CYzn2cC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
},
"language": "en",
"previewLink": "http://books.google.pl/books?id=7tkN1CYzn2cC&pg=PP1&dq=java&hl=&cd=1&source=gbs_api",
"infoLink": "http://books.google.pl/books?id=7tkN1CYzn2cC&dq=java&hl=&source=gbs_api",
"canonicalVolumeLink": "https://books.google.com/books/about/A_Hypervista_of_the_Java_Landscape.html?hl=&id=7tkN1CYzn2cC"
},
"saleInfo": {
"country": "PL",
"saleability": "NOT_FOR_SALE",
"isEbook": false
},
"accessInfo": {
"country": "PL",
"viewability": "PARTIAL",
"embeddable": true,
"publicDomain": false,
"textToSpeechPermission": "ALLOWED",
"epub": {
"isAvailable": true,
"acsTokenLink": "http://books.google.pl/books/download/A_Hypervista_of_the_Java_Landscape-sample-epub.acsm?id=7tkN1CYzn2cC&format=epub&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
},
"pdf": {
"isAvailable": true,
"acsTokenLink": "http://books.google.pl/books/download/A_Hypervista_of_the_Java_Landscape-sample-pdf.acsm?id=7tkN1CYzn2cC&format=pdf&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
},
"webReaderLink": "http://play.google.com/books/reader?id=7tkN1CYzn2cC&hl=&printsec=frontcover&source=gbs_api",
"accessViewStatus": "SAMPLE",
"quoteSharingAllowed": false
}
}

Use different class name than JSON with Jackson deserialization

I'm trying to deserialize a JSON file with Jackson and I want to use different names for objects. I know how to set the #JsonProperty annotation but this doesn't work for class names. An example:
public class _my_class {
#JsonProperty("my_variable")
private String myVariable;
}
I want the class to be named MyClass. I also tried to use #JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "MyClass") but it doesn't work too. Is there a solution to this?
EDIT
This is my simplified JSON file:
{
"CVE_data_type": "CVE",
"CVE_data_format": "MITRE",
"CVE_data_version": "4.0",
"CVE_data_numberOfCVEs": "1",
"CVE_data_timestamp": "2018-10-26T07:00Z",
"CVE_Items": [
{
"cve": {
"data_type": "CVE",
"data_format": "MITRE",
"data_version": "4.0",
"CVE_data_meta": {
"ID": "CVE-2018-0001",
"ASSIGNER": "my#mail.com"
},
"affects": {
"vendor": {
"vendor_data": [
{
"vendor_name": "myVendorName",
"product": {
"product_data": [
{
"product_name": "myProductName",
"version": {
"version_data": [
{
"version_value": "myVersionValue",
"version_affected": "myVersionAffected"
}
]
}
}
]
}
}
]
}
},
"problemtype": {
"problemtype_data": [
{
"description": [
{
"lang": "en",
"value": "myProblemtypeDescription"
}
]
}
]
},
"references": {
"reference_data": [
{
"url": "http://www.myReferenceDataUrl.com/",
"name": "myReferenceDataName",
"refsource": "myReferenceDataRefsource",
"tags": [
"myReferenceDataTagOne",
"myReferenceDataTagTwo"
]
}
]
},
"description": {
"description_data": [
{
"lang": "en",
"value": "myDescription"
}
]
}
},
"configurations": {
"CVE_data_version": "4.0",
"nodes": [
{
"operator": "OR",
"cpe": [
{
"vulnerable": true,
"cpe22Uri": "cpe:/o:this:is:a:cpe",
"cpe23Uri": "cpe:2.3:o:this:is:a:cpe:*:*:*:*:*:*",
"versionStartIncluding": "myVersionStartIncluding",
"versionStartExcluding": "myVersionStartExcluding",
"versionEndIncluding": "myVersionEndIncluding",
"versionEndExcluding": "myVersionEndExcluding"
},
{
"vulnerable": true,
"cpe22Uri": "cpe:/o:this:is:another:cpe",
"cpe23Uri": "cpe:2.3:o:this:is:another:cpe:*:*:*:*:*:*"
}
]
}
]
},
"impact": {
"baseMetricV3": {
"cvssV3": {
"version": "3.0",
"vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"availabilityImpact": "HIGH",
"baseScore": 9.8,
"baseSeverity": "CRITICAL"
},
"exploitabilityScore": 3.9,
"impactScore": 5.9
},
"baseMetricV2": {
"cvssV2": {
"version": "2.0",
"vectorString": "(AV:N/AC:L/Au:N/C:P/I:P/A:P)",
"accessVector": "NETWORK",
"accessComplexity": "LOW",
"authentication": "NONE",
"confidentialityImpact": "PARTIAL",
"integrityImpact": "PARTIAL",
"availabilityImpact": "PARTIAL",
"baseScore": 7.5
},
"severity": "HIGH",
"exploitabilityScore": 10.0,
"impactScore": 6.4,
"obtainAllPrivilege": false,
"obtainUserPrivilege": false,
"obtainOtherPrivilege": false,
"userInteractionRequired": false
}
},
"publishedDate": "2018-01-10T22:29Z",
"lastModifiedDate": "2018-02-23T02:29Z"
}
]
}
Now in want the corresponding class for the CVE Meta Data like this:
public class CVEDataMeta /* currently it's CVE_Data_Meta */ {
private String id;
private String assigner;
// getter and setters
}
EDIT 2
That's how i read the json file:
public CVE_Data deserialize(InputStream jsonStream) {
CVE_Data cveData = null;
ObjectMapper mapper = new ObjectMapper();
try {
cveData = mapper.readValue(jsonStream, CVE_Data.class);
} catch (...) {
...
}
return cveData;
}

The structure of my GeoJSON does not allow LeafLet to display the points on the layer

I am using the leaflet-ajax project (https://github.com/calvinmetcalf/leaflet-ajax) and I want to declare a geojsonLayer variable like this :
var geojsonLayer = L.geoJson.ajax("http://localhost:7070/findInArea");
where http://localhost:7070/findInArea is an endpoint to a Dropwizard REST web service that I coded.
Before trying to use http://localhost:7070/findInArea as a parameter I tried as parameter a JSON file containing what my REST web service returns :
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"imo": 0,
"course": "0.0",
"description": "description",
"mmsi": 432473000,
"type": "VESSEL",
"heading": "NaN"
},
"geometry": {
"type": "Point",
"coordinates": [-4.064533333333333, 5.29355]
}
}, {
"type": "Feature",
"properties": {
"imo": 0,
"course": "0.0",
"description": "description",
"mmsi": 375488000,
"type": "VESSEL",
"heading": "NaN"
},
"geometry": {
"type": "Point",
"coordinates": [-4.025521666666666, 5.303138333333333]
}
}, {
"type": "Feature",
"properties": {
"imo": 0,
"course": "0.0",
"description": "description",
"mmsi": 355794000,
"type": "VESSEL",
"heading": "NaN"
},
"geometry": {
"type": "Point",
"coordinates": [-4.01319, 5.28968]
}
}]
}
When I try with this JSON the points are not displayed on the layer. I searched on the Web an example of (Geo)JSON for which it works. On https://github.com/calvinmetcalf/leaflet-ajax/tree/gh-pages/example I found one which is :
{
"type":"FeatureCollection",
"features":[
{
"geometry":{
"type":"Point",
"coordinates":[
-71.123723098996251,
42.379003083976961
]
},
"type":"Feature",
"id":0,
"properties":{
"UNDERGRAD":43,
"CITYST":"Cambridge, MA",
"OBJECTID":72.0,
"URL":"http://www.longy.edu",
"TYPE":"PRI",
"DESCRIPTN":"4-year or above",
"NCES_ID":"166489",
"ZIPCODE":"02138",
"L_ACC_EST":16,
"SITE":"1",
"L_SRC_1":"nces.ed.gov",
"L_BASE":"DOQ",
"DEGREES":"C, M",
"L_TYPE":"CB",
"ADDRESS":"One Follen St",
"COLLEGE":"Longy School Of Music",
"L_METH":"IN-WEBSITE",
"GRAD":137,
"MAIN_TEL":"(617) 876-0956"
}
},
{
"geometry":{
"type":"Point",
"coordinates":[
-71.308156671517793,
42.643612284195882
]
},
"type":"Feature",
"id":1,
"properties":{
"UNDERGRAD":79,
"CITYST":"Lowell, MA",
"OBJECTID":73.0,
"URL":"http://www.lowellacademy.com",
"TYPE":"PRI",
"DESCRIPTN":"less-than-2-year",
"NCES_ID":"166498",
"ZIPCODE":"01852",
"L_ACC_EST":16,
"SITE":"1",
"L_SRC_1":"nces.ed.gov",
"L_BASE":"DOQ",
"DEGREES":"C",
"L_TYPE":"CB",
"ADDRESS":"136 Central St",
"COLLEGE":"Lowell Academy Of Hairdressing",
"L_METH":"IN-VERB",
"GRAD":0,
"MAIN_TEL":"(978) 453-3235"
}
}
]
}
Currently the Java code of my REST web service is :
#Override
public FeatureCollection findTracksInACertainArea(double longitudeMin, double longitudeMax, double latitudeMin, double latitudeMax){
FeatureCollection fc = new FeatureCollection();
List<Feature> features = new ArrayList<Feature>();
DBCursor cursor = null;
BasicDBObject query = new BasicDBObject();
query.put("detection.position.0", BasicDBObjectBuilder.start("$gte", longitudeMin).add("$lte", longitudeMax).get());
query.put("detection.position.1", BasicDBObjectBuilder.start("$gte", latitudeMin).add("$lte", latitudeMax).get());
cursor = collection.find(query);
while(cursor.hasNext()) {
final Track track = TrackDAOHelper.convertTrackFromDBObject(cursor.next());
features.add(buildFeature(track));
}
fc.setFeatures(features);
return fc;
}
private Feature buildFeature(Track track) {
Feature feature = new Feature();
Point point = new Point(track.getDetection().getPosition().getLongitude(), track.getDetection().getPosition().getLatitude());
feature.setGeometry(point);
Map<String, Object> properties = buildProperties(track);
feature.setProperties(properties);
return feature;
}
private Map<String, Object> buildProperties(Track track) {
Map<String, Object> properties = new HashMap<String, Object>();
if (track != null) {
if (track.getName() != null)
properties.put("name", track.getName());
properties.put("course", "0.0");
properties.put("heading", "NaN");
properties.put("type", "VESSEL");
if (track.getMmsi() != null)
properties.put("mmsi", track.getMmsi());
if (track.getImo() != null)
properties.put("imo", track.getImo());
if (track.getCallsign() != null)
properties.put("callsign", track.getCallsign());
String description = buildDescription();
properties.put("description", description);
}
return properties;
}
private String buildDescription() {
return "description";
}
How can I modify it in order to get a working (Geo)JSON?
It is not due to the JSON, it is due to the around Javascript code

How to get json value using GSON from json tree

I have a json such as below
{
"apiVersion": "v1",
"metadata": {
"status": {
"statusCode": 0
},
},
"stuff": [
{
"name": {
"text": "red"
},
"properties": [
{
"attributes": {
"shade": "dark"
},
"component": {
"id": "BA1",
}
"type": "Color"
}
]
},
{
"name": {
"text": "Toyota Camry"
},
"properties": [
{
"attributes": {},
"component": {
"id": "MS",
},
"type": "Vehicle"
}
]
},
]
}
I'm using GSON to parse the results like this:
Gson gson = new Gson();
JsonObject json = (JsonObject) gson.fromJson(in, JsonObject.class);
System.out.println(json.get("apiVersion").getAsString());
I can get the apiVersion but don't know how to get elements that are inside the json tree. For example, type...what if I want to output all the different type..in this case Color and Vehicle
I must be missing something here, but why can't you nest calls to getJsonObject? For example, to get the status code:
System.out.println(json.getAsJsonObject("metadata")
.getAsJsonObject("status")
.get("statusCode").getAsInt());
You can create an object in that matter and to parse the json to it (with GSON):
ParsedObject parsedObject = new Gson().fromJson(json, ParsedObject.class);
public class ParsedObject {
#SerializedName(value = "apiVersion")
private String mApiVersion;
#SerializedName(value = "metadata")
private Metadata mMetadata;
}

Categories

Resources