How to write a servlet program which consume both XML and JSON? - java

I am writing a servlet program, which aim to accept both xml and json, my request in json is this,
{"Symbol":["OLM","ASC"]}
and it is working well.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
Connection connection = null;
BufferedReader reader1 = request.getReader();
StringBuffer jb = new StringBuffer();
String line = null;
while ((line = reader1.readLine()) != null) {
jb.append(line);
}
String str = jb.toString();
JSONObject obj2 = null;
try {
obj2 = new JSONObject(str);
} catch (JSONException e1) {
e1.printStackTrace();
}
JSONArray array = null;
try {
array = (JSONArray) obj2.get("Symbol");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
I know that it is working for json because of I am casting the obtained string(in my case str) to JSONObject, but if I want to accept XML also and obtain Symbol from it, how to change this code?
Thanks in advance
Iam updating my question,
ObjectMapper objectMapper = new ObjectMapper();
if(request.getHeader("content-type")=="application/json") {
System.out.println("json ");
Symbol symbolContainerFromJson = objectMapper.readValue(request.getReader(), Symbol.class);
System.out.println(symbolContainerFromJson.getSymbolName());
}
else if (request.getHeader("content-type")=="application/xml") {
System.out.println("xml");
Symbol symbolContainerFromXml = new XmlMapper().readValue(request.getReader(), Symbol.class);
System.out.println(symbolContainerFromXml.getSymbolName());
}
But it is not entering both the loops, kindly help

The most robust way to deserialize is by creating the data structure in the back-end and let a framework like Jackson do the heavy lifting.
So we first create our object representation that we expect in either XML or JSON. No magic, it's just a POJO. I add a JsonProperty annotation because you expect Symbol upper-case and I hate upper-case fields in Java.
public class SymbolContainer {
#JsonProperty("Symbol")
private List<String> symbol;
public List<String> getSymbol() {
return symbol;
}
}
Then I use a Jackson Object/Xml mapper to transform the content from the request body to an in-memory object.
if(contentTypeIsJson(request.getHeader("content-type"))) {
SymbolContainer symbolContainerFromJson = new ObjectMapper().readValue("{\"Symbol\":[\"OLM\",\"ASC\"]}", SymbolContainer.class);
System.out.println(symbolContainerFromJson.getSymbol()); // [OLM, ASC]
} else if (contentTypeIsXml(request.getHeader("content-type"))) {
SymbolContainer symbolContainerFromXml = new XmlMapper().readValue("<root>\n" +
" <Symbol>\n" +
" <element>OLM</element>\n" +
" <element>ASC</element>\n" +
" </Symbol>\n" +
"</root>", SymbolContainer.class);
System.out.println(symbolContainerFromXml.getSymbol()); // [OLM, ASC]
}
This using only these three Jackson dependencies
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.5</version>
</dependency>
Note that these ObjectMappers can be configured. If you are only interested in a part of the request (eg Symbol) and want to ignore the rest of the passed object, best to configure your ObjectMapper like so, which lets you ignore unmapped fields.
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

Related

Generate json schema from POJO

I need to generate json schema from my POJOs. The requirement is that every POJO must be exported as a separate file and the references inside the json schema must be handled appropriately. It means that the library should keep track of which POJO is exported to which file. I found this library: https://github.com/mbknor/mbknor-jackson-jsonSchema and it works fine but it seems (or at least i cannot find such option) that i can't accomplish the requirements without custom coding. Do you know any other library that supports this?
You can use Jackson to generate the JSON schema using the following maven dependencies
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jsonSchema</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
You can then generate the schema by writing something like this
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
Reflections reflections = new Reflections("my.pojo.model",new SubTypesScanner(false));
Set<Class<?>> pojos = reflections.getSubTypesOf(Object.class);
Map<String, String> schemaByClassNameMap = pojos.stream()
.collect(Collectors.toMap(Class::getSimpleName, pojo -> getSchema(mapper, schemaGen, pojo)));
schemaByClassNameMap.entrySet().forEach(schemaByClassNameEntry->writeToFile(schemaByClassNameEntry.getKey(),schemaByClassNameEntry.getValue()));
}
private static void writeToFile(String pojoClassName, String pojoJsonSchema) {
try {
Path path = Paths.get(pojoClassName + ".json");
Files.deleteIfExists(path);
byte[] strToBytes = pojoJsonSchema.getBytes();
Files.write(path, strToBytes);
}catch (Exception e){
throw new IllegalStateException(e);
}
}
private static String getSchema(ObjectMapper mapper,JsonSchemaGenerator schemaGenerator,Class clazz){
try {
JsonSchema schema = schemaGenerator.generateSchema(clazz);
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);
}catch (Exception e){
throw new IllegalStateException(e);
}
}

