issue KendoUI and SpringMVC with json binding - json

When I use a grid KendoUI, there is a problem with SpringMVC and jackson.
In fact, the grid datasource take a json with the format :
[{"name":"Apple","description":"a description","value":15}]
However, SpringMVC serialize it like :
{"name":"Apple","description":"a description","value":15}
without square bracket in String, so this grid doesn't bind values.
e.g code :
#RequestMapping(value="/product", method = RequestMethod.GET)
public #ResponseBody Product get(Model model) {
Product app = new Product("Apple", "a description", 15);
return app;
}
#RequestMapping(value="/product/json", method = RequestMethod.GET)
public #ResponseBody String getJson(Model model) {
return"[{\"name\":\"Apple\",\"description\":\"a description\",\"value\":15}]";
}

You can use dataSource.schema.parse to manually intercept and parse that string representing your JSON into valid JavaScript Array.

Below should work. Kendo Grid is expecting a JSON array, thus the block quotes.
For READ :
#RequestMapping(value = "/list", method = RequestMethod.GET)
public #ResponseBody
List<Product> list() {
Product apple = new Product("Apple", "a description", 15);
List<Product> listProduct = new ArrayList<Product>();
listProduct.add(apple);
return listProduct;
}

#RequestMapping(value="/product", method = RequestMethod.GET)
public #ResponseBody Product[] get(Model model) {
Product app = new Product("Apple", "a description", 15);
return new Product[]{app};
}
or
#RequestMapping(value="/product", method = RequestMethod.GET)
public #ResponseBody List<Product> get(Model model) {
List<Product> product = new ArrayList<Product>();
product.add(new Product("Apple", "a description", 15));
product.add(new Product("Guice","a guice",3));
return product;
}

Related

Spring boot application POST request not works and not update the database

