Game class:
public class Game {
private String name;
private int steam_appid;
private boolean isInstalled;
}
Json example: https://store.steampowered.com/api/appdetails/?appids=435150&filters=basic
My attempt:
public static Game readJson(String gameID) throws IOException {
String targetURL = String.format(STEAM_API, gameID);
URL url = new URL(targetURL);
InputStreamReader reader = new InputStreamReader(url.openStream());
Gson gson = new Gson();
Game json = gson.fromJson(reader, Game.class);
return json;
}
When I tried to print the output, I get Name:null steam_appid:0 isInstalled:false
I want to check the key success first, if value is true parse it to Game. Otherwise, do nothing.
How can I parse the Json to my Game?
If a field is marked transient, (by default) it is ignored and not included in the JSON serialization or deserialization.
https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects
use below code if you don't want to include name in json:
public class Game
{
private transient String name;
private int steam_appid;
private boolean isInstalled;
}
Option 1:
Ignore Field at the Field Level
public class Game {
private String name;
#JsonIgnore
private int steam_appid;
private boolean isInstalled;
}
We can also ignore a field directly via the #JsonIgnore annotation directly on the field:
Option 2:
In another way you can use #JsonIgnoreProperties annotation to skip pojo properties. Here is the code snippet: You can use either way.
#JsonIgnoreProperties({ "name", "steam_appid" })
public class Game {
private String name;
private int steam_appid;
private boolean isInstalled;
}
Based on the response example the class to use Gson should look like this:
Note the classes need the getters and setters to be added.
class SteamResponseWrapper{
#SerializedName("434150")
private SteamResponse steamResponse;
}
class SteamResponse{
boolean success;
GameData data;
}
class GameData {
String name;
int steam_appid;
// I couldn't find the isInstalled property if you are adding it, make it transient
}
With this structure you would call:
SteamResponseWrapper wrapper = new Gson().fromJson(reader, SteamResponseWrapper.class)
and then
wrapper.getSteamResponse().isSuccess()
to check the success field.
And
wrapper.getSteamResponse().getData()
to access the game object.
But the problem I see is that the top object name is in fact data and will change for every game. So I don't think Gson will be able to handle this because for every request the annotated serialized name should be different.
I think you will be better of handling it with Jackson or as a JsonObject.
EDIT I
This example uses these maven dependencies:
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
The example:
public class SteamApiReader {
private static final String STEAM_API = "http:// ......";
public static void main(String args[]) {
try {
SteamApiReader.readJson("435150");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Game readJson(String gameID) throws IOException {
Game rtn = null;
String targetURL = String.format(STEAM_API, gameID);;
URL url = new URL(targetURL);
InputStreamReader reader = new InputStreamReader(url.openStream());
JsonReader jsonReader = Json.createReader(reader);
JsonStructure jsonStructure = jsonReader.read();
JsonObject jsonObject = (JsonObject) jsonStructure;
JsonObject wrapper = jsonObject.getJsonObject(gameID);
boolean success = wrapper.getBoolean("success");
if(success) {
JsonObject data = wrapper.getJsonObject("data");
String name = data.getString("name");
int steamAppId = data.getInt("steam_appid");
rtn = new Game(name, steamAppId);
}
return rtn;
}
public static class Game{
public Game(String name, int steamAppId) {
this.name = name;
this.steamAppId = steamAppId;
}
String name;
int steamAppId;
}
}
Related
I wanted to make new JSON object with org.json library, but I have noticed there is a problem with Java 14 records.
When I call
String json = new JSONObject(new Order("", "Albert", "GOOGL", "SELL", 97.9, 90L)).toString();
the fields are null.
I suppose it is because java record doesn't use old getters like getXYZ?
Is there a simple work around? I mean without using different library.
Or maybe my assumptions are incorrect.
public record Order(
String id,
String userId,
String securityId,
String type,
Double price,
Long quantity
) {
}
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20220320</version>
</dependency>
If you don't want to use other libraries like Jackson or Gson (it will be a much better solution in my opinion) you could write your own converter:
public final class JsonConverter {
private JsonConverter() {
}
#SneakyThrows
public static String toJSON(Object object) {
Class<?> c = object.getClass();
JSONObject jsonObject = new JSONObject();
for (Field field : c.getDeclaredFields()) {
field.setAccessible(true);
String name = field.getName();
Object value = field.get(object);
jsonObject.put(name, value);
}
return jsonObject.toString();
}
}
You could use it like:
public static void main(String[] args) {
Order order = new Order("", "Albert", "GOOGL", "SELL", 97.9, 90L);
System.out.println(order);
JSONObject jsonObject = new JSONObject(order);
System.out.println(jsonObject.toString());
System.out.println(JsonConverter.toJSON(order));
}
Output:
OrderRecord[id=, userId=Albert, securityId=GOOGL, type=SELL, price=97.9, quantity=90]
{}
{"quantity":90,"price":97.9,"securityId":"GOOGL","id":"","type":"SELL","userId":"Albert"}
It is a real workaround. However, it uses exactly org.json.
According to documentation JSONObject(Object bean) constructor
construct a JSONObject from an Object using bean getters.
So, yes as you noticed it expects getter to be in format getFieldName(), but in records getters are named differently.
For, example getter for filed price would be price(), not getPrice().
One possible solution is to add getters in record class, like this :
public record Order(
String id,
String userId,
String securityId,
String type,
Double price,
Long quantity
) {
public Double getPrice() { // Compliant
return price;
}
public String getId() { // Compliant
return id;
}
public String getSecurityId() { // Compliant
return securityId;
}
public String getType() { // Compliant
return type;
}
public Long getQuantity() { // Compliant
return quantity;
}
}
You should see output like this :
I have two object one is Dashboard and second is Room i have a json which is look like this
{
"hotel_id":"1",
"hotel_room":"200",
"hotel_properties":[{
"id":"1",
"room_type":"Single",
"rack_rate":"2000",
"publish_rate":"1800",
"discount":"10",
"availiable":"40",
"total":"50"
},
{
"id":"2",
"room_type":"Double",
"rack_rate":"4000",
"publish_rate":"3600",
"discount":"10",
"availiable":"45",
"total":"50"
}
]
}
And the Object is
public class DashBoard {
private int hotel_id;
private int hotel_room;
#JsonProperty("hotel_properties")
private Room hotel_properties;
}
There is another Object Room which is look like this
public class Room {
private Long id;
private String room_type;
private String rack_rate;
private String publish_rate;
private String discount;
private String availiable;
private String total;
}
I am Hide all constructor,setter and getter for Stackoverflow but it is in my code
i want parse Json to Object using ObjectMapper from an URL using this code
JsonReader jsonReader = new JsonReader();
ObjectMapper mapper = new ObjectMapper();
try {
JSONObject json = jsonReader.readJsonFromUrl("http://localhost/quinchy/json/dashboard.json");
DashBoard dsh = mapper.readValue(json.toString(), DashBoard.class);
System.out.println(json.toString());
} catch (IOException | JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but i get this error
org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of Object out of START_ARRAY token
please help me out from this
From the JSON String you posted, it looks like there is a list of Room objects. But you have used a single object.
In your DashBoard class, try changing:
private Room hotel_properties;
to:
private List<Room> hotel_properties;
I have a JSON object that looks like this
{
id:int,
tags: [
"string",
"string"
],
images: {
waveform_l:"url_to_image",
waveform_m:"url_to_image",
spectral_m:"url_to_image",
spectral_l:"url_to_image"
}
}
I'm trying to use retrofit to parse the JSON and create the interface. The problem that I have is that I get a null for the images urls. Everything else works, I am able to retrieve the id, the tags, but when I try to get the images they are all null.
I have a sound pojo that looks like this:
public class Sound {
private Integer id;
private List<String> tags = new ArrayList<String>();
private Images images;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Images getImages() {
return images;
}
public void setImages(Images images) {
this.images = images;
}
... setters and getter for tags as well
}
and I have a Images pojo that looks like this:
public class Images {
private String waveformL;
private String waveformM;
private String spectralM;
private String spectralL;
public String getWaveformL() {
return waveformL;
}
public void setWaveformL(String waveformL) {
this.waveformL = waveformL;
}
public String getWaveformM() {
return waveformM;
}
public void setWaveformM(String waveformM) {
this.waveformM = waveformM;
}
public String getSpectralM() {
return spectralM;
}
public void setSpectralM(String spectralM) {
this.spectralM = spectralM;
}
public String getSpectralL() {
return spectralL;
}
public void setSpectralL(String spectralL) {
this.spectralL = spectralL;
}
}
Whenever I try to call images.getWaveformM() it gives me a null pointer. Any ideas?
#SerializedName can also be used to solve this. It allows you to match the expected JSON format without having to declare your Class variable exactly the same way.
public class Images {
#SerializedName("waveform_l")
private String waveformL;
#SerializedName("waveform_m")
private String waveformM;
#SerializedName("spectral_m")
private String spectralM;
#SerializedName("spectral_l")
private String spectralL;
...
}
If the only differences from the JSON to your class variables are the snake/camel case then perhaps #njzk2 answer works better but in cases where there's more differences outside those bounds then #SerializeName can be your friend.
You possibly need this part:
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) will allow gson to automatically transform the snake case into camel case.
public class Images {
private String waveform_l;
private String waveform_m;
private String spectral_m;
private String spectral_m;
}
Key name should be same in model as in json other wise it won't recognise it else you haven't define it at GsonBuilder creation.Generate the getter setter for the same and you will be good to go
I just try to integrate with external webservice via JSON from Android. I receive following JSON format:
Data that i'm interested in is in "messages" branch.
To access data i'm using :
builder.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY);
Gson gson = builder.create();
ClassToStore response = gson.fromJson(reader, ClassToStore.class);
where reader is a input stream from:
am = getInstrumentation().getContext().getAssets();
am.open("data.json");
Message structure looks like:
ClassToStore has all fields with the same names.
I get all objects but all of theme are null's
PLEASE HELP :(
My classToStore:
public static class ClassToStore implements Serializable {
private static final long serialVersionUID = -1463052486583654136L;
public String id ;
public String replied_to_id ;
public String sender_id ;
public String created_at ;
public String getId() {
return id;
}
public String getReplied_to_id() {
return replied_to_id;
}
public String getSender_id() {
return sender_id;
}
public String getCreated_at() {
return created_at;
}
}
You will need an extra class to match the outer object:
public class OuterObject {
List<ClassToStore> messages;
}
And then load it like this:
Gson gson = new Gson();
Type type = new TypeToken<List<OuterObject>>(){}.getType();
List<OuterObject> outerList = gson.fromJson(reader, type);
List<ClassToStore> listOfMessages = outerlist.get(0).messages;
I want my JSON to look like this:
{
"information": [{
"timestamp": "xxxx",
"feature": "xxxx",
"ean": 1234,
"data": "xxxx"
}, {
"timestamp": "yyy",
"feature": "yyy",
"ean": 12345,
"data": "yyy"
}]
}
Code so far:
import java.util.List;
public class ValueData {
private List<ValueItems> information;
public ValueData(){
}
public List<ValueItems> getInformation() {
return information;
}
public void setInformation(List<ValueItems> information) {
this.information = information;
}
#Override
public String toString() {
return String.format("{information:%s}", information);
}
}
and
public class ValueItems {
private String timestamp;
private String feature;
private int ean;
private String data;
public ValueItems(){
}
public ValueItems(String timestamp, String feature, int ean, String data){
this.timestamp = timestamp;
this.feature = feature;
this.ean = ean;
this.data = data;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getFeature() {
return feature;
}
public void setFeature(String feature) {
this.feature = feature;
}
public int getEan() {
return ean;
}
public void setEan(int ean) {
this.ean = ean;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
#Override
public String toString() {
return String.format("{timestamp:%s,feature:%s,ean:%s,data:%s}", timestamp, feature, ean, data);
}
}
I just missing the part how I can convert the Java object to JSON with Jackson:
public static void main(String[] args) {
// CONVERT THE JAVA OBJECT TO JSON HERE
System.out.println(json);
}
My Question is: Are my classes correct? Which instance do I have to call and how that I can achieve this JSON output?
To convert your object in JSON with Jackson:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(object);
I know this is old (and I am new to java), but I ran into the same problem. And the answers were not as clear to me as a newbie... so I thought I would add what I learned.
I used a third-party library to aid in the endeavor: org.codehaus.jackson
All of the downloads for this can be found here.
For base JSON functionality, you need to add the following jars to your project's libraries:
jackson-mapper-asl
and
jackson-core-asl
Choose the version your project needs. (Typically you can go with the latest stable build).
Once they are imported in to your project's libraries, add the following import lines to your code:
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
With the java object defined and assigned values that you wish to convert to JSON and return as part of a RESTful web service
User u = new User();
u.firstName = "Sample";
u.lastName = "User";
u.email = "sampleU#example.com";
ObjectMapper mapper = new ObjectMapper();
try {
// convert user object to json string and return it
return mapper.writeValueAsString(u);
}
catch (JsonGenerationException | JsonMappingException e) {
// catch various errors
e.printStackTrace();
}
The result should looks like this:
{"firstName":"Sample","lastName":"User","email":"sampleU#example.com"}
Just follow any of these:
For jackson it should work:
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
//will return json in string
For gson it should work:
Gson gson = new Gson();
return Response.ok(gson.toJson(yourClass)).build();
You could do this:
String json = new ObjectMapper().writeValueAsString(yourObjectHere);
This might be useful:
objectMapper.writeValue(new File("c:\\employee.json"), employee);
// display to console
Object json = objectMapper.readValue(
objectMapper.writeValueAsString(employee), Object.class);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(json));
You can use Google Gson like this
UserEntity user = new UserEntity();
user.setUserName("UserName");
user.setUserAge(18);
Gson gson = new Gson();
String jsonStr = gson.toJson(user);
Well, even the accepted answer does not exactly output what op has asked for. It outputs the JSON string but with " characters escaped. So, although might be a little late, I am answering hopeing it will help people! Here is how I do it:
StringWriter writer = new StringWriter();
JsonGenerator jgen = new JsonFactory().createGenerator(writer);
jgen.setCodec(new ObjectMapper());
jgen.writeObject(object);
jgen.close();
System.out.println(writer.toString());
Note: To make the most voted solution work, attributes in the POJO have to be public or have a public getter/setter:
By default, Jackson 2 will only work with fields that are either
public, or have a public getter method – serializing an entity that
has all fields private or package private will fail.
Not tested yet, but I believe that this rule also applies for other JSON libs like google Gson.
public class JSONConvector {
public static String toJSON(Object object) throws JSONException, IllegalAccessException {
String str = "";
Class c = object.getClass();
JSONObject jsonObject = new JSONObject();
for (Field field : c.getDeclaredFields()) {
field.setAccessible(true);
String name = field.getName();
String value = String.valueOf(field.get(object));
jsonObject.put(name, value);
}
System.out.println(jsonObject.toString());
return jsonObject.toString();
}
public static String toJSON(List list ) throws JSONException, IllegalAccessException {
JSONArray jsonArray = new JSONArray();
for (Object i : list) {
String jstr = toJSON(i);
JSONObject jsonObject = new JSONObject(jstr);
jsonArray.put(jsonArray);
}
return jsonArray.toString();
}
}