My servlet has an ArrayList and a HashMap object that I want to be sent to my jsp via AJAX. How do I do that and then how do I separate them out after getting them as javascript responseText? (Cant use jQuery)
ArrayList al = new ArrayList();
String json1= new Gson().toJson(al);
HashMap hm = new HashMap();
String json2= new Gson().toJson(hm);
What I havedone so far
ServletOutputStream os = res.getOutputStream();
String json = "[" + json1 + "," + json2 + "]";
System.out.println(json);
os.write(json.toString().getBytes());
flushCloseOutputStream(os);
res.setStatus(HttpServletResponse.SC_OK);
And then on jsp side
var jsonResponse = JSON.parse(this.responseText);
var workDesc = jsonResponse[1];
var thirdPartyData = jsonResponse[0];
My question is, is this the correct way of sending response?
GSON will do the trick. A simple example:
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.HashMap;
class App {
private static final Type hashMapStringApp = new TypeToken<HashMap<String,App>>(){}.getType();
private String attribute;
public App(String attribute) {
this.attribute = attribute;
}
public static void main(String[] args) {
Gson gson = new Gson();
// Complex object to JSON
HashMap<String, App> map = new HashMap<>();
map.put("1", new App("Attr1"));
map.put("2", new App("Attr2"));
String json = gson.toJson(map);
System.out.println(json);
// JSON to complex object
HashMap<String, App> fromJson = gson.fromJson(json, hashMapStringApp);
System.out.println(fromJson.get("2").getAttribute());
}
public void setAttribute(String attribute) {
this.attribute = attribute;
};
public String getAttribute(){
return this.attribute;
}
}
Maven dependency:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
Related
I'm Java beginner. Just added JSON. Simple dependency and it's so easy to convert data to JSON format.
example :
public void Post_test3_positive(){
JSONObject user = new JSONObject();
user.put("name","John");
user.put("email","John#inbox.lv");
given()
.body(user.toJSONString())
.when().post("/api/user/createUserPost")
.then().statusCode(201)
Is there any easy way to convert request body (username and email ) to XML format?
Thanks
Hi try this to convert map to xml string :
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("name","chris");
map.put("island","faranga");
XStream magicApi = new XStream();
magicApi.registerConverter(new MapEntryConverter());
magicApi.alias("root", Map.class);
String xml = magicApi.toXML(map);
System.out.println("Result of tweaked XStream toXml()");
System.out.println(xml);
Map<String, String> extractedMap = (Map<String, String>) magicApi.fromXML(xml);
assert extractedMap.get("name").equals("chris");
assert extractedMap.get("island").equals("faranga");
}
public static class MapEntryConverter implements Converter {
public boolean canConvert(Class clazz) {
return AbstractMap.class.isAssignableFrom(clazz);
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
AbstractMap map = (AbstractMap) value;
for (Object obj : map.entrySet()) {
Map.Entry entry = (Map.Entry) obj;
writer.startNode(entry.getKey().toString());
Object val = entry.getValue();
if ( null != val ) {
writer.setValue(val.toString());
}
writer.endNode();
}
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Map<String, String> map = new HashMap<String, String>();
while(reader.hasMoreChildren()) {
reader.moveDown();
String key = reader.getNodeName(); // nodeName aka element's name
String value = reader.getValue();
map.put(key, value);
reader.moveUp();
}
return map;
}
}
}
I use java POJO and convert it to json/xml by using Jackson library.
#Data
#AllArgsConstructor
#XmlRootElement
#NoArgsConstructor
static class Example {
private String name;
private String email;
}
#Test
void name() {
Example payload = new Example("John", "John#inbox.lv");
given().log().body()
.contentType(ContentType.JSON)
.body(payload)
.when().post("https://postman-echo.com/post");
given().log().body()
.contentType(ContentType.XML)
.body(payload)
.when().post("https://postman-echo.com/post");
}
result:
Body:
{
"name": "John",
"email": "John#inbox.lv"
}
Body:
<example>
<email>John#inbox.lv</email>
<name>John</name>
</example>
pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
I have a JSON file(it contains an array of JSON objects.)
I am trying to read it object by object.
Each object I need to convert it to a LinkedHashMap<String,String> where both the key and value are strings. Note that even if the JSON objects contain a non-string value(Integer/Boolean), I want my LinkedHashMap to contain a string.
This is my JSON file (films.json):
[
{
"name": "Fight Club",
"year": 1999,
}
]
Now, this has 1 object. I want to convert it to a LinkedHashMap<String,String>.
So for the above example, my LinkedHashMap should contain(for the 1st JSON object) :
"name" : "Fight CLub"
"year" : "1999"
Notice how the year is String in the LinkedHashMap and not Integer.
This is what I tried.
Map<String, Object> myLinkedHashMap;
JsonParser jsonParser = new JsonFactory().createParser(new File("films.json"));
jsonParser = new JsonFactory().createParser(new File(filePath));
jsonParser.nextToken();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
while(jsonParser.nextToken() != JsonToken.END_ARRAY){
myLinkedHashMap = mapper.readValue(jsonParser, LinkedHashMap.class);
}
The variable myLinkedHashMap will contain a key/value pair for an object in my JSON file.
But the problem is that for 'year' of the JSON file, I am getting Integer in the LinkedHashMap as the JSON file also contains Integer.
Instead, I want the Integer as String in the LinkedHashMap.
Please help me get String in the LinkedHashMap instead of Integer.
Note: The solution should be generic to other data types also.
So if the JSON object contains boolean true, then my LinkedHashMap should contain "true".
You can construct map type using TypeFactory and constructMapType method to tell exactly what do you need from readValue method. See below example:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.MapType;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.util.Assert;
import java.io.File;
import java.util.LinkedHashMap;
public class JsonMapApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
JsonParser jsonParser = mapper.getFactory().createParser(jsonFile);
jsonParser.nextToken();
MapType mapType = mapper.getTypeFactory().constructMapType(LinkedHashMap.class, String.class, String.class);
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
LinkedHashMap<String, String> map = mapper.readValue(jsonParser, mapType);
map.forEach((k, v) -> {
Assert.isInstanceOf(String.class, v);
System.out.println(k + " -> " + v + " (" + v.getClass().getName() + ")");
});
}
}
}
Above code prints:
name -> Fight Club (java.lang.String)
year -> 1999 (java.lang.String)
Change
Map<String, Object> myLinkedHashMap;
to
Map<String, String> myLinkedHashMap;
I want to write a JSON Object to a file.Currently I have tried using ObjectMapper and Gson but they are writing the JSON as JSONString, Thus the output file has JSON string rather than object. So is there a way JSON Object is written as Object rather than String
JSONObject responseData = new JSONObject(response.getBody().toString());
org.json.simple.JSONObject object = new
org.json.simple.JSONObject(responseData.toMap());
ObjectMapper objMapper = new ObjectMapper();
objMapper.writeValue(new File(path) , object);
Now the above code is writing the JSON Object as String in to file not a JSONObject.
Don't use ObjectMapper. You can achieve this with org.json.simple.* package itself.
package com.tutorial
import java.io.FileWriter;
import java.io.IOException;
import org.json.simple.JSONObject;
public class JosnObjectWrite {
public static void main(String[] args) throws IOException {
JSONObject responseData = new JSONObject(response.getBody().toString());
JSONObject object = new JSONObject(responseData.toMap());
try (FileWriter file = new FileWriter("/Users/<username>/Documents/file1.txt")) {
file.write(object.toJSONString());
System.out.println("Successfully Copied JSON Object to File...");
System.out.println("\nJSON Object: " + object);
}
}
}
Hi I am try to parse some JSON by GSON which used number as the key.
I reference the post but it give some error and I don't know why.
How to convert json objects with number as field key in Java?
I also see the post but still cannot solve my problem.
"Expected BEGIN_OBJECT but was STRING at line 1 column 1"
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Gson gson = new Gson();
Type type = new TypeToken<HashMap<String, HashMap<String, String>>>() {}.getType();
Map<String, Map<String, String>> map = gson.fromJson("./src/main/resources/input.json", type);
}
}
The json file is
{
"1":{"id":"1"}
}
The fromJson method doesn't receive a filename, it receives an actual JSON: look at the docs here
But there is an overload that receives a Reader instead:
try (FileReader reader = new FileReader("./src/main/resources/input.json"))
{
map = gson.fromJson(reader, type)
}
catch (...) { ... }
I have a JSON I want a to convert it to a HashMap. I have the following code -
ObjectMapper mapper = new ObjectMapper();
Map<String, String> jsonData = new HashMap<String, String>();
jsonData = mapper.readValue(userPropertyJson, new TypeReference<HashMap<String,String>>(){});
it is working fine if the input JSON is
{"user":1, "entity": "email"}
but fails when the JSON is as below -
{"user":1, "entity": ["email","fname","lname","phone"]}
How do I map to HashMap for array also?
Declare a generic HashMap with String as a key and Object as a value , since you don't know the type of value exactly.
Map<String, Object>
And beware of assigning wrong types while retrieving data
Use Map<String, Object>. Example
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonParser {
public static void main(String[] args) {
String userPropertyJson = "{\"user\":1, \"entity\": [\"email\",\"fname\",\"lname\",\"phone\"]}";
ObjectMapper mapper = new ObjectMapper();
try {
Map<String, Object> jsonData = new HashMap<String, Object>();
jsonData = mapper.readValue(userPropertyJson, new TypeReference<HashMap<String,Object>>(){});
System.out.println(jsonData);
} catch (JsonParseException e) {
System.out.println(e.getMessage());
} catch (JsonMappingException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
If you know in advance that your json will always have the same format (a String key mapped to a List<String>, either with a single element or with many elements), then you could use the ACCEPT_SINGLE_VALUE_AS_ARRAY deserialization feature:
ObjectMapper mapper = new ObjectMapper()
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
String jsonWithArray =
"{\"user\": 1, \"entity\": [\"email\", \"fname\", \"lname\", \"phone\"]}";
Map<String, List<String>> map1 =
mapper.readValue(
jsonWithArray,
new TypeReference<HashMap<String, List<String>>>() {});
System.out.println(map1); // {user=[1], entity=[email, fname, lname, phone]}
String jsonWithoutArray = "{\"user\": 1, \"entity\": \"email\"}";
Map<String, List<String>> map2 =
mapper.readValue(
jsonWithoutArray,
new TypeReference<HashMap<String, List<String>>>() {});
System.out.println(map2); // {user=[1], entity=[email]}
This enables you to either have an array for the values in your json, or a single element.
Check out http://www.jsonschema2pojo.org/
It allows you to convert json to java object automatically. I use it when I need to create DTOs from a web service for which I don't have java mapping or SDK.