Accessing JSONObject in jsp - json

My JSP, is being passed an JSONObject in the context, on which it needs to do some processing like creating tables, etc.
But when I try to access the member of this object, it gives the following error -
(the name of one of the keys in this object is ok)
Servlet.service() for servlet jsp threw exception { javax.servlet.jsp.el.ELException:
Unable to find a value for "ok" in object of class "org.json.JSONObject" using operator "."
JSP Code accessing it looks like this -
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:if test="${serviceOutput.ok}">
<c:if test="${serviceOutput.ret.proposalCount} > 0">
.....
Can anyone please suggest how I can resolve this and successfully access all the members of this object?

The other option that could be taken now is to use a different JSON parsing library such as json-simple (http://code.google.com/p/json-simple/). The JSONObject in this library extends HashMap and the JSONArray extends an ArrayList, so EL should work with them. You would then not have to change your jstl or do extra parsing.

EL only understands Javabeans and Maps. You need to let a preprocessing servlet convert each item of the JSONObject to a fullworthy Javabean which has getter methods which can be used in EL, or to a Map.
Here's an example which converts it to a Map:
Map<String, Object> serviceMap = new HashMap<String, Object>();
serviceMap.put("ok", serviceOutput.getBoolean("ok"));
serviceMap.put("foo", serviceOutput.getString("foo"));
// ...
request.setAttribute("serviceMap", serviceMap);
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
This way EL expressions like ${serviceMap.ok} will work.

Related

How SpringMVC #SessionAttributes sends session object to JSP

I am learning SpringMVC framework and I have got the following example from here. Java Controller:
SessionController.java
package javabeat.net.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
#Controller
#RequestMapping("/sessiontest")
#SessionAttributes("sessionValue")
public class SessionController {
#RequestMapping(method = RequestMethod.GET)
public String getForm(#RequestParam("param") String paramVal, ModelMap map){
System.out.println("Param Value : " + paramVal);
map.addAttribute("sessionValue", "Test Object");
return "hello";
}
}
JSP page:
hello.jsp
<%# page contentType="text/html; charset=UTF-8" %>
<html>
<head>
<title>Hello World</title>
</head>
<body>
<%
String value = (String)session.getAttribute("sessionValue");
out.print(value);
%>
</body>
</html>
I am trying to understand the flow of the execution:
to the best of my knowledge, it assumes that in the execution flow the URL /sessiontest?param=paramVal is going to be hit first. Then paramVal is screened to the console. Then the collection map is enriched with the key-value pair "sessionValue"/"Test Object". Then "hello" is returned . So when hello.jsp is being hit, it retrieves the just added value, and the html body screens Test Object.
If my above interpretation is correct, I would like to know:
1) who is passing ModelMap map object to the method getForm?
2) what is the purpose of returning hello to nowhere?
3) how session object in the JSP is tied with the ModelMap map where the new key-value pair is being added?
I guess I'm not really good at explaining things since my words are clumsy.
But here is the thing :
1) who is passing ModelMap map object to the method getForm?
Spring container generates this model object and (behind the scene) invokes it as the argument to the method , it's working just like JSP Implicit Objects (request, response, .etc) where JSP Container makes them available in each page and these objects can be called directly without being explicitly declared .
ModelMap is used to wrap some attributes (key & value) so that you can deliver these values to the view returned from the method. So later, you can access these values in the view via its corresponding keys.
2). what is the purpose of returning hello to nowhere?
hello is the view name (hello.jsp) forwarded from the method where you can access the previous wrapped attributes in the map
3) how session object in the JSP is tied with the ModelMap map where
the new key-value pair is being added?
Spring’s #SessionAttributes is used on a controller to designate which model attributes (think these attributes as keys & values wrapped in the map) should be stored in a session.
In simple explanation : Since this controller is annotated with #SessionAttributes("sessionValue") so whenever a map wrap a value mapped with a key of "sessionValue" then the value will be available in HttpSession.
So then later you access this session attribute via implicit session object in your view.
String value = (String)session.getAttribute("sessionValue"); // gives you "Test Object"

Parse json and unable to access javascript object

I am passing a json object to the client side from java object with a time and value as attributes with gson
this.template.convertAndSend("/topic/123", gson.toJson(object, type));
and on the client side i have the following code where the json object data is stored in the body of the payload but I am unable to access the properties with obj.time or obj.value, it tells me undefined after it is parsed, I tried showing the entire 'obj' itself and the format seems fine however:
var subscription_callback1 = function(payload) {
var obj = JSON.parse(payload.body);
alert(obj);
};
output with alert(obj)
{"time":"3:00:34","value":"7989797"}
Nevermind solved. Since I am transfering STOMP protocol messages with the Spring 4 framework. I opted to use the Jackson2 message converter instead of directly using gson and it seems to work
#Configuration
#EnableWebSocketMessageBroker
public class MessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
messageConverters.add(new MappingJackson2MessageConverter());
return true;
}
then i directly put my java object into the send function instead of using gson to convert it as above
this.template.convertAndSend("/topic/123", event)

