Return JSON as string with Java - java

I have always used XML for returning data from my servlets and i have decided to have a go with JSON.Simple.
I currently have;
public JSONObject loadDetails() throws IOException {
JSONArray list = new JSONArray();
list.add(new Car("car1",3,4,3,2,4,5));
list.add(new Car("car2",3,4,3,2,4,5));
StringWriter out = new StringWriter();
list.writeJSONString(out);
System.out.println(out.toString());
return null;
}
I am trying to store some car details, however when i try and print i just get the object names rather than the correct JSON value. My car class implements JSONStreamAware eg;
public void writeJSONString (Writer out) throws IOException{
LinkedHashMap obj = new LinkedHashMap();
obj.put("carname", carname);
obj.put("engine", engine);
JSONValue.writeJSONString(obj, out);
}
Have i missed something here?

I am sorry, I know that this is not what you are explicitly asking for but I will definitely recommend using Gson for json parsing. You jsut specify several annotations and everything is magically serialized / deserialized. Read about gson here. Again sorry that this is not exact answer of the question, but still I hope it will help you get started in json.

Related

get a key value pair from a String json (simple object)

Im trying to get a key:value pair from a simple jsonString to add it after into a memory tab. If facing an issue cause my input is a string. and it looks like my loop isnot able to read the key value pair.
I read many topics about it, and im still in trouble with it. As you can see below
{"nom":"BRUN","prenom":"Albert","date_naiss":"10-10-1960","adr_email":"abrun#gmail.com","titre":"Mr","sexe":"F"}
and my method, find only on object... the result is the same in my loop
public static ArrayHandler jsonSimpleObjectToTab(String data) throws ParseException {
if( data instanceof String) {
final var jsonParser = new JSONParser();
final var object = jsonParser.parse(data);
final var array = new JSONArray();
array.put(object);
final var handler = new ArrayHandler("BW_funct_Struct");
for( KeyValuePair element : array) {
handler.addCell(element);
Log.warn(handler);
}
return handler;
} else {
throw new IllegalArgumentException("jsonSimpleObjectToTab: do not support complex object" + data + "to Tab");
}
}
i also tryed before to type my array as a List, Object etc, without the keyValuePair object, i would appreciate some help.
Thanks again dear StackOverFlowers ;)
You can try this :
const json = '{"nom":"BRUN","prenom":"Albert","date_naiss":"10-10-1960","adr_email":"abrun#gmail.com","titre":"Mr","sexe":"F"}';
map = new Map();
const obj = JSON.parse(json,(key,value) => {
map.set(key,value)
});
and you'll have every pair stored in map
Simply split the whole line at the commas and then split the resulting parts at the colon. This should give you the individual parts for your names and values.
Try:
supposing
String input = "\"nom\":\"BRUN\",\"prenom\":\"Albert\"";
then
String[] nameValuePairs = input.split(",");
for(String pair : nameValuePairs)
{
String[] nameValue = pair.split(":");
String name = nameValue[0]; // use it as you need it ...
String value = nameValue[1]; // use it as you need it ...
}
You can use TypeReference to convert to Map<String,String> so that you have key value pair.
String json = "{\"nom\":\"BRUN\",\"prenom\":\"Albert\",\"date_naiss\":\"10-10-1960\",\"adr_email\":\"abrun#gmail.com\",\"titre\":\"Mr\",\"sexe\":\"F\"}";
ObjectMapper objectMapper = new ObjectMapper();
TypeReference<Map<String,String>> typeReference = new TypeReference<Map<String, String>>() {
};
Map<String,String> map = objectMapper.readValue(json, typeReference);
I just answered a very similar question. The gist of it is that you need to parse your Json String into some Object. In your case you can parse it to Map. Here is the link to the question with my answer. But here is a short version: you can use any Json library but the recommended ones would be Jackson Json (also known as faster XML) or Gson(by Google) Here is their user guide site. To parse your Json text to a class instance you can use ObjectMapper class which is part of Jackson-Json library. For example
public <T> T readValue(String content,
TypeReference valueTypeRef)
throws IOException,
JsonParseException,
JsonMappingException
See Javadoc. But also I may suggest a very simple JsonUtils class which is a thin wrapper over ObjectMapper class. Your code could be as simple as this:
Map<String, Object> map;
try {
map = JsonUtils.readObjectFromJsonString(input , Map.class);
} catch(IOException ioe) {
....
}
Here is a Javadoc for JsonUtils class. This class is a part of MgntUtils open source library written and maintained by me. You can get it as Maven artifacts or from the Github