Java: similar function to PHP:json_decode available? [duplicate]

This might be a dumb question but what is the simplest way to read and parse JSON from URL in Java?
In Groovy, it's a matter of few lines of code. Java examples that I find are ridiculously long (and have huge exception handling block).
All I want to do is to read the content of this link.
Using the Maven artifact org.json:json I got the following code, which I think is quite short. Not as short as possible, but still usable.
package so4308554;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import org.json.JSONException;
import org.json.JSONObject;
public class JsonReader {
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
}
public static void main(String[] args) throws IOException, JSONException {
JSONObject json = readJsonFromUrl("https://graph.facebook.com/19292868552");
System.out.println(json.toString());
System.out.println(json.get("id"));
}
}
Here are couple of alternatives versions with Jackson (since there are more than one ways you might want data as):
ObjectMapper mapper = new ObjectMapper(); // just need one
// Got a Java class that data maps to nicely? If so:
FacebookGraph graph = mapper.readValue(url, FaceBookGraph.class);
// Or: if no class (and don't need one), just map to Map.class:
Map<String,Object> map = mapper.readValue(url, Map.class);
And specifically the usual (IMO) case where you want to deal with Java objects, can be made one liner:
FacebookGraph graph = new ObjectMapper().readValue(url, FaceBookGraph.class);
Other libs like Gson also support one-line methods; why many examples show much longer sections is odd. And even worse is that many examples use obsolete org.json library; it may have been the first thing around, but there are half a dozen better alternatives so there is very little reason to use it.
The easiest way:
Use gson, google's own goto json library. https://code.google.com/p/google-gson/
Here is a sample. I'm going to this free geolocator website and parsing the json and displaying my zipcode. (just put this stuff in a main method to test it out)
String sURL = "http://freegeoip.net/json/"; //just a string
// Connect to the URL using java's native library
URL url = new URL(sURL);
URLConnection request = url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object.
String zipcode = rootobj.get("zip_code").getAsString(); //just grab the zipcode
If you don't mind using a couple libraries it can be done in a single line.
Include Apache Commons IOUtils & json.org libraries.
JSONObject json = new JSONObject(IOUtils.toString(new URL("https://graph.facebook.com/me"), Charset.forName("UTF-8")));
Maven dependency:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
I have done the json parser in simplest way, here it is
package com.inzane.shoapp.activity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
System.out.println(line);
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
System.out.println("error on parse data in jsonparser.java");
}
// return JSON String
return jObj;
}
}
this class returns the json object from the url
and when you want the json object you just call this class and the method in your Activity class
my code is here
String url = "your url";
JSONParser jsonParser = new JSONParser();
JSONObject object = jsonParser.getJSONFromUrl(url);
String content=object.getString("json key");
here the "json key" is denoted that the key in your json file
this is a simple json file example
{
"json":"hi"
}
Here "json" is key and "hi" is value
This will get your json value to string content.
Use HttpClient to grab the contents of the URL. And then use the library from json.org to parse the JSON. I've used these two libraries on many projects and they have been robust and simple to use.
Other than that you can try using a Facebook API java library. I don't have any experience in this area, but there is a question on stack overflow related to using a Facebook API in java. You may want to look at RestFB as a good choice for a library to use.
I have found this to be the easiest way by far.
Use this method:
public static String getJSON(String url) {
HttpsURLConnection con = null;
try {
URL u = new URL(url);
con = (HttpsURLConnection) u.openConnection();
con.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (con != null) {
try {
con.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
return null;
}
And use it like this:
String json = getJSON(url);
JSONObject obj;
try {
obj = new JSONObject(json);
JSONArray results_arr = obj.getJSONArray("results");
final int n = results_arr.length();
for (int i = 0; i < n; ++i) {
// get the place id of each object in JSON (Google Search API)
String place_id = results_arr.getJSONObject(i).getString("place_id");
}
}
It's very easy, using jersey-client, just include this maven dependency:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.25.1</version>
</dependency>
Then invoke it using this example:
String json = ClientBuilder.newClient().target("http://api.coindesk.com/v1/bpi/currentprice.json").request().accept(MediaType.APPLICATION_JSON).get(String.class);
Then use Google's Gson to parse the JSON:
Gson gson = new Gson();
Type gm = new TypeToken<CoinDeskMessage>() {}.getType();
CoinDeskMessage cdm = gson.fromJson(json, gm);
I wanted to add an updated answer here since (somewhat) recent updates to the JDK have made it a bit easier to read the contents of an HTTP URL.
Like others have said, you'll still need to use a JSON library to do the parsing, since the JDK doesn't currently contain one.
Here are a few of the most commonly used JSON libraries for Java:
org.JSON
FasterXML Jackson
GSON
To retrieve JSON from a URL, this seems to be the simplest way using strictly JDK classes (but probably not something you'd want to do for large payloads), Java 9 introduced: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/InputStream.html#readAllBytes()
try(java.io.InputStream is = new java.net.URL("https://graph.facebook.com/me").openStream()) {
String contents = new String(is.readAllBytes());
}
To parse the JSON using the GSON library, for example
com.google.gson.JsonElement element = com.google.gson.JsonParser.parseString(contents); //from 'com.google.code.gson:gson:2.8.6'
The Oracle Documentation describes how
an HttpRequest is built and then
sent by the HttpClient to the URL
in just a few lines of code, by using only the Java Class Library. Put this code into your main method:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com/"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
The response consists of a JSON object { ... } and can be further processed in your application.
Here I printed it to the console, just to confirm it works:
System.out.println(request);
This is available for Java Versions 11+
I am not sure if this is efficient, but this is one of the possible ways:
Read json from url use url.openStream() and read contents into a string.
construct a JSON object with this string (more at json.org)
JSONObject(java.lang.String source)
Construct a JSONObject from a source JSON text string.
Here's a full sample of how to parse Json content. The example takes the Android versions statistics (found from Android Studio source code here, which links to here).
Copy the "distributions.json" file you get from there into res/raw, as a fallback.
build.gradle
implementation 'com.google.code.gson:gson:2.8.6'
manifest
<uses-permission android:name="android.permission.INTERNET" />
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState != null)
return
thread {
// https://cs.android.com/android/platform/superproject/+/studio-master-dev:tools/adt/idea/android/src/com/android/tools/idea/stats/DistributionService.java
var root: JsonArray
Log.d("AppLog", "loading...")
try {
HttpURLConnection.setFollowRedirects(true)
val statsUrl = "https://dl.google.com/android/studio/metadata/distributions.json" //just a string
val url = URL(statsUrl)
val request: HttpURLConnection = url.openConnection() as HttpURLConnection
request.connectTimeout = 3000
request.connect()
InputStreamReader(request.content as InputStream).use {
root = JsonParser.parseReader(it).asJsonArray
}
} catch (e: Exception) {
Log.d("AppLog", "error while loading from Internet, so using fallback")
e.printStackTrace()
InputStreamReader(resources.openRawResource(R.raw.distributions)).use {
root = JsonParser.parseReader(it).asJsonArray
}
}
val decimalFormat = DecimalFormat("0.00")
Log.d("AppLog", "result:")
root.forEach {
val androidVersionInfo = it.asJsonObject
val versionNickName = androidVersionInfo.get("name").asString
val versionName = androidVersionInfo.get("version").asString
val versionApiLevel = androidVersionInfo.get("apiLevel").asInt
val marketSharePercentage = androidVersionInfo.get("distributionPercentage").asFloat * 100f
Log.d("AppLog", "\"$versionNickName\" - $versionName - API$versionApiLevel - ${decimalFormat.format(marketSharePercentage)}%")
}
}
}
}
As alternative to the dependency, you can also use this instead:
InputStreamReader(request.content as InputStream).use {
val jsonArray = JSONArray(it.readText())
}
and the fallback:
InputStreamReader(resources.openRawResource(R.raw.distributions)).use {
val jsonArray = JSONArray(it.readText())
}
The result of running this:
loading...
result:
"Ice Cream Sandwich" - 4.0 - API15 - 0.20%
"Jelly Bean" - 4.1 - API16 - 0.60%
"Jelly Bean" - 4.2 - API17 - 0.80%
"Jelly Bean" - 4.3 - API18 - 0.30%
"KitKat" - 4.4 - API19 - 4.00%
"Lollipop" - 5.0 - API21 - 1.80%
"Lollipop" - 5.1 - API22 - 7.40%
"Marshmallow" - 6.0 - API23 - 11.20%
"Nougat" - 7.0 - API24 - 7.50%
"Nougat" - 7.1 - API25 - 5.40%
"Oreo" - 8.0 - API26 - 7.30%
"Oreo" - 8.1 - API27 - 14.00%
"Pie" - 9.0 - API28 - 31.30%
"Android 10" - 10.0 - API29 - 8.20%

Any method of passing the Json data in URL format using JSONObject?

I create a java URL class which contain my Json data and have some function to obtain back my json data for doing some data comparison, I found out it's might not support by JSONObject for passing the data into the JSONObject. Do I need to use JSONArray in my case because my JSON data have array structure as well?
try
{
JSONObject obj = new JSONObject ();
obj.readJsonFromUrl(theUrl);
System.out.println(obj.toString());
}
catch(MalformedURLException e)
{
System.out.print("your problem here ...1");
}
}
else
{
System.out.print("Can't Connect");
}
I am sure that this is the place give me the error message because it return me this error in my compiler
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method readJsonFromUrl(URL) is undefined for the type JSONObject
there are also some warning message for that the JSONObject readJsonFromUrl method
private static JSONObject readJsonFromUrl(URL theUrl) throws IOException, JSONException {
Anyone can provide me the explaination of how the JSON data work in java? I saw quite number of Java class for JSON which make me confuse for it such as JSONObject, JSONArray , JSONValue. I search some information online but I also not very clear about it since I am very new to JSON data processing This is my sample json data and the data I need is scan_result only
{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"file_info":{
"display_name":"",
"file_size":242,
"file_type":"Not available",
"file_type_description":"Not available",
"md5":"aa69ba384f22d0dc0551ace2fbb9ad55",
"sha1":"09ceb54e65df3d3086b222e8643acffe451a6e8a",
"sha256":"dcb46d6ae2a187f789c12f19c44bbe4b9a43bd200a3b306d5e9c1fcf811dc430",
"upload_timestamp":"2016-11-18T09:09:08.390Z"
},
"process_info":{
"blocked_reason":"",
"file_type_skipped_scan":false,
"post_processing":{
"actions_failed":"",
"actions_ran":"",
"converted_destination":"",
"converted_to":"",
"copy_move_destination":""
},
"profile":"File scan",
"progress_percentage":100,
"result":"Allowed",
"user_agent":""
},
"scan_results":{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"progress_percentage":100,
"scan_all_result_a":"No Threat Detected",
"scan_all_result_i":0,
"scan_details":{
"Ahnlab":{
"def_time":"2016-11-08T15:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":1,
"threat_found":""
},
"Avira":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":133,
"threat_found":""
},
"ClamAV":{
"def_time":"2016-11-08T10:28:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":94,
"threat_found":""
},
"ESET":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":38,
"threat_found":""
}
},
"start_time":"2016-11-18T09:09:08.405Z",
"total_avs":4,
"total_time":250
},
"vulnerability_info":{
}
}
As mentioned here, there are many ways to solve this. Either you have to implement the read, parse operations yourself (#Roland Illig 's answer)
//you have to implement the readJSON method
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
Or you could use a library. The most well-known and widely used libraries are jackson and gson.
The big picture is that you try to "map" your json Object to a class.
You have your json file:
{
"id":1,
"name":"eirini",
"hobbies":["music","philosophy","football"]
}
and a class that represents this file and will store the values (depending on the library that you use there might be different requirements, for example getters, setters etc..)
public class Person {
public int id;
public String name;
public List<String> hobbies = new ArrayList<String>();
public String toString() {
return name +" has the id: " + id + " the following hobbies" + hobbies.get(0) + " " + hobbies.get(2);
}
}
Finally in your main method:
public static void main(String[] args) throws IOException, ParseException {
ObjectMapper mapper = new ObjectMapper();
InputStream input = this.getClass().getResourceAsStream(FILE); //read your file. There are many ways to achieve this.
ObjectMapper mapper = new ObjectMapper(); // just need one
Person eirini = mapper.readValue(input, Person.class);
System.out.println(eirini.toString());
You cannot pass json in url, you can pass it in body. Writing Json to stream body and post it using regular java method.
Here is oracle community url of explanation of your problem.
Required Jar can be downloaded from here.
Test Code Follows:
URL url = new URL("https://graph.facebook.com/search?q=java&type=post");
try (InputStream is = url.openStream();
JsonReader rdr = Json.createReader(is)) {
JsonObject obj = rdr.readObject();
JsonArray results = obj.getJsonArray("data");
for (JsonObject result : results.getValuesAs(JsonObject.class)){
System.out.print(result.getJsonObject("from").getString("name"));
System.out.print(": ");
System.out.println(result.getString("message", ""));
System.out.println("-----------");
}
}

Create JSONObject from POJO

I created a simple POJO:
public class LoginPojo {
private String login_request = null;
private String email = null;
private String password = null;
// getters, setters
}
After some searching I found this: JSONObject jsonObj = new JSONObject( loginPojo );
But with this I got the error:
The constructor JSONObject(LoginPojo) is undefined
I found another solution:
JSONObject loginJson = new JSONObject();
loginJson.append(loginPojo);
But this method does not exist.
So how can I convert my POJO into a JSON?
Simply use the java Gson API:
Gson gson = new GsonBuilder().create();
String json = gson.toJson(obj);// obj is your object
And then you can create a JSONObject from this json String, like this:
JSONObject jsonObj = new JSONObject(json);
Take a look at Gson user guide and this SIMPLE GSON EXAMPLE for more information.
It is possible to get a (gson) JsonObject from POJO:
JsonElement element = gson.toJsonTree(userNested);
JsonObject object = element.getAsJsonObject();
After that you can take object.entrySet() and look up all the tree.
It is the only absolutely free way in GSON to set dynamically what fields you want to see.
Jackson provides JSON parser/JSON generator as foundational building block; and adds a powerful Databinder (JSON<->POJO) and Tree Model as optional add-on blocks. This means that you can read and write JSON either as stream of tokens (Streaming API), as Plain Old Java Objects (POJOs, databind) or as Trees (Tree Model). for more reference
You have to add jackson-core-asl-x.x.x.jar, jackson-mapper-asl-x.x.x.jar libraries to configure Jackson in your project.
Modified Code :
LoginPojo loginPojo = new LoginPojo();
ObjectMapper mapper = new ObjectMapper();
try {
mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);
// Setting values to POJO
loginPojo.setEmail("a#a.com");
loginPojo.setLogin_request("abc");
loginPojo.setPassword("abc");
// Convert user object to json string
String jsonString = mapper.writeValueAsString(loginPojo);
// Display to console
System.out.println(jsonString);
} catch (JsonGenerationException e){
e.printStackTrace();
} catch (JsonMappingException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
Output :
{"login_request":"abc","email":"a#a.com","password":"abc"}
JSONObject input = new JSONObject(pojo);
This worked with latest version.
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
You can also use project lombok with Gson overriding toString function. It automatically includes builders, getters and setters in order to ease the data assignment like this:
User user = User.builder().username("test").password("test").build();
Find below the example class:
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.google.gson.Gson;
#Data
#Builder(toBuilder = true)
#AllArgsConstructor
#NoArgsConstructor
public class User {
/* User name. */
private String username;
/* Password. */
private String password;
#Override
public String toString() {
return new Gson().toJson(this, User.class);
}
public static User fromJSON(String json) {
return new Gson().fromJson(json, User.class);
}
}
Simply you can use the below solution:
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(loginPojo);
JSONObject jsonObject = new JSONObject(str);
I use jackson in my project, but I think that u need a empty constructor.
public LoginPojo(){
}
You can use
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.13</version>
</dependency>
To create a JSON object:
#Test
public void whenGenerateJson_thanGenerationCorrect() throws ParseException {
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < 2; i++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("AGE", 10);
jsonObject.put("FULL NAME", "Doe " + i);
jsonObject.put("DATE OF BIRTH", "2016/12/12 12:12:12");
jsonArray.add(jsonObject);
}
String jsonOutput = jsonArray.toJSONString();
}
Add the annotations to your POJO class like so:
#JSONField(name = "DATE OF BIRTH")
private String dateOfBirth;
etc...
Then you can simply use:
#Test
public void whenJson_thanConvertToObjectCorrect() {
Person person = new Person(20, "John", "Doe", new Date());
String jsonObject = JSON.toJSONString(person);
Person newPerson = JSON.parseObject(jsonObject, Person.class);
assertEquals(newPerson.getAge(), 0); // if we set serialize to false
assertEquals(newPerson.getFullName(), listOfPersons.get(0).getFullName());
}
You can find a more complete tutorial on the following site:
https://www.baeldung.com/fastjson

Simplest way to read JSON from a URL in Java

This might be a dumb question but what is the simplest way to read and parse JSON from URL in Java?
In Groovy, it's a matter of few lines of code. Java examples that I find are ridiculously long (and have huge exception handling block).
All I want to do is to read the content of this link.
Using the Maven artifact org.json:json I got the following code, which I think is quite short. Not as short as possible, but still usable.
package so4308554;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import org.json.JSONException;
import org.json.JSONObject;
public class JsonReader {
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
}
public static void main(String[] args) throws IOException, JSONException {
JSONObject json = readJsonFromUrl("https://graph.facebook.com/19292868552");
System.out.println(json.toString());
System.out.println(json.get("id"));
}
}
Here are couple of alternatives versions with Jackson (since there are more than one ways you might want data as):
ObjectMapper mapper = new ObjectMapper(); // just need one
// Got a Java class that data maps to nicely? If so:
FacebookGraph graph = mapper.readValue(url, FaceBookGraph.class);
// Or: if no class (and don't need one), just map to Map.class:
Map<String,Object> map = mapper.readValue(url, Map.class);
And specifically the usual (IMO) case where you want to deal with Java objects, can be made one liner:
FacebookGraph graph = new ObjectMapper().readValue(url, FaceBookGraph.class);
Other libs like Gson also support one-line methods; why many examples show much longer sections is odd. And even worse is that many examples use obsolete org.json library; it may have been the first thing around, but there are half a dozen better alternatives so there is very little reason to use it.
The easiest way:
Use gson, google's own goto json library. https://code.google.com/p/google-gson/
Here is a sample. I'm going to this free geolocator website and parsing the json and displaying my zipcode. (just put this stuff in a main method to test it out)
String sURL = "http://freegeoip.net/json/"; //just a string
// Connect to the URL using java's native library
URL url = new URL(sURL);
URLConnection request = url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object.
String zipcode = rootobj.get("zip_code").getAsString(); //just grab the zipcode
If you don't mind using a couple libraries it can be done in a single line.
Include Apache Commons IOUtils & json.org libraries.
JSONObject json = new JSONObject(IOUtils.toString(new URL("https://graph.facebook.com/me"), Charset.forName("UTF-8")));
Maven dependency:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
</dependency>
I have done the json parser in simplest way, here it is
package com.inzane.shoapp.activity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
System.out.println(line);
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
System.out.println("error on parse data in jsonparser.java");
}
// return JSON String
return jObj;
}
}
this class returns the json object from the url
and when you want the json object you just call this class and the method in your Activity class
my code is here
String url = "your url";
JSONParser jsonParser = new JSONParser();
JSONObject object = jsonParser.getJSONFromUrl(url);
String content=object.getString("json key");
here the "json key" is denoted that the key in your json file
this is a simple json file example
{
"json":"hi"
}
Here "json" is key and "hi" is value
This will get your json value to string content.
Use HttpClient to grab the contents of the URL. And then use the library from json.org to parse the JSON. I've used these two libraries on many projects and they have been robust and simple to use.
Other than that you can try using a Facebook API java library. I don't have any experience in this area, but there is a question on stack overflow related to using a Facebook API in java. You may want to look at RestFB as a good choice for a library to use.
I have found this to be the easiest way by far.
Use this method:
public static String getJSON(String url) {
HttpsURLConnection con = null;
try {
URL u = new URL(url);
con = (HttpsURLConnection) u.openConnection();
con.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (con != null) {
try {
con.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
return null;
}
And use it like this:
String json = getJSON(url);
JSONObject obj;
try {
obj = new JSONObject(json);
JSONArray results_arr = obj.getJSONArray("results");
final int n = results_arr.length();
for (int i = 0; i < n; ++i) {
// get the place id of each object in JSON (Google Search API)
String place_id = results_arr.getJSONObject(i).getString("place_id");
}
}
It's very easy, using jersey-client, just include this maven dependency:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.25.1</version>
</dependency>
Then invoke it using this example:
String json = ClientBuilder.newClient().target("http://api.coindesk.com/v1/bpi/currentprice.json").request().accept(MediaType.APPLICATION_JSON).get(String.class);
Then use Google's Gson to parse the JSON:
Gson gson = new Gson();
Type gm = new TypeToken<CoinDeskMessage>() {}.getType();
CoinDeskMessage cdm = gson.fromJson(json, gm);
I wanted to add an updated answer here since (somewhat) recent updates to the JDK have made it a bit easier to read the contents of an HTTP URL.
Like others have said, you'll still need to use a JSON library to do the parsing, since the JDK doesn't currently contain one.
Here are a few of the most commonly used JSON libraries for Java:
org.JSON
FasterXML Jackson
GSON
To retrieve JSON from a URL, this seems to be the simplest way using strictly JDK classes (but probably not something you'd want to do for large payloads), Java 9 introduced: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/InputStream.html#readAllBytes()
try(java.io.InputStream is = new java.net.URL("https://graph.facebook.com/me").openStream()) {
String contents = new String(is.readAllBytes());
}
To parse the JSON using the GSON library, for example
com.google.gson.JsonElement element = com.google.gson.JsonParser.parseString(contents); //from 'com.google.code.gson:gson:2.8.6'
The Oracle Documentation describes how
an HttpRequest is built and then
sent by the HttpClient to the URL
in just a few lines of code, by using only the Java Class Library. Put this code into your main method:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com/"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
The response consists of a JSON object { ... } and can be further processed in your application.
Here I printed it to the console, just to confirm it works:
System.out.println(request);
This is available for Java Versions 11+
I am not sure if this is efficient, but this is one of the possible ways:
Read json from url use url.openStream() and read contents into a string.
construct a JSON object with this string (more at json.org)
JSONObject(java.lang.String source)
Construct a JSONObject from a source JSON text string.
Here's a full sample of how to parse Json content. The example takes the Android versions statistics (found from Android Studio source code here, which links to here).
Copy the "distributions.json" file you get from there into res/raw, as a fallback.
build.gradle
implementation 'com.google.code.gson:gson:2.8.6'
manifest
<uses-permission android:name="android.permission.INTERNET" />
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState != null)
return
thread {
// https://cs.android.com/android/platform/superproject/+/studio-master-dev:tools/adt/idea/android/src/com/android/tools/idea/stats/DistributionService.java
var root: JsonArray
Log.d("AppLog", "loading...")
try {
HttpURLConnection.setFollowRedirects(true)
val statsUrl = "https://dl.google.com/android/studio/metadata/distributions.json" //just a string
val url = URL(statsUrl)
val request: HttpURLConnection = url.openConnection() as HttpURLConnection
request.connectTimeout = 3000
request.connect()
InputStreamReader(request.content as InputStream).use {
root = JsonParser.parseReader(it).asJsonArray
}
} catch (e: Exception) {
Log.d("AppLog", "error while loading from Internet, so using fallback")
e.printStackTrace()
InputStreamReader(resources.openRawResource(R.raw.distributions)).use {
root = JsonParser.parseReader(it).asJsonArray
}
}
val decimalFormat = DecimalFormat("0.00")
Log.d("AppLog", "result:")
root.forEach {
val androidVersionInfo = it.asJsonObject
val versionNickName = androidVersionInfo.get("name").asString
val versionName = androidVersionInfo.get("version").asString
val versionApiLevel = androidVersionInfo.get("apiLevel").asInt
val marketSharePercentage = androidVersionInfo.get("distributionPercentage").asFloat * 100f
Log.d("AppLog", "\"$versionNickName\" - $versionName - API$versionApiLevel - ${decimalFormat.format(marketSharePercentage)}%")
}
}
}
}
As alternative to the dependency, you can also use this instead:
InputStreamReader(request.content as InputStream).use {
val jsonArray = JSONArray(it.readText())
}
and the fallback:
InputStreamReader(resources.openRawResource(R.raw.distributions)).use {
val jsonArray = JSONArray(it.readText())
}
The result of running this:
loading...
result:
"Ice Cream Sandwich" - 4.0 - API15 - 0.20%
"Jelly Bean" - 4.1 - API16 - 0.60%
"Jelly Bean" - 4.2 - API17 - 0.80%
"Jelly Bean" - 4.3 - API18 - 0.30%
"KitKat" - 4.4 - API19 - 4.00%
"Lollipop" - 5.0 - API21 - 1.80%
"Lollipop" - 5.1 - API22 - 7.40%
"Marshmallow" - 6.0 - API23 - 11.20%
"Nougat" - 7.0 - API24 - 7.50%
"Nougat" - 7.1 - API25 - 5.40%
"Oreo" - 8.0 - API26 - 7.30%
"Oreo" - 8.1 - API27 - 14.00%
"Pie" - 9.0 - API28 - 31.30%
"Android 10" - 10.0 - API29 - 8.20%

Categories