Render value without quotes from simple-json Object - json

I try to do in a Servlet:
JSONObject json = new JSONObject();
json.put( "eventContent", "event" );
String script = "var object= " + json.toJSONString() + ";";
response.getWriter().print( something + script + another );
The content of script is of course:
var object = {"eventContent":"event"};
But I render this String into a javascript function and try to refer a existent javascript object "event". So I need the value in the JSON Sting without quotes.
var object = {"eventContent":event};
any suggestions? :)
thanks a lot

I think it's not really JSON, since you should not refer variables. Anyway you can obtain what you need by implementing the JSONString interface, like this.
public static void main(String[] args) throws JSONException {
JSONObject json = new JSONObject();
json.put( "eventContent", new JSONVariable("event") );
System.out.println("var object= " + json.toString() + ";");
}
private static class JSONVariable implements JSONString { // implements JSONAware with com.googlecode.json-simple
private final String name;
public JSONVariable(String name) {
this.name = name;
}
#Override
public String toJSONString() {
return name;
}
}

Related

Passing JSON from Unity Application to Firebase function with onCall results as undefined

Hey why are Firebase Logs telling me that following data is undefined:
In unity i have following class:
public class Question
{
private string question;
private string answerA;
private string answerB;
private string answerC;
private string answerD;
private string rightAnswer;
public Question(string question, string answerA, string answerB, string answerC, string answerD, string rightAnswer)
{
this.question = question;
this.answerA = answerA;
this.answerB = answerB;
this.answerC = answerC;
this.answerD = answerD;
this.rightAnswer = rightAnswer;
}
}
When i click a button i create a object of Question and transform it into a JSON:
submitButton.onClick.AddListener(() =>
{
Question myQuestion = new Question(questionField.text, answerAField.text,
answerBField.text, answerCField.text, answerDField.text, rightAnswer.text);
string json = JsonUtility.ToJson(myQuestion);
firebaseManager.createQuestion(json);
});
finally i pass the JSON string to following function:
public void createQuestion(string json)
{
var function = FirebaseFunctions.DefaultInstance.GetHttpsCallable("createQuestion");
function.CallAsync(json).ContinueWithOnMainThread(task =>
{
if (task.IsCompleted)
Debug.Log("done");
});
}
My firebase function is just printing some fields of the JSON but the problem is that my firebase function says that the data is undefined:
exports.createQuestion = functions.https.onCall((data, context) => {
console.log(data.answerA);
console.log(data.answerB);
return 0;
});
When i use a Dictionary<string,object> instead of the JSON string then it is working but i wanna know why the JSON solution is not working?
SOLUTION
had to change the code on the server:
exports.createQuestion = functions.https.onCall((data, context) => {
var myObject = JSON.parse(data);
console.log(myObject.answerA);
console.log(myObject.answerB);
return 0;
});
Put this attribute on top of your data class
[System.Serializable]
Classes without that wont serialize.
Make the fields you want to serialize public, Private fields wont serialize.
[System.Serializable]
public class Question
{
public string question;
public string answerA;
public string answerB;
public string answerC;
public string answerD;
public string rightAnswer;
public Question(string question, string answerA, string answerB, string answerC, string answerD, string rightAnswer)
{
this.question = question;
this.answerA = answerA;
this.answerB = answerB;
this.answerC = answerC;
this.answerD = answerD;
this.rightAnswer = rightAnswer;
}
}

Convert JSON String to JSON

I am querying Postgres DB for retrieving JSONB format data using spring data JPA, which is stored like this in DB :
"{
"name":"abc",
"place"="xyz"
}"
but I am getting the response back with out double quotes, is there a way that I get the double quotes using spring data JPA or convert back to JSON with double quotes?
I tried new GSON().tJson() and ObjectMapper but no luck any help is appreciated.
Thanks
Your JSON object format is quite good and you should have no issue deserializing it back to a POJO.
Assuming your POJO class is named Template, here down a sample de-serialization implementation:
public class SerializationTest {
private static final String OBJECT = "{\n"
+ "\"name\":\"abc\",\n"+
"\"place\"=\"xyz\"\n"+
"}";
public static void main(String[] args) {
System.out.println("Serialized object:\n" + OBJECT);
Gson gson = new Gson();
Template template = gson.fromJson(OBJECT, Template.class);
System.out.println(template);
}
private static class Template {
private String name;
private String place;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
#Override
public String toString() {
return "Template{" +
"name='" + name + '\'' +
", place='" + place + '\'' +
'}';
}
}
}