Create JSON Request string using Javascript Overlay types in GWT

We have used JSO for our JSON parsing in GWT client side. Now, we need to convert our Java objects to JSON string. I just wanted to understand, how we can achieve this? JSO overlay types was used for JSON parsing. Can it also be used to create a JSON request string or do we have to go by some other means?
Generating a JSON object in JavaScript is pretty simple. You can do it like this:
var obj = { "var1": "hello", "var2": "world" };
this will generate a JSON object with two varibles ("var1" and "var2") with their values ("hello", "world").
The Object can be converted into a String (for sending purposes) with the JSON.stringify(jso); method.
Generating JSON data from the java code isn't possible (well not with a usefull result) since all varibles are optimzed to single Strings, so applying this method wouldn't hava a usefull result (if even possible).
If you have already a JSO object (generated with something like safeeval). You can edit your varibles there, like this:
public final native void newValue(String newValue) /*-{
this.ValueName = newValue;
}-*/;
If you then want the object as string you have to define the following method in your JSO class:
public final native String returnAsString () /*-{
return JSON.stringify(this);
}-*/;
or use this in you Java class: String s = (new JSONObject(jso)).toString();.
This way you can edit your original intput data and send the original object back to the server.
BR

Map JSON array of objects to #RequestBody List<T> using jackson

I'm having issues using Jackson to map a Javascript posted JSON array of hashes (Tag).
Here is the data received by the controller #RequestBody (It is send with correct json requestheader):
[{name=tag1}, {name=tag2}, {name=tag3}]
Here is the controller:
#RequestMapping(value = "purchases/{purchaseId}/tags", method = RequestMethod.POST, params = "manyTags")
#ResponseStatus(HttpStatus.CREATED)
public void createAll(#PathVariable("purchaseId") final Long purchaseId, #RequestBody final List<Tag> entities)
{
Purchase purchase = purchaseService.getById(purchaseId);
Set<Tag> tags = purchase.getTags();
purchaseService.updatePurchase(purchase);
}
When I debug and view the 'entities' value it shows as an ArrayList of generic objects, not as a list of objects of type 'Tag' as I would expect.
How can I get jackson to map a passed array of objects to a list of obejcts of type 'Tag'?
Thanks
It sounds like Spring is not passing full type information for some reason, but rather a type-erased version, as if declaration was something like List<?> tag. I don't know what can be done to fully resolve this (may need something from Spring integration team), but one work-around is to define your own type like:
static class TagList extends ArrayList<Tag> { }
and use that instead. This will retain generic parameterization through super-type declarations so that even if Spring only passes equivalent of TagList.class, Jackson can figure out the Tag parameter.
Another way to do this is to rather obtain an array than a List, as follows:
#RequestBody Tag[] entities
Jackson requires a default constructor with no parameters on custom Objects, so you'll need to simply add a default constructor to your Tag class.
In your case simply add to your Tag class:
public Tag(){}

How to serialize this JSON Array String using Jackson Annotations?

[{"ID":"hzQ8ll","CreationDate":"Thu, 24 Feb 2011 12:53:31 GMT","Count":6,"Name":"SOMETAG"}]
The inside is of type Tag so I just wrote this Java class:
public class Tags {
public List <Tag>tags;
}
But I get com.sun.jersey.api.client.ClientHandlerException:
org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.test.Tags out of START_ARRAY token
I am using Jersey with the JacksonJsonProvider like this:
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(JacksonJsonProvider.class);
Then I just do a simple Jersey client call:
ClientResponse response = builder.get(ClientResponse.class);
Tags tags = response.getEntity(Tags.class);
Any ideas? Most of the time my outermost elements had a name associated to it so this is new to me. Thanks for any help
You possibly have to declare a Tag[] instead of a List<Tag>.
I had a similar issue with a different JSON library.
It seems to have to do with difficulties introspecting generic containers.
You have a strange usage of get().
http://jersey.java.net/nonav/apidocs/1.5/jersey/com/sun/jersey/api/client/UniformInterface.html#get%28java.lang.Class%29
Return and argument type should be the same.
Either:
ClientResponse resp = builder.get(ClientResponse.class);
or
Tag[] resp = builder.get(Tag[].class);
Anyway, it seems tha the problem is that your JSON data is an array and it is being deserialized into something that is not (Tags).
Try this directly:
Tag[] tags = response.getEntity(Tag[].class);