I'm trying to Parse very simply JSON to object (with GSON)
My JSON:
[{"username":"admin","password":"admin","name":"admin","email":"admin#admin.com"},{"username":"mark20","password":"mark123","name":"mark","email":"mark#steew.com"}]
is there 2 users, so I create 2 class, Users with list of users and User :
public class Users {
ArrayList<User> users;
Users(ArrayList<User> users){
this.users = users;
}
}
.
public class User {
String userame;
String password;
String name;
String email;
}
and here is my parsing code:
public void onResponse(Call call, Response response) throws IOException {
String body = response.body().string();
Gson gson = new GsonBuilder().create();
Users users = gson.fromJson(body, Users.class);
}
of course in variable body I have got correct JSON, but in last lane I got:
JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
What can be wrong here ? How to fix it ?
Your json is an array of User not a wrapper Users of array User.
Read your json like this:
User[] users = gson.fromJson(body, User[].class);
If you want an ArrayList<>:
List<User> userList = Arrays.asList(users);
Another way is to use TypeToken:
Type listType = new TypeToken<ArrayList<User>>(){}.getType();
List<User> userList = gson.fromJson(body, listType);
If I'm reading from what I read elsewhere correctly try:
public void onResponse(Call call, Response response) throws IOException {
String body = response.body().string();
Gson gson = new GsonBuilder().create();
User[] users = gson.fromJson(body, User[].class);
}
Related
I need to send json data to a post call in java. The following is the code
my pojo class
public class Data{
#JSONProperty("clientIP")
String clientIP;
#JSONProperty("empID")
String empID;
public Data setClientIP(String clientIp){
this.clientIP = clientIp;
return this;
}
public Data setEmpID(String empId){
this.empID = empId;
return this;
}
public String toString(){ /*toString conversion*/ }
}
Filter class where am setting clientIp
public doFilter(ServletRequest request, ServletResponse response){
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String clientIP = httpServletRequest.getRemoteAddr();
Data data = new Data();
data.setClientIP(clientIP);
}
Java class where am setting other emp related data for example userId
public Emp createEmp(empId, /*other emp related data*/){
Data data = new Data();
data.setEmpID(empId);
//append clientIp to this data object
ConvertToJSON(data);
}
in another service class am converting this data to json formatted string using jackson binding. Here I want to append previously set clientIp to this data so that I can convert entire data object to json formatted string
Class where am converting java object to json
convertToJSON(Object data){
ObjectMapper mapper = new ObjectMapper();
String jsonString = null;
jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
}
I need output like { clientIP: 123.123.123.123, empID: emp123 }
currently it displays { clientIP: null, empID: emp123} which is obvious
As I said in comment, one simple way is to store clienIP into session attribute in your web filter as follows:
String clientIP = httpServletRequest.getRemoteAddr();
HttpSession session = httpServletRequest.getSession();
session.setAttribute("X-CLIENT-IP", clientIP);
Then you can use request.getSession().getAttribute("X-CLIENT-IP").toString() to retrieve client IP if you have a declaration of HttpServletRequest request.
After that, you can pass it as an argument for mehtod createEmp such as
public Emp createEmp(empId, clientIp) {
Data data = new Data();
data.setClientIP(clientIp);
data.setEmpID(empId);
...
}
Android space
void post(Food food)
{
Gson gson = new Gson();
String jsonFood = gson.toJson(food);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.postForEntity(URL, jsonFood, String.class);
}
Back end space
#PostMapping("/food")
public void postFood(#RequestBody String foodJson)
{
Food food = new GsonBuilder().create().fromJson(foodJson, Food.class);
String id = createId(food);
// now how do I send back saying I got this and here is an id?
}
After I receive I want to reply back saying I got the information and send back an ID.
Spring boot will automatically convert the json to a model object under the covers using Jackson
#PostMapping("/food")
public YourResponse postFood(#RequestBody Food food)
{
String id = createId(food);
return new YourResponse(id,"hello World");
}
Response object
public class YourResponse{
private String id;
private String response;
//.. constructor, getter setter
}
You can create a response model
public class PostFoodResponse{
private String id;
private String response;
//.. constructor, getter setter
}
In your code create an object of PostFoodResponse set data and send the object back as a json response
#PostMapping("/food")
public String postFood(#RequestBody String foodJson)
{
Food food = new GsonBuilder().create().fromJson(foodJson, Food.class);
String id = createId(food);
// now how do I send back saying I got this and here is an id?
PostFoodResponse response = new PostFoodResponse(id, "I got this");
return new GsonBuilder().create().toJson(response);
}
I need to send data to database in this format -
{"param1":"value1", "param2":"value2", "param3": {"username": "admin", "password": "123"}}
How to generate this using JSONStringer ?
I tried this -
vm = new JSONStringer().object().key("param1").value("value1")
.object().key("param2").value("value2")
.key("param3").object()
.key("username").value("admin")
.key("password").value("123")
.endObject().endObject().endObject();
But I'm getting this error -
org.json.JSONException: Nesting problem at
org.json.JSONStringer.beforeValue(JSONStringer.java:415)
JSONObject object1 = new JSONObject();
object1.put("param1", "value1");
object1.put("param2", "param2");
JSONObject innerObject1 = new JSONObject();
innerObject1.put("username", "admin");
innerObject1.put("password", "123");
object1.put("param3",innerObject1);
String jsonStr = object1.toString();
Ideally reverse of JSON parsing can be applied to create a json string object, so that the same can be send to Server/DB
Try this
try {
JSONObject object=new JSONObject();
object.put("param1","value1");
object.put("param2","value2");
JSONObject param3=new JSONObject();
paraam3.put("username","admin");
paraam3.put("password","123");
object.put("param3",param3);
} catch (JSONException e) {
e.printStackTrace();
}
You can create model which will be your java file same as your JSON file and can use gson library which is supported by Google to do JSON parsing. The library is quite flexible and easy to use then using traditional method of JSON parsing.
Model File
public class Response {
public String param1;
public String param2;
public Param3 param3;
public Response(String param1, String param2) {
this.param1 = param1;
this.param2 = param2;
}
public class Param3 {
public String username;
public String password;
public Param3(String username, String password) {
this.username = username;
this.password = password;
}
}
}
In file in which you insert data
Response res = new Response("value1", "value2", new Param3("admin","123"));
String dbResult = new Gson.toJson(res);
If you are looking for the actual solution using org.json.JSONStringer
JSONWriter writer = stringer3.object()
.key("param1").value("value1")
.key("param2").value("value2")
.key("param3").object()
.key("username").value("admin")
.key("password").value("123")
.endObject()
.endObject();
System.out.println(writer.toString());
You can think of the object() method as opening a new parenthesis and the endObject() as closing it
I have a response object like this:
public class TestResponse {
private final String response;
private final ErrorCodeEnum error;
private final StatusCodeEnum status;
// .. constructors and getters here
}
I am serializing above class using Gson library as shown below:
Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
System.out.println(gson.toJson(testResponseOutput));
And the response I am getting back is shown below:
{
"response": "{\"hello\":0,\"world\":\"0\"}",
"error": "OK",
"status": "SUCCESS"
}
As you can see, my json string in "response" field is getting escaped. Is there any way I can ask gson not to do that and instead return a full response like this:
{
"response": {"hello":0,"world":"0"},
"error": "OK",
"status": "SUCCESS"
}
And also - Is there any problem if I do it above way?
NOTE: My "response" string will always be JSON string or it will be null so only these two values will be there in my "response" string. In "response" field, I can have any json string since this library is calling a rest service which can return back any json string so I am storing that in a string "response" field.
If your response field can be arbitrary JSON, then you need to:
Define it as an arbitrary JSON field (leveraging the JSON type system already built into GSON by defining it as the root of the JSON hierarchy - JsonElement)
public class TestResponse {
private final JsonElement response;
}
Convert the String field to an appropriate JSON object representation. For this, you can use GSON's JsonParser class:
final JsonParser parser = new JsonParser();
String responseJson = "{\"hello\":0,\"world\":\"0\"}";
JsonElement json = parser.parse(responseJson); // Omits error checking, what if responseJson is invalid JSON?
System.out.println(gson.toJson(new TestResponse(json)));
This should print:
{
"response": {
"hello": 0,
"world": "0"
}
}
It should also work for any valid JSON:
String responseJson = "{\"arbitrary\":\"fields\",\"can-be\":{\"in\":[\"here\",\"!\"]}}";
JsonElement json = parser.parse(responseJson);
System.out.println(gson.toJson(new TestResponse(json)));
Output:
{
"response": {
"arbitrary": "fields",
"can-be": {
"in": [
"here",
"!"
]
}
}
}
I know this is old but just adding an potential answer in case it is needed.
Sounds like you just want to return the response without escaping. Escaping is a good thing, it will help to prevent security issues and prevent your JS application from crashing with errors.
However, if you still want to ignore escaping, try:
Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().create();
add simple TypeAdapter and use jsonValue(value)
gson 2.8.0
version 1:
#Test
public void correctlyShow() {
TestResponse2 src = new TestResponse2("{\"arbitrary\":\"fields\",\"can-be\":{\"in\":[\"here\",\"!\"]}}");
Gson create = new GsonBuilder().registerTypeAdapter(String.class, ADAPTER).create();
Stopwatch createStarted = Stopwatch.createStarted();
String json2 = create.toJson(src);
System.out.println(json2 + " correctlyShow4 " + createStarted.stop());
}
public class TestResponse2 {
private final String response;
public TestResponse2(String response) {
this.response = response;
}
public String getResponse() {
return response;
}
}
private static final TypeAdapter<String> ADAPTER = new TypeAdapter<String>() {
#Override
public String read(JsonReader in) throws IOException {
throw new UnsupportedOperationException("Unsupported Operation !!!");
}
#Override
public void write(JsonWriter out, String value) throws IOException {
out.jsonValue(value);
}
};
...
vesrion 2
#Test
public void correctlyShow() {
TestResponse2 src = new TestResponse2("{\"arbitrary\":\"fields\",\"can-be\":{\"in\":[\"here\",\"!\"]}}");
String json2 = new Gson().toJson(src);
System.out.println(json2 + " correctlyShow4 ");
}
public class TestResponse2 {
#JsonAdapter(value = AdapterStringJson.class)
private final String response;
public TestResponse2(String response) {
this.response = response;
}
public String getResponse() {
return response;
}
}
private class AdapterStringJson extends TypeAdapter<String> {
#Override
public String read(JsonReader in) throws IOException {
throw new UnsupportedOperationException("Unsupported Operation !!!");
}
#Override
public void write(JsonWriter out, String value) throws IOException {
out.jsonValue(value);
}
}
You should have a nested object.
public class Response {
private final Integer hello;
private final String world;
}
public class TestResponse {
private final Response response;
private final ErrorCodeEnum error;
private final StatusCodeEnum status;
// .. constructors and getters here
}
Instead of a String, depending on your needs, you could use a Map (or similar) or a nested Object. There should not be a problem representing it this way but in your example, if it were a String, there would be a problem if you didn't escape characters such as the double-quote.
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<ProductData> getAllProductList(#QueryParam("hotel_id") int hotel_id) throws SQLException{
System.out.println("Hotel id id==="+hotel_id);
ProductData productData=new ProductData();
List<ProductData> products = new ArrayList<ProductData>();
rs=stmt.executeQuery("select * from products where hotel_id="+hotel_id);
while(rs.next()){
productData.setProductName(rs.getString("name"));
productData.setProductCategory(rs.getString("category"));
productData.setProductRate(rs.getDouble("rate"));
productData.setProductLogoPath(rs.getString("productLogoPath"));
products.add(productData);
}
return products;
}
I have passed List as JsonObject.Now i tried to get List value like
void handleResponse(String response) throws JSONException {
JSONObject jsonObject=new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("products");
}
but i can't get the List value.anyBody can help me?
There is the simple way to convert json string to object :
Try this :
ObjectMapper mapper = new ObjectMapper();
POJO obj = mapper.readValue(yourJSONString, POJO.class);
Use method signature something similar like-
public Response getAllProduct..
&
return like-
return Response.status(Status.OK).entity(products).build();
For intg. layer use-
public ClientResponse<> similarSignatureMethod..
&
call via the client and then get response entity as-
clientResponse.getEntity();