How to parse JSON response from DuckDuckGo Answers API using Retrofit2?

I'm trying to obtain POJO instances using Gson and Retrofit2.
A typical JSON response looks like this.
My issue is with the Infobox field. In some cases, (like this) the field would be an object of the following type and an empty string otherwise.
class Infobox {
public List<Content> content = new ArrayList<>();
public List<Metum> meta;
}
class Content {
public String dataType;
public String value;
public String label;
public Integer wikiOrder;
}
class Metum {
public String dataType;
public String value;
public String label;
}
I tried writing a TypeAdapter as below
class InfoboxAdapter extends TypeAdapter<Infobox> {
final Gson embedded = new Gson();
#Override
public void write(JsonWriter out, Infobox infobox) throws IOException {
if (infobox == null) {
out.nullValue();
return;
}
out.beginObject();
out.name("content");
embedded.toJson(embedded.toJsonTree(infobox.content), out);
out.name("meta");
embedded.toJson(embedded.toJsonTree(infobox.meta), out);
out.endObject();
}
#Override
public Infobox read(JsonReader in) throws IOException {
if ("".equals(in.peek())) {
return null;
}
return embedded.fromJson(in, Infobox.class);
}
But it fails with java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING
The more confusing fact is that the field meta in the response, which is also an object, will in some cases have the value as null (and not an empty string like infobox)
I'd prefer to be able to do it using Gson as I've used it for everything else and I don't want to add another dependency
Hi Please go to :http://www.jsonschema2pojo.org/
paste your code. this sites automatically create your all related classes.
if issue please have a look at this link.
my drive link
I ended up using a JsonDeserializer. Google recommends:
New applications should prefer TypeAdapter, whose streaming API is more efficient than this interface's tree API.
But I didn't notice any performance impact for my use. I might someday rewrite this to use a TypeAdapter, but this works for me in till then
class InfoboxDeserialiser implements JsonDeserializer<Infobox> {
#Override
public Infobox deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
if (json.isJsonNull() || json.isJsonPrimitive()) {
return null;
}
JsonObject jsonObject = json.getAsJsonObject();
Infobox infobox = new Infobox();
JsonArray jsonContent = jsonObject.get("content").getAsJsonArray();
JsonArray jsonMeta = jsonObject.get("meta").getAsJsonArray();
infobox.content = new Content[jsonContent.size()];
for (int i = 0; i < jsonContent.size(); i++) {
infobox.content[i] = context.deserialize(jsonContent.get(i), Content.class);
}
infobox.meta = new Metum[jsonMeta.size()];
for (int i = 0; i < jsonMeta.size(); i++) {
infobox.meta[i] = context.deserialize(jsonContent.get(i), Metum.class);
}
return infobox;
} catch (Exception e) {
Timber.e(e, "Failed to deserialise the infobox");
return null;
}
}
}
Where the classes are as follows
class Metum {
public String dataType;
public String value;
public String label;
}
class Content {
public String dataType;
public String value;
public String label;
public Integer wikiOrder;
}
I register this deserializer while creating the service object
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Infobox.class, new InfoboxDeserialiser());
GsonConverterFactory converterFactory = GsonConverterFactory.create(gsonBuilder.create());
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("https://api.duckduckgo.com/")
.addConverterFactory(converterFactory);

JAX-RS/Jackson -- Deserialize JSON with Unknown Root Element Name?

