I am getting a JsonObject that i need to return it as a raw json in spring mvc in the controller.
Using #ResponseBody doesn't work. So it's either i fix in the controller or i render it in a jsp , so any idea about any of these 2 solutions?
Note that i don't always know the type of the object returned in the json
Are you able to return String? If so, use Json encoder and decoder. For example, JSON-lib.jar can be used to do these.
Here are few links that will help you
Returning JsonObject using #ResponseBody in SpringMVC
Spring configure #ResponseBody JSON format
Related
I want to pass a preformed JSON string from a Spring MVC controller method using the ModelMap.addAttribute or put method. I have some data that needs to be loaded when the page renders. I do not want to send a Java object list and then have to unpack it with Javascript into JSON. The problem is that ModelMap.addAttribute or ModelMap.put seems to convert the JSON string back into the Java objects.
When I inspect the added attribute in the JSP I get things like:
[foos.web.FOOSController$foosDataHolder#63eef378,foos.web.FOOSController$foosDataHolder#5f395275]
In controller:
model.put("foosData", jsonFoosString); // can I just pass a string here?
In JSP:
var foosData = "${foosData}";
Then the JSON parser in the browser cannot parse foos.web.FOOSController$foosDataHolder#63eef378 and says that '#' is an invalid character, which it is.
Thanks for any suggestions for this Spring MVC novice.
I know that I could do an ajax method and get the JSON string back, or unpack an object array in the JSP, but I want this to be fast.
Thanks to #RestController I don't need to add annotation #ResposneBody, cause spring knows that it is rest controller, and he will not generate view, but instead it will return json object.
Unfortunately there is one more annotation related to this topic. It is #RequestBody, when controller method accept json object as a parameter. And it will have to be pointed before that parameter.
My question is there a way to get rid of that annotation (#RequestBody).? If my controller is rest controller (#RestController instead of regular #Controller) it should be demanded from spring?
No, you'll have to specify #RequestBody. A Java method can have only a single return value, and so the #ResponseBody is unambiguous, but there are multiple possible ways that mapped controller parameters might be interpreted (in particular, using #ModelAttribute with form encoding is a very common alternative to #RequestBody with JSON), and you'll need to tell Spring how to map the incoming request.
i am trying to get json data and store data in db and send json object about status of operation i am able to store data in db but my return json object is not working fine i am not getting json object
my java code:
#RequestMapping(value = "/a",headers="Content-Type=application/json",method = RequestMethod.POST)
#ResponseBody
public JSONObject data(#RequestBody String load)
{
org.json.JSONObject obj = new org.json.JSONObject();
obj.put("Status", "Success");
obj.put("Details","DB updated");
return obj;
}
In your #RequestMapping annotation define produces = MediaTyp.APPLICATION_JSON_VALUE. Your method should then just return a simple Map.
What is returned is actually controlled by the accepts Header in the request. So as an alternativ you could always ensure that your request asks for the right typ. But setting produces in the annotation is in my opinion a good idea as Spring does some auto conversions based on libraries available on the classpath. This might cause security issues if you do not control the type by hand.
edit:
Instead of a simple Map you could also just return any Java Object as long as it can be serialized by Jackson. You can control serialization using annotation in the Object class in this case.
Also you need the Jaclson library on the classpath for this to work (should be the case if you use a basic Spring Boot Web App).
Here is the offical Spring guide on how to build sutch a service: http://spring.io/guides/gs/rest-service/
I'd like to POST JSON and have Jackson convert it to a POJO, but for now I can't even POST a simple String parameter.
I'm using Jackson 2.3.2 (jackson-core and jackson-databaind)
I'm using Spring 3.2.8.RELEASE (spring-context, spring-webmvc)
My Controller looks like this:
#RequestMapping(value="add-name", method=RequestMethod.POST, headers = "Accept=application/json")
public String addName(#RequestParam(value = "name", required = false) String name) {
LOG.info(String.format("name: %s", name));
return "name";
}
I POST to this Controller with data like this:
{ "name" : "my_name" }
The response I receive is 400 Bad Request
Note: I'm submitting the POST via jQuery.post(), but to remove that as a variable, I'm also submitting POST via FF Poster add-on specifying the URL, Content Type (application/json), and data as above.
Edit: I think the issue may be that the Jackson library isn't even being called. I took it out of the dependencies and nothing changes, no different error/exception, I still simply get a 400 Bad Request response.
Edit 2: Even if I take out the parameter to addName completely and post an empty body {} I still get a 400 Bad Request
You are posting raw data in the body, but your controller is looking for a parameter named name. Either post with a parameter name whose value is my_name, or use #RequestBody in the handler to pass in the JSON object.
I downgraded to Spring 3.1.1.RELEASE and Jackson 1.9.9 and it works now. Seems like a hack. I thought Spring 3.2 and Jackson 2 were compatible.
I wish to implement a REST service using Spring MVC where I pass in the following object at the URL "/url/lookup/{jsonparm}":
{"url":"http://bubba.com/foo/bar", "max_hops":3}
I tried the following:
#RequestMapping(value = "/url/lookup/{jsonparam}", method = RequestMethod.GET)
#ResponseBody
public String urlLookup(#PathVariable("jsonparam") String jsonparam) {
// just to see if I can get the parms
logger.debug("urlLookup get request : " + jsonparam.toString());
JSONObject resp = new JSONObject();
return resp.toString(); // return an empty JSONObject for now
}
So I invoke this by calling
http://localhost:8080/v1/wsp/url/lookup/%7B%22max_hops%22%3A3%2C%22url%22%3A%22http%3A%2F%2Fbubba.com%2Ffoo%2Fbar%22%7D
No luck see the following in my Jetty log:
WARNING: No mapping found for HTTP request with URI [/v1/wsp/url/lookup/{"max_hops":3,"url":"http://bubba.com/foo/bar"}] in DispatcherServlet with name 'rest'
Notes:
the url prefix localhost:8080/v1/wsp/ is correct and my Servlet and Request Mapping are also correct
I have updated the question to use a #PathVariable as one of the responders suggested
Thanks.
You're confusing GET and POST methods.
Either:
Use POST method and actually post the JSON contents to the controller. You can debug this using any REST client, eg. Advanced Rest Client for Chrome.
Use GET method (as you are currently). But you have to pass the JSON value as an actual parameter called jsonparam. So, your example should change to:
http://localhost:8080/v1/wsp/url/lookup/jsonparam=%7B%22max_hops%22%3A3%2C%22url%22%3A%22http%3A%2F%2Fbubba.com%2Ffoo%2Fbar%22%7D
The latter is less common.
Edit:
On second look at your URL, I suspect you're confusing two Spring annotations:
#PathVariable("jsonparam") and:
#RequestParam("jsonparam")
You're using #RequestParam while your URL indicates need for #PathVariable.
Edit2:
However, as can be read here: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-uri-templates the path variable can be passed a value of any simple type. I believe JSON isn't one of them, hence your problems.
I would strongly recommend using POST for interchanging JSON values. However, if that is not an option, I would recommend sticking with GET method, #RequestParam for accessing parameter value, and passing the JSON value like in the corrected example above.
You should use #PathVariable instead of #RequestParam:
public String urlLookup(#PathVariable("jsonparam") String jsonparam){
}
because you have #RequestMapping(value = "/url/lookup/{jasonparam}"
And you have a typo in your #RequestMapping value. It should be /url/lookup/{jsonparam} instead of {jasonparam}