Unable to retrieve data from POST request

I am working in JAVA 1.8 to write and using Apache Tomcat to run the server, I am unable to retrieve data from a POST request i.e in JSON.
I actually need it in an HashMap and I can even parse and convert it into HashMap even if it is readable in JSON. I have tried several links on the internet and I always get exception like Could not deserialize to type interface PACKAGE NAME.
#POST
#Produces("application/json")
#Consumes("application/json")
#Path("ClassifyCase")
public Rules Classify(HttpServletRequest request) {
StringBuffer jb = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null)
jb.append(line);
} catch (Exception e) { System.out.println("Buffer Reader Error"); }
System.out.println("What I read: "+jb);
System.out.println("Here la la l ala ");
// System.out.println("Case: ++ "+Case.toString());
System.out.println("Here la la l ala ");
Rules foundRule = new Rules();
// List<Rules> objListRules = new ArrayList<Rules>();
try
{
DataAccessInterface objDAInterface = new RuleDataAdapter();
AbstractDataBridge objADBridge = new DatabaseStorage(objDAInterface);
// foundRule = objADBridge.Classify(Case);
logger.info("Classification done!");
}
catch(Exception ex)
{
logger.info("Error in classification");
System.out.println("Couldnt Classify Properly!");
// return
}
return foundRule;
}
Can someone please share a guide on how can I receive this data and convert it into a Map or either I can directly get a Map!
I strongly recommend you to use this library of JSON..
You can find it in Maven Repository and it's so easy to parse a JSON to a Map or to a JSONArray or JSONObject... depends of your necessity what you want to do..
Here is a example show how to parse a JSON to a HashMap
Map<String, Object> map = new JSONObject(--JSONString here--).toMap();
And that's all...
Now, if your JSON has a list of objects, i mean like a list of maps, what you just need to do is this...
JSONArray jsonArray = new JSONArray(--JSON string here--);
for(int i = 0; i < jsonArray.length(); i++){
Map<String, Object> map = jsonArray.getJSONObject(i).toMap();
}
Here is the explanation.
You take you JSON string and pass it as a parameter to the JSONArray,what JSONArray does is, take your json string a parse it to like a list
Then you make a for to get each Object of that list and parse it to a map.
Note: what the JSONObject does, is take the object of the JSONArray and parse it... you can parse it to a map or you can get each object of that map..
String jsonString = "{\n" +
"\t\"1\": \"1\",\n" +
"\t\"FPG\": \"50\",\n" +
"\t\"Symptoms\": \"Yes\"\n" +
"}";
Map<String, String> map = new Gson().fromJson(jsonString, Map.class);
for (String key: map.keySet()) {
System.out.println(map.get(key));
}
The request you send does not contain proper JSON in the body. You are missing the commas ",". It should be something like this:
{
"1":"1",
"FPG":"50",
"Symptoms":"yes"
}
Just change it and give proper JSON format to the message.
Even if the request was not in your control, I would strongly suggest that you contacted the service that creates the message and asked from them to fix it.
It would be the last resort for me to make my own deserializer to handle an "inproper" message.
An easy way to check if your JSON is properly formated is an online formatter, e.g. https://jsonformatter.org/

How to modularize the code for JsonObject and JsonArray to read Json files at class level. Which I am using later to write Testcases

