I'm trying to implement a simple command-line Java app that requests some resources from a RESTful webservice. Is there a way to automatically deserialize JSON responses into my model classes?
In Objective-C there is Key-Value-Coding that allows you to create objects, access variables and methods by their string representation. This can be used to automatically deserialize an XML or JSON document into objects and this is done by some third party libraries, like RestKit.
Is there something similar for Java? I know I could use a JSON parser to get a array and map representation of the document and then create my model objects myself, but I was wondering if this could be automated?
I spent the entire evening yesterday searching for libraries, tutorials and user guides. All of them were either explaining how to build a RESTful webservice, or if it was a client app, all they ever did is download some JSON and print it to system out.
Look into Jackson
With this, you can create a class that "matches" your json data structure, and Jackson will automatically instantiate and populate the class for you. Then you're already integrated with the rest of your Java app.
Look into Google GSON, It is Google's Library for Marshaling/UnMarshaling JSON to Java and Java to JSON.
You can also look for its tutorial at http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/
Here an example, using XStream library: (http://x-stream.github.io/json-tutorial.html)
package com.thoughtworks.xstream.json.test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
public class ReadTest {
public static void main(String[] args) {
String json = "{\"product\":{\"name\":\"Banana\",\"id\":123"
+ ",\"price\":23.0}}";
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.alias("product", Product.class);
Product product = (Product)xstream.fromXML(json);
System.out.println(product.getName());
}
}
Related
I am working on an app that processes incoming Json's and I want to easily extract the json data and convert it to a DSL language I'v created using Xtext. My goal is to be able to later convert this data to a String that is based on my. I could probably just extract the data and manually add it to a big String variable ,but I want to do this programmatically. So ,does Xtext supports that. Is there any way to convert data to an Xtext object and later to a String (I am looking for something like json object classes)
Thanks!
If I correctly understand your question, you have already created an Xtext grammar that syntactically 'looks like' JSON.
In that case, the Xtext generated parser will be able to parse documents that follow the grammar specification (meaning they are both valid JSON and valid according to the grammar of your language).
The code that you would write looks as follows:
Package org.something.other
import com.google.inject.Injector;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.YourDSL.YourDSLStandaloneSetupGenerated;
public class ParseDocument {
public static void main(String[] args) throws IOException {
//First you use dependency injection to register the generated resource factory with EMF
Injector injector = new ourDSLStandaloneSetupGenerated().createInjectorAndDoEMFRegistration();
//Get a resource set object
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
//Register the generated EMF package
resourceSet.getPackageRegistry().put
(YourDSLPackage.eNS_URI, YourDSLPackage.eINSTANCE);
//Create an new resource with a suitable URI
Resource resource =
resourceSet.getResource(URI.createFileURI("./test.yourdsl"), true);
//You can now programmatically query and manipulate objects according to the metamodel of you DSL
MainClass root = (MainClass)resource.getContents().get(0);
}
That being said, an Xtext parser might be complete overkill depending on what you are trying to do and something like Jackson might be a better fit.
i want to ask about Retrofit 2.0
all this time, i knew Retrofit only with GSON Converter and get the object.
But i dont know how to get the data with API like this
https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty
i'm trying to display all top stories and get the object after i load all the top stories first.
i only know with old school style like this: http://pastebin.com/JMpwjH8H
I'm pretty sure for your example you can just set the response type as a list of Integers like this:
public interface ApiInterface {
#GET("topstories.json?print=pretty")
Call<List<Integer>> getTopStories();
}
Using a POJO would be too complex for what is essentially, just an array of Integers.
First of all, you should know whether it is POST web service or GET web service.
what parameters you will be giving to get the desired response and how would you store the response in POJO. This tutorial will help you with all basic thing that you require for integrating web services
I am writing a class that extends a class that uses Digester to parse an XML response from an API (Example existing class, code snipper below). After receiving the response, the code creates an object and adds specific methods on that.
Code snippet edited for brevity:
private Digester createDigester() {
Digester digester = new Digester();
digester.addObjectCreate("GeocodeResponse/result", GoogleGeocoderResult.class);
digester.addObjectCreate("GeocodeResponse/result/address_component", GoogleAddressComponent.class);
digester.addCallMethod("GeocodeResponse/result/address_component/long_name", "setLongName", 0);
...
digester.addSetNext("GeocodeResponse/result/address_component", "addAddressComponent");
Class<?>[] dType = {Double.class};
digester.addCallMethod("GeocodeResponse/result/formatted_address", "setFormattedAddress", 0);
...
digester.addSetNext("GeocodeResponse/result", "add");
return digester;
}
}
The API that I will be calling, however, only supports JSON. I have found a probable solution, which involves converting the JSON to XML and then running it through Digester, but that seems incredibly hackish.
public JsonDigester(final String customRootElementName) {
super(new JsonXMLReader(customRootElementName));
}
Is there a better way to do this?
This class is specifically meant to deal with XML as per the documentation:
Basically, the Digester package lets you configure an XML -> Java
object mapping module, which triggers certain actions called rules
whenever a particular pattern of nested XML elements is recognized. A
rich set of predefined rules is available for your use, or you can
also create your own.
Why would you think it would work with JSON?
Currently our application uses GWT-RPC for most client-server communication. Where this breaks down is when we need to auto generate images. We generate images based on dozens of parameters so what we do is build large complex urls and via a get request retrieve the dynamically built image.
If we could find a way to serialize Java objects in gwt client code and deserialize it on the server side we could make our urls much easier to work with. Instead of
http://host/page?param1=a¶m2=b¶m3=c....
we could have
http://host/page?object=?JSON/XML/Something Magicical
and on the server just have
new MagicDeserializer.(request.getParameter("object"),AwesomeClass.class);
I do not care what the intermediate format is json/xml/whatever I just really want to be able stop keeping track of manually marshalling/unmarshalling parameters in my gwt client code as well as servlets.
Use AutoBean Framework. What you need is simple and is all here http://code.google.com/p/google-web-toolkit/wiki/AutoBean
I've seen the most success and least amount of code using this library:
https://code.google.com/p/gwtprojsonserializer/
Along with the standard toString() you should have for all Object classes, I also have what's called a toJsonString() inside of each class I want "JSONable". Note, each class must extend JsonSerializable, which comes with the library:
public String toJsonString()
{
Serializer serializer = (Serializer) GWT.create(Serializer.class);
return serializer.serializeToJson(this).toString();
}
To turn the JSON string back into an object, I put a static method inside of the same class, that recreates the class itself:
public static ClassName recreateClassViaJson(String json)
{
Serializer serializer = (Serializer) GWT.create(Serializer.class);
return (ClassName) serializer.deSerialize(json, "full.package.name.ClassName");
}
Very simple!
I know that GWT has a good RPC support. But for various purposes I need to build this on my own:
1.) How can I convert a Bean Object (on the Client Side) like;
class MyPerson {
String name;
String getName();
void setName(String name);
//..
}
with GWT into a JSON String? (Ideally only using libraries that come officially from GWT/Google).
2.) Secondly, how can I send this generated JSON String from the Client side to any Server also using any GWT Client Logik. (Ideally only using libraries that come officially from GWT/Google).
I have searched a lot, but the examples never show how to send data but only to receive JSON data.
Thank you very much!!!
Jens
There's a nifty class called AutoBeanFactory that GWT will create for you, no third-party libs required. See http://google-web-toolkit.googlecode.com/svn-history/r9219/javadoc/2.1/com/google/gwt/editor/client/AutoBeanFactory.html
Once you have your AutoBeanFactory, you can use it like this:
producing JSON from an object of type SimpleInterface
AutoBean<SimpleInterface> bean = beanFactory.create(SimpleInterface.class, simpleInterfaceInstance);
String requestData = AutoBeanCodex.encode(bean).getPayload();
useRequestBuilderToSendRequestWhereverYouWant(requestData);
parsing JSON from an object of type SimpleInterface
SimpleInterface simpleInterfaceInstance = AutoBeanCodex.decode(beanFactory, SimpleInterface.class, responseText).as();
You can use RequestBuilder to send these requests without GWT-RPC or the RF stuff.
I recommend you use RestyGWT it makes JSON rest services work just like GWT RPC services.
Take a look at GWT's AutoBean framework, which can be used to create and receive JSON payloads. The RequestBuilder type can be used to send HTTP requests to the server.
You have also another solution which is 3rd party solution, maybe a second place solution but it can be also the first place.
The 3rd party called GSON and it's a project open source on google code.
You can find it here.
I used it and it's very good and very simple.