I am writing a RESTeasy Proxy Client to consume Apple's API for retrieving their iTunes category list. When you query for information about a given category , for example with this URL:
https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres?id=1420
...you get a JSON response that looks like this:
{
"1420":{
"name":"Self-Help",
"id":"1420",
"url":"https://itunes.apple.com/us/genre/podcasts-health-self-help/id1420?mt=2",
"rssUrls":{
"topVideoPodcastEpisodes":"https://itunes.apple.com/us/rss/topvideopodcastepisodes/genre=1420/json",
"topAudioPodcasts":"https://itunes.apple.com/us/rss/topaudiopodcasts/genre=1420/json",
"topVideoPodcasts":"https://itunes.apple.com/us/rss/topvideopodcasts/genre=1420/json",
"topPodcasts":"https://itunes.apple.com/us/rss/toppodcasts/genre=1420/json",
"topAudioPodcastEpisodes":"https://itunes.apple.com/us/rss/topaudiopodcastepisodes/genre=1420/json",
"topPodcastEpisodes":"https://itunes.apple.com/us/rss/toppodcastepisodes/genre=1420/json"
},
"chartUrls":{
"videoPodcastEpisodes":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=VideoPodcastEpisodes",
"podcasts":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=Podcasts",
"audioPodcastEpisodes":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=AudioPodcastEpisodes",
"audioPodcasts":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=AudioPodcasts",
"podcastEpisodes":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=PodcastEpisodes",
"videoPodcasts":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=VideoPodcasts"
}
}
}
I am trying to map this JSON response to a Java object using JAXB and Jackson. However, the "1420" root element name seems to be causing a problem, as I get the following exception when calling my client:
Unrecognized field "1420" (class foo.bar.ITunesCategoryList), not marked as ignorable
My JAXB class looks like this:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class ITunesCategory implements TransferObject {
private static final long serialVersionUID = 3443545925023804457L;
#XmlElement(name = "id")
#JsonProperty("id")
private String identifier = null;
#XmlElement
private String name = null;
#XmlElementWrapper(name = "subgenres")
private List<ITunesCategory> subcategories = new ArrayList<ITunesCategory>();
...
}
I've even tried creating a wrapper class since the search could result in more than one category being returned. It looks like this:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class ITunesCategoryList implements TransferObject {
private static final long serialVersionUID = 3303125979016445238L;
#XmlElement
private List<ITunesCategory> categories = new ArrayList<ITunesCategory>();
...
}
However, regardless of which class I specify as my return type, I get the same error because the category identifier is the root element name of the JSON object.
Is there any way to tell JAXB/Jackson/JAX-RS/RESTeasy to ignore the root element name and just map the underlying object to Java? There is no way for me to know the root element name at develop/compile time, since it corresponds directly to the results returned by the search. Is there anything that can be done to get around this exception? Thanks for any help you can give!
I couldn't find much on dynamically ignoring the root, at least not anything that would be suitable in a JAX-RS environment. The only thing I could think is to write a custom deserializer, and just skip the root node. Something like
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Map;
public abstract class IHateRootElemsJsonDeserializer<T> extends JsonDeserializer<T> {
private final ObjectMapper mapper = new ObjectMapper();
private final Class<T> cls;
public IHateRootElemsJsonDeserializer(Class<T> cls) {
this.cls = cls;
}
#Override
public T deserialize(JsonParser jp, DeserializationContext dc)
throws IOException, JsonProcessingException {
JsonNode rootNode = jp.getCodec().readTree(jp);
Map.Entry<String,JsonNode> field = rootNode.fields().next();
JsonNode node = field.getValue();
T result = mapper.convertValue(node, cls);
return result;
}
}
Then just extend it with a concrete type.
public class GenreDeserializer extends IHateRootElemsJsonDeserializer<Genre>{
public GenreDeserializer() {
super(Genre.class);
}
}
Here's a test using the exact JSON you provided above
public class Test {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
GenreDeserializer deserializer = new GenreDeserializer();
SimpleModule module = new SimpleModule();
module.addDeserializer(Genre.class, deserializer);
mapper.registerModule(module);
Genre genre = mapper.readValue(JSON_FILE, Genre.class);
System.out.println(genre);
genre = mapper.readValue(JSON_FILE, Genre.class);
System.out.println(genre);
}
static final File JSON_FILE = new File("json.json");
}
The model
public class Genre {
public String id;
public String name;
public String url;
public RssUrls rssUrls;
public ChartUrls chartUrls;
#Override
public String toString() {
return "Category{" + "id=" + id + ", name="
+ name + ", url=" + url + ", rssUrls=" + rssUrls + '}';
}
public static class RssUrls {
public String topVideoPodcastEpisodes;
public String topAudioPodcasts;
public String topVideoPodcasts;
public String topPodcasts;
public String topAudioPodcastEpisodes;
public String topPodcastEpisodes;
#Override
public String toString() {
return "RssUrls{" + "topVideoPodcastEpisodes=" + topVideoPodcastEpisodes
+ ", topAudioPodcasts=" + topAudioPodcasts
+ ", topVideoPodcasts=" + topVideoPodcasts
+ ", topPodcasts=" + topPodcasts
+ ", topAudioPodcastEpisodes=" + topAudioPodcastEpisodes
+ ", topPodcastEpisodes=" + topPodcastEpisodes + '}';
}
}
public static class ChartUrls {
public String videoPodcastEpisodes;
public String podcasts;
public String audioPodcastEpisodes;
public String audioPodcasts;
public String podcastEpisodes;
public String videoPodcasts;
#Override
public String toString() {
return "ChatUrls{" + "videoPodcastEpisodes=" + videoPodcastEpisodes
+ ", podcasts=" + podcasts
+ ", audioPodcastEpisodes=" + audioPodcastEpisodes
+ ", audioPodcasts=" + audioPodcasts
+ ", podcastEpisodes=" + podcastEpisodes
+ ", videoPodcasts=" + videoPodcasts + '}';
}
}
}
To configure the ObjectMapper in JAX-RS, you can have a look at this post

