JSP Expression Language on Jackson's JsonNode
Let's say I'm using Spring and have a controller that returns a model containing a field data
that is an instance of Jackson's ObjectNode
. Within data
I have a StringBuilder
named log
.
In the JSP I use
${data}
and I get this output:
{"log":hello world}
Now if I want to access log
I thought I could use
${data["log"]}
but all I get is
javax.el.PropertyNotFoundException: Property 'log' not found on type org.codehaus.jackson.node.ObjectNode
javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:214)
javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:191)
javax.el.BeanELResolver.property(BeanELResolver.java:300)
javax.el.BeanELResolver.getValue(BeanELResolver.java:81)
javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
org.apache.el.parser.AstValue.getValue(AstValue.java:123)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:938)
:
${data.log}
shows the same.
I know that according to the EL data.log
looks for a method getLog()
on data
, but IIRC Maps<开发者_运维技巧;?,?>
support this kind of access to its keys. Is there any similar way to make it work with Jackson? Or if that just doesn't work this way, how would you do this?
I haven't worked with EL in a while, so I'm guessing a bit...
Since ObjectNode
does not implement Map
and does not define a property getter for "log", perhaps a different approach is necessary. (I'm guessing the example EL only works on Map
instances and beans.)
Instead of putting Jackson implementations in your view (the JSP), does it make sense to populate an appropriate Java structure (without any Jackson classes in it) from the data in the Jackson structure, and then just pass the view the Jackson-free Java structure? Then, binding Java data to view elements would be more straightforward.
Since one of Jackson's strengths is generally making it very easy to populate Java structures from JSON data, I'd think this approach would be relatively easy.
Now that I revisited this issue, I wrote my own ELResolver for ArrayNode and ObjectNode. Helpful links were
- http://java.sun.com/products/jsp/reference/techart/unifiedEL.html#Features_of_the_Unified_EL (look for "Writing an ELResolver Implementation")
- http://pukkaone.github.com/2011/01/03/jsp-cross-site-scripting-elresolver.html
EDIT:
As far as the ArrayNode is concerned, it helped me to look at Tomcat's ArrayELResolver. It's pretty easy to go from there.
精彩评论