Specific information from json string - java
I've been playing around with tweets in Eclipse for a while, which are presented as a json string.
To this end, I've created an object called Tweet (original, huh?) which takes certain information from the json string, and stores it in the Tweet object. Nothing fancy.
My Tweet class looks as follows:
public class Tweet implements TwitterMelding {
public Tweet() {
}
String created_at;
String id;
String text;
String user;
public void setUser(String user) {
this.user = user;
}
public void setText(String text) {
this.text = text;
}
public void setId(String id) {
this.id = id;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
}
Now, simple as it may look, there is one of those that doesn't work.
Specifically String user. What it's suppose to do, is store user ID of the person who posted the tweet.
The following is the tweet as obtained from Twitter in all it's horrible length:
{"created_at":"Sat Feb 08 15:37:37 +0000 2014","id":432176397474623489,"id_str":"432176397474623489","text":"Skal begynne \u00e5 selge vekter.. Eneste m\u00e5ten det konstant kommer penger i lommen","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":366301747,"id_str":"366301747","name":"skinny-pete","screen_name":"JFarsund","location":"bj\u00f8rge","url":null,"description":"j\u00f8rgen er en tynn gutt med pack.. Men det teller vel ikke? Det gj\u00f8r vel ikke bio heller","protected":false,"followers_count":427,"friends_count":291,"listed_count":2,"created_at":"Thu Sep 01 23:03:49 +0000 2011","favourites_count":5103,"utc_offset":3600,"time_zone":"Copenhagen","geo_enabled":true,"verified":false,"statuses_count":8827,"lang":"no","contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/pbs.twimg.com\/profile_background_images\/378800000089578611\/6840970475350d63190eb05d3d7e47ec.png","profile_background_image_url_https":"https:\/\/pbs.twimg.com\/profile_background_images\/378800000089578611\/6840970475350d63190eb05d3d7e47ec.png","profile_background_tile":true,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/431961396528414720\/EwkxQBkW_normal.jpeg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/431961396528414720\/EwkxQBkW_normal.jpeg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/366301747\/1391822743","profile_link_color":"0084B4","profile_sidebar_border_color":"FFFFFF","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":{"type":"Point","coordinates":[60.33700829,5.24626808]},"coordinates":{"type":"Point","coordinates":[5.24626808,60.33700829]},"place":{"id":"2260fcb4a77f2bad","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/2260fcb4a77f2bad.json","place_type":"city","name":"Bergen","full_name":"Bergen, Hordaland","country_code":"NO","country":"Norge","contained_within":[],"bounding_box":{"type":"Polygon","coordinates":[[[5.1602697,60.1848543],[5.1602697,60.5335445],[5.6866852,60.5335445],[5.6866852,60.1848543]]]},"attributes":{}},"contributors":null,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[],"symbols":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false,"filter_level":"medium","lang":"no"}
It really is a long eye-sore.
I've added a few "..." to the next one, to make it slightly more readable, only showing the value I'm interested in:
{…,"user":{"id":366301747,"id_str":"366301747","name":"skinny-pete","screen_name":"JFarsund","location":"bj\u00f8rge","url":null,"description":"j\u00f8rgen er en tynn gutt med pack.. Men det teller vel ikke? Det gj\u00f8r vel ikke bio heller","protected":false,"followers_count":427,"friends_count":291,"listed_count":2,"created_at":"Thu Sep 01 23:03:49 +0000 2011","favourites_count":5103,"utc_offset":3600,"time_zone":"Copenhagen","geo_enabled":true,"verified":false,"statuses_count":8827,"lang":"no","contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/pbs.twimg.com\/profile_background_images\/378800000089578611\/6840970475350d63190eb05d3d7e47ec.png","profile_background_image_url_https":"https:\/\/pbs.twimg.com\/profile_background_images\/378800000089578611\/6840970475350d63190eb05d3d7e47ec.png","profile_background_tile":true,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/431961396528414720\/EwkxQBkW_normal.jpeg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/431961396528414720\/EwkxQBkW_normal.jpeg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/366301747\/1391822743","profile_link_color":"0084B4","profile_sidebar_border_color":"FFFFFF","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null}, …}
Right, still with me?
As I mentioned above, what I want is the users ID, which I want assigned to the variable "user" in the Tweet object.
{…,"user":{"id":366301747,"id_str":"366301747",… }…}
All I want is to assign the number 366301747, to the variable "user" in my Tweet object.
But for the life of me, I cannot seem to.
To make sure the Tweet object gets the info it wants and not the info it doesn't, I am using a Jackson object:
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
So my question.
How do I tell Tweet to take the 366301747 number from my json string and assign it to the variable "user"?
I'd prefer it doable with Jackson alone, and not having to import more JARs than necessary.
Please forgive the wall of text.
It can be pretty straightforward with Gson library.
Since, you've already done the hard work of creating the pojo, by looking at your json you can validate that User is a valid json object and not a String value.
Hence, let's modify your pojo's (Tweet) user attribute a little with:
User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
Where User custom class is:
public class User {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Now just call the your Gson method to convert your object from the json (I stored the json to a file and read it through a BufferedReader):
public static void main(String[] args) throws FileNotFoundException {
Gson gson = new Gson();
BufferedReader br = new BufferedReader(new FileReader(
"json.txt"));
Tweet tweetObj = gson.fromJson(br, Tweet.class);
System.out.println(tweetObj.getUser().getId());
}
Output:
366301747
EDIT: Based on the comments, solution using jackson - 2 options
Keep newly created User class, the ObjectMapper code remains exactly the same and System.out.println(tweet.getUser().getId()) gets you the userid.
If User class is not to be used, change your Tweet to look like this:
Code:
public class Tweet {
String created_at;
String id;
String text;
Map<String, String> user;
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Map<String, String> getUser() {
return user;
}
public void setUser(Map<String, String> user) {
this.user = user;
}
}
And print the userid in the calling method as:
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Tweet tweet = mapper.readValue(br, Tweet.class);
System.out.println(tweet.getUser().get("id"));
Gets you:
366301747
You can change the setUser method to take a Map and set user.id manually:
public void setUser(Map<String, Object> props) {
user = props.get("id").toString();
}
Related
Variables are not coming up null during Postman call
Setting up an Java Postman call assigning values to the variables but its shows null. #PostMapping("/caStudents/student") public String generateSignedValue(#RequestBody StudentRequest studentRequest) throws Exception String signedValue=studentService.getSignedValue(studentRequest); return signedValue; My Pojo Student Class public class StudentRequest { String user; Long duration ; public String getPublicKey() { return publicKey; } public void setPublicKey(String publicKey) { this.publicKey = publicKey; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public Long getDuration() { return duration; } public void setDuration(Long duration) { this.duration = duration; } Postman Request {"studentRequest":[{"user":"admin","duration":19336}]}
your request body should be like this: {"user":"admin","duration":19336} because you are getting StudentRequest as RequestBody and it means you should send StudentRequest internal properties not containing StudentRequest it self in request , second problem is that your RequestBody contains singular object not array .
According to what you've given us your request should actually be { "user": "admin", "duration": 19336 } If you want to provide multiple student requests at once (within an array), then you're StudenRequest class should look somewhat like this: public class StudentRequest { List<StudentR>; // Getter and Setter or not in case you use lombok class StudenR { String user; Long duration ; } }
Jackson custom serializer and deserializer with conditions
I am unable to find the correct way to manipulate the casing of a value via a custom annotation that I can control conditionally. I have already looked into Jackson tutorials online with JsonFilters, Serialization, Deserialization - I have had most of them working but not with my desired outcome. Custom Serializer: public class CaseSerializer extends JsonSerializer<String> { private boolean myCheck; public CaseSerializer() { // default } public CaseSerializer(boolean myControl) { this.myCheck = myControl; } #Override public void serialize(String value, JsonGenerator generator, SerializerProvider provider) throws IOException { if (value != null) { if (myCheck) { generator.writeString(value.toUpperCase()); } else { generator.writeString(value); } } } } Person Model: public class Person { #JsonSerialize(using = CaseSerializer.class) private String title; private String firstName; private String lastName; public Person(String title, String firstName, String lastName) { this.title = title; this.firstName = firstName; this.lastName = lastName; } // getters, setters & toString } Usage: Person person = new Person("dr", "john", "doe"); SimpleModule module = new SimpleModule(); module.addSerializer(String.class,new CaseSerializer(true)); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(module); String titleShouldBeUpper = mapper.writeValueAsString(person); System.out.println(titleShouldBeUpper); From running the code provided I expect that the title field within the Person class to be uppercased and the other values to remain as they were. (CaseSerializer(true) meaning I want to uppercase the values) This is not the case as the code prints the following output: {"title":"dr","firstName":"JOHN","lastName":"DOE"} When I run the code with the CaseSerializer() without the boolean myControl set to true, the expected output is that none of the fields are uppercased. Which is what is happening: {"title":"dr","firstName":"john","lastName":"doe"} This means by default nothing will change. If I call the mapper with a true for case serialization I only want the fields where the JsonSerialize(using = CaseSerializer.class) is present. Any ideas?
Convert Json to List Java
I have a JSON array like this : [ {"_id": {"$oid":"57e9e4b1f36d281c4b330509"}, "user": "edmtdev" }, {"_id": {"$oid":"57e9e4cec2ef164375c4c292"}, "user": "admin1234" }, {"_id": {"$oid":"57ea1b0ac2ef164375c5ff1e"}, "username": "admin34" } ] This is my User.class, used to store all data: public class User{ private Id id; private String user; public Id getId() { return id; } public void setId(Id id) { this.id = id; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } } And my Id.class, used to store the ID: public class Id { private String $oid; public String get$oid() { return $oid; } public void set$oid(String $oid) { this.$oid = $oid; } } I am using GSON in Java to get my users as a List<User>: List<User> users = new ArrayList<User>(); Gson gson = new Gson(); Type listType = new TypeToken<List<User>>(){}.getType(); users = gson.fromJson(s,listType); The problem is, I get users with username but no ID, $oid is not registered. Can someone help me understanding what does not work in this piece of code ?
You must replace id in User class by: private Id _id; because your json is _id, not id. And your json string at the end is wrong, is user, not username
#SerializedName("_id") private Id id; This is another approach.You can use this above annotation also.
Mapping JSON into POJO using Gson
I have the following JSON to represent the server response for a salt request: { "USER": { "E_MAIL":"email", "SALT":"salt" }, "CODE":"010" } And i tried to map it with the following POJO: public class SaltPOJO { private String code = null; private User user = null; #Override public String toString() { return this.user.toString(); } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public class User { private String e_mail = null; private String salt = null; #Override public String toString() { return this.e_mail + ": " + this.salt; } public String getE_mail() { return e_mail; } public void setE_mail(String e_mail) { this.e_mail = e_mail; } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } } } Now everytime i do this: Gson gson = new Gson(); SaltPOJO saltPojo = gson.fromJson(json.toString(), SaltPOJO.class); Log.v("Bla", saltPojo.toString()); The saltPojo.toString() is null. How can i map my JSON into POJO using Gson? Is the order of my variables important for the Gson mapping?
Is the order of my variables important for the Gson mapping? No, that's not the case. How can i map my JSON into POJO using Gson? It's Case Sensitive and the keys in JSON string should be same as variable names used in POJO class. You can use #SerializedName annotation to use any variable name as your like. Sample code: class SaltPOJO { #SerializedName("CODE") private String code = null; #SerializedName("USER") private User user = null; ... class User { #SerializedName("E_MAIL") private String e_mail = null; #SerializedName("SALT") private String salt = null;
You don't have proper mapping between your getter and setter. If you change your json to something like below, it would work: { "user": { "email":"email", "salt":"salt" }, "code":"010" } If you are getting json form third party then unfortunately, you would have to change your pojo or you could use adapter.
Datastructure to store an nested element in JSON
I am modelling classes in Java to store a JSON , for a particular JSON "id":1, "firstName":"sample", "lastName":"person", "Books":{ "bookName":"gone with the wind" "isbn": 12345 } I created a class person with int id , String firstName etc... what would be the best way to store bookName , make a class Books with a String bookName and int isbn , how would I represent books in the person class , As an array? since books always has only one value is there a better way to represent it
For json serialization/deserialization, I suggest the jackson library.Here is my code,it works fine on my computer! I store the json in the file named json.data as following: {"id":1, "firstName":"sample", "lastName":"person", "books":[{"bookName":"gone with the wind","isbn":12345}] } And the code,I omitted the getter/setter to be short public class Book { private String bookName; private int isbn; } public class BookWriter { private String id; private String firstName; private String lastName; private Book[] books; } public class JSONTest { public static void main(String[] args) { try { ObjectMapper mapper = new ObjectMapper(); BookWriter writer=(BookWriter)mapper.readValue(new File("json.data"), BookWriter.class); for(Book book:writer.getBooks()) { System.out.println(book.getBookName()+","+book.getIsbn()); } } catch (Exception e) { e.printStackTrace(); } } }