Node.js equivalent for GSON Json creation?

I have a Java class in a servlet that uses GSON to render posted JSON Strings into a Java object. The beauty of the approach is, that GSON filters out all JSON elements that don't match a class property, so I never end up with JSON content that I don't want to process. The servlet's doPost (simplified) looks like this:
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
PrintWriter out = null;
try {
InputStream in = request.getInputStream();
Demo d = Demo.load(in);
in.close();
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
out = response.getWriter();
out.println(d.toJson);
} catch (Exception e) {
e.printStackTrace();
out.println(e.getMessage());
}
out.close();
}
The Demo class (and that's the one I need to recreate in common.js or node.js looks like this:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Demo implements Serializable {
public static Demo load(InputStream in) {
Demo result = null;
try {
Gson gson = new GsonBuilder().create();
result = gson.fromJson(new InputStreamReader(in), Demo.class);
} catch (Exception e) {
result = null;
}
return result;
}
#TypeDiscriminator
#JsonProperty("_id")
private String id = UUID.randomUUID().toString();
private Date created = new Date();
private String color;
private String name;
private String taste;
public String getColor() {
return this.color;
}
public String getName() {
return this.name;
}
public String getTaste() {
return this.taste;
}
public Date getCreated() {
return this.created;
}
public String getId() {
return this.id;
}
public void setName(String name) {
this.name = name;
}
public void setTaste(String taste) {
this.taste = taste;
}
public void setColor(String color) {
this.color = color;
}
public String toJson() {
GsonBuilder gb = new GsonBuilder();
gb.setPrettyPrinting();
gb.disableHtmlEscaping();
Gson gson = gb.create();
return gson.toJson(this);
}
}
Obviously I stripped out all the processing logic and the servlet just echos the JSON back, which is not what the app does, but serves to illustrate the point. I can throw pretty any String in a HTTP Post at that example and I only get valid Demo objects.
How would I do something like this in node.js?
Node.js is Javascript so has built in support for json. You can use JSON.parse to convert from string to json and wrap in try catch block.
To only include select properties there is no built in feature in node that I know of unless you are using Mongodb with mongoose, but you could do following: Have a "class" that is an object containing all properties that you want and delete those from parsed json object that are not in that "class" object.
var class = {x: null, y:null};
for(var prop in object){
if (!class.hasOwnProperty (prop)) {
delete object [prop]
}
It would be best to use this class as object and expose parseJSON function to encapsulate this functionality