I have java Spring Boot application. When I’m sending data POST request through POSTman. JSONObject cannot be returned, POSTman showing {"false"}
This is my controller,
package com.lagoma.demo.controller;
#RestController
#RequestMapping(value = "/user")
public class User {
#Autowired
private UserService userService;
#GetMapping
public List<UserModel> getUsers() {
return userService.getUsers();
}
#RequestMapping(method = RequestMethod.GET, value = "/get")
public UserModel getOneUser(#RequestParam(value = "id", required = false, defaultValue = "00") int id) {
return userService.getUser(id);
}
#RequestMapping(method = RequestMethod.POST, value = "/save")
public boolean updateUser(#RequestBody UserModel userModel){
return userService.updateUser(userModel);
}
Spring Controller can't return primitive type or its wrapper .
You need to return some object.
If you dont have any object in scope, returning a Map will also do.
Change your updateUser to something like this
#RequestMapping(method = RequestMethod.POST, value = "/save")
public Map<String, Boolean> updateUser(#RequestBody UserModel userModel){
return Collections.singletonMap("result", userService.updateUser(userModel));
}
or with a Object
#RequestMapping(method = RequestMethod.POST, value = "/save")
public User updateUser(#RequestBody UserModel userModel){
// assuming userService.updateUser will return User object
User user = userService.updateUser(userModel);
return user;
}

JsonConvert a json with a list<> element WP8

I have a json coming from webservice, which has a List<> element in it.
But when I try to deserialize it using Newtonsoft.Json
Response resp = JsonConvert.DeserializeObject<Response>(responseStr);
then when I fetch the list using resp.ProjectList, it throws a null pointer exception.
So the List<Project> is not getting deserialized.
Any idea what am I missing?
The response is of the form:
public Response
{
public string msg;
public List<Project> ProjectList{get; set;}
}
[DataContract]
public class Project
{
[DataMember]
public string ID {get; set;}
}
Just remove the [DataContract] and [DataMember] attributes, they do not mix well with Json.NET.
Or you can do the deserialization "manually"
var j = JToken.Parse("{ \"Msg\": \"Success\", \"ProjectList\": [ { \"ID\": \"/Date(1400120100000-0700)/\" }, { \"ID\": \"/Date(1404260520000-0700)/\" } ] } ");
var resp = new Response
{
msg = j.SelectToken("Msg").ToString(),
ProjectList = ((JArray) j.SelectToken("ProjectList")).Select(l => new Project {ID = l.SelectToken("ID").ToString()}).ToList()
};

How To parse multiple objects in the same JSON request/response throw SpringMVC without creating custom DTO

I have two model classes
Class User
{
}
Class UserProfile
{
}
I want to use SpringMVC and JSON to send/receive(#GET,#POST) multiple objects in the same request/response.
for example:
{
"userprofile" : { "id":1, name:"test1" },
"user" : {"id": 161, "name": "x"}
}
Ensure that Jackson is on the classpath. Make an additional inner class in your Controller that resembles
static class UserAndProfile {
public UserProfile userprofile;
public User user;
}
and then your request mappings would resemble
#RequestMapping(value = "/user", method = RequestMethod.GET)
public #ResponseBody UserAndProfile user() {
UserAndProfile userAndProfile = new UserAndProfile();
userAndProfile.userprofile = ...
userAndProfile.user = ...
return userAndProfile;
}
#RequestMapping(value = "/user", method = RequestMethod.POST)
public Object user(#RequestBody UserAndProfile userAndProfile) {
...
}
See Mapping the response body with the #ResponseBody annotation for further details.

Create JsonObject from #ResponseBody

#RequestMapping(value = "/dropDown", method = RequestMethod.GET)
public #ResponseBody
DropDown getList(Map<String, Object> map, HttpServletRequest request,
HttpServletResponse response) {
DropDown dropDown = new DropDown();
List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();
List<MapTable2> list = contactService.mapProcess();
for (MapTable2 table : list) {
Map<String, Object> dataRow = new HashMap<String, Object>(1);
dataRow.put("text", table.getProcess());
dataRow.put("value", table.getId());
dataRow.put("selected", false);
dataRow.put("description", table.getProcess());
dataRow.put("imageSrc", "image.jpg");
rows.add(dataRow);
}
dropDown.setRows(rows);
return dropDown;
}
I need to create following one
var ddData = [
{
text: "Facebook",
value: 1,
selected: false,
description: "Description with Facebook",
imageSrc: "http://dl.dropbox.com/u/40036711/Images/facebook-icon-32.png"
},
{
text: "Twitter",
value: 2,
selected: false,
description: "Description with Twitter",
imageSrc: "http://dl.dropbox.com/u/40036711/Images/twitter-icon-32.png"
}]
I know the issue with my above java coding , I'm not aware to create json array like above.
please check it and help me to correct it.
MapTable2 has ProcessId & ProcessName
public class MapTable2 {
private int id;
private String process;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProcess() {
return process;
}
public void setProcess(String process) {
this.process = process;
}
}
#theon is right.
Since you are using #Responsebody you can let Spring do the JSON conversion for you. Create a class that matches the objects in the JSON array:
public class SomeObject {
public String getText() { //... }
public int getValue() { //... }
public boolean getSelected { // ... }
public String getDescription { // ... }
public String getImageSrc { // ... }
}
Populate the objects and return it as a list from your controller:
#RequestMapping(value = "/dropDown", method = RequestMethod.GET)
#ResponseBody
public List<SomeObject> getList(Map<String, Object> map, HttpServletRequest request, HttpServletResponse response) {
// Get the objects, return them in a list
}
Add the <mvc:annotation-driven /> or the #EnableWebMvc to your application config unless you have not already done so. Make sure that Jackson is available on your classpath and then Spring will automatically serialize your objects to JSON (if the request has Content-Type: application/json. Alternatively, the produces attribute can be added to the #RequestMapping annotation to always return JSON).
Well Use this library. It is very light weight (16KB) and does exactly what you need.
So in your case, you will be using JSONObject which internally extends HashMap
and do
JSONObject o = new JSONObject();
o.put("text","whatever text");
o.put("value",1);
o.put("selected",false);
//and so on
JSONArray arr = new JSONArray();
arr.add(o);
The above will give you this:
[
{
text: "Facebook",
value: 1,
selected: false,
description: "Description with Facebook",
imageSrc: "http://dl.dropbox.com/u/40036711/Images/facebook-icon-32.png"
}
]
To add more objects, add more JSONObjects in a loop to JSONArray
So as per your given code, just replace dataRow with 'JSONObject' and rows with JSONArray and thats it. In the end, to retrieve the string, do rows.toString().

Spring MVC Controller adds request object to response

I am building a JSON REST service with Spring 3.0.5 and my response contains the object from my request although I did not add it. I am using the MappingJacksonJsonView and Jackson 1.6.4 for rendering the ModelAndView object to JSON.
The User object is simple
public class SimpleUser {
private String username;
private String password;
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password;
}
}
One of the requests looks like this
#RequestMapping(value = "/register", method = RequestMethod.GET)
public ModelAndView register(SimpleUser user) {
ModelAndView mav = new ModelAndView();
mav.addObject("ok", "success");
return mav;
}
Then I call the service with
curl 'http://localhost:8080/register?username=mike&password=mike'
The response I expect is
{"ok": "success"}
The response I get is
{"ok":"success","simpleUser":{"username":"mike","password":"mike"}}
Where and why is the user object added to the ModelAndView and how can I prevent that?
Possible solution
One way to work around this is to use Model instead of SimpleUser. This seems to work but it should be possible to use the business object.
This works:
#RequestMapping(value = "/register", method = RequestMethod.GET)
public ModelAndView register(Model model) {
log.debug("register(%s,%s)", model.asMap().get("usernmae"), model.asMap().get("password"));
ModelAndView mav = new ModelAndView();
mav.addObject("ok", "success");
return mav;
}
It looks like you're trying to process a form submission and retrieve the result via ajax. If this is the case, you don't want to return a ModelAndView object. Use the #ResponseBody annotation to have Jackson represent your return object as a json object.
public #ResponseBody Map registerUser(SimpleUser user){
Map responseMap = new HashMap();
if(registerUser(user)){
responseMap.put("OK", "Success");
} else {
responseMap.put("OK", "Failure");
}
return responseMap;
}
For Spring 3.1.x You can set the modelKey property in org.springframework.web.servlet.view.json.MappingJacksonJsonView in your *servlet.xml like below:
Servlet.xml:
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="modelKey" value="appResponse"/>
</bean>
Request Method:
#RequestMapping(value="/access")
public #ResponseBody Model getAccess(Model model) {
...
model.addAttribute("appResponse", responseDetails);
...
return model;
}
When you set a specific modelKey, all other attributes attached the the model will be ignored, hence the form parameters/request parameters. In additional, this provides a clearer design if your are presenting views for multiple media types (application/xml or application/json).