I am using GSON library to read JSON file for my automation. For which I need to read file and then create a object of json while traversing the JSON.
Later I am using these objects to to modify the JSON..
I want to reduce the code for traversing down the json as many objects are getting created.
Though this works perfectly fine. Just I need to modularize the code.
Adding the code with the URL , Response and User JSON
Url.json
{"emplyee":
{"addemplyee": "<URL>/emplyee","addemplyee": "<URL>/editemplyee"}
}
Response .json
[
{"success":true},
{"success":false}
]
emplyee.json
{
"addemplyee":
{"details":{
"lst":"lastname",
"id":"username",
"Password":"password"
}
},
"editemplyee":
{ "details":{
"Password":"password"
}}}
Actual
Currently I am creating multiple objects to read ths jOSN file and later with the use of same I am updating my JSON.
Expected
Can I modularize this approach of code.
Yes you can:
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); //you can reuse gson as often as you like
public <T> static T readJson(String file){
try{
FileReader fr = new FileReader(new File(file)); //gson takes a filereader no need to load the string to ram
T t = GSON.fromJson(fr, T.getClass());
fr.close(); //close the reader
return t;
}catch(Error e){
//ignore or print, if you need
}
}

Faster object json convertor

I have written a program which inserts in bulk to Elasticsearch in batch of around 3000. The problem is that I need to convert these object to json before executing the bulk insert request. But there is major downside with json convertion and it is becoming a bottle neck of my whole computation.
Can any one suggest a super fast way to convert object to json in java. My code looks like this:
private String getESValueAsString(ElasticSearchValue elasticSearchValue) throws JsonProcessingException {
ElasticSearchValue prevValue = null;
if (stateType == StateType.OPAQUE) {
prevValue = (ElasticSearchValue) elasticSearchValue.getPrevious();
}
elasticSearchValue.setPrevious(null);
ObjectMapper om = new ObjectMapper();
Map<String, Object> props = om.convertValue(elasticSearchValue, Map.class);
if (stateType == stateType.OPAQUE) {
props.put("previous", prevValue);
}
return om.writeValueAsString(props);
}
Just found the issue, I am creating too many ObjectMapper for each serialization and that is making my whole processing slow.
This is a very good guide and it improved my performance 100x
http://wiki.fasterxml.com/JacksonBestPracticesPerformance
why not just insert into BulkRequestBuilder json records in the first place, something like this
Client client = new TransportClient().addTransportAddress(new InetSocketTransportAddress("localhost", 9300));
BulkRequestBuilder bulk = client.prepareBulk();
.....
bulk.add(client.prepareIndex(<your index>, <your type>)
.setSource(<your object>.toJson());
....
and in <your object> class
create Gson like this:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
and method:
public String toJson(){
return gson.toJson(this, <you class>.class);
}

Streaming a json element

Let's say I have a json that looks like this:
{"body":"abcdef","field":"fgh"}
Now suppose the value of the 'body' element is huge(~100 MB or more). I would like to stream out the value of the body element instead of storing it in a String.
How can I do this? Is there any Java library I could use for this?
This is the line of code that fails with an OutOfMemoryException when a large json value comes in:
String inputStreamString = (String) JsonPath.read(textValue.toString(), "$.body");
'textValue' here is a hadoop.io.Text object.
I'm assuming that the OutOfMemory error occurs because we try to do method calls like toString() (which creates a new object), and JsonPath.read(), all of which are done in-memory. I need to know if there is an approach I could take while handling large-sized textValue objects.
Please let me know if you need additional info.
JsonSurfer is good for processing very large JSON data with selective extraction.
Example how to surf in JSON data collecting matched values in the listeners:
BufferedReader reader = new BufferedReader(new FileReader(jsonFile));
JsonSurfer surfer = new JsonSurfer(GsonParser.INSTANCE, GsonProvider.INSTANCE);
SurfingConfiguration config = surfer.configBuilder().bind("$.store.book[*]", new JsonPathListener() {
#Override
public void onValue(Object value, ParsingContext context) throws Exception {
JsonObject book = (JsonObject) value;
}
}).build();
surfer.surf(reader, config);
Jackson offers a streaming API for generating and processing JSON data.

Categories

Resources