JSP, JavaScript, and Java Objects - java

I have a JSP where I'm using a javascript framework to build a chart using the Google Visualization API.
My servlet is returning a sales hashmap object with year as the key and integer (sales number) as the value.
My javascript uses the sales object to add data to the Google chart API which builds my chart.
code:
sales = '<%= session.getAttribute("sales") %>';
The sales object in my js gets the hashmap but it's a long string. Do I have to parse it in my javascript or is there a way it will automatically put the hashmap object properly into the javascript sales object?

you wont need to use an external json library (but you could!) - you can print out the json directly into a javascript variable like:
<%# taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<script>
(function(){
var sales = {
<c:forEach var="entry" items="${requestScope['sales'].entrySet}" varStatus="counter">
'${entry.key}' : ${entry.value} //outputs "2000" :1234 ,
<c:if test="${!counter.last}">, </c:test>
</c:foreach>
};
//js code that uses the sales object
doStuffWith(sales);
})()
</script>

Java and Javascript are completely different languages. Javascript doesn't know what do do with a Java HashMap object (actually in your example you'll get the output of HashMap.toString()). You'll have to serialize it into some form that Javascript will understand, eg. JSON.

Try using JSON which will allow you to describe your Java object in json ( java script object notation ) That way you can load the described object directly into javascript.

All this piece of code
sales = '<%= session.getAttribute("sales") %>';
does is print the value of session.getAttribute("sales") to the HTML output. Without any logic on your part as to how to format the output, Java will merely call .toString() on that Object - which the default implementation (unless you override it) usually results in an output that looks like classname#1234abc12.
So the short answer is that yes you will need to put in some logic on the Java side as far as how you would like your object / data structure to be output into the HTML document.

Related

Multiple inline insert using Ajax & JSP [duplicate]

I have a JSON object sent from the browser to the jsp page.How do I receive that object and process it in jsp.Do I need any specific parsers? I have used the following piece of code.But it wouldn't work.Essentially I should read the contents of the object and print them in the jsp.
<%#page language="java" import="jso.JSONObject"%>
<%
JSONObject inp=request.getParameter("param1");
%>
<% for(int i=0;i<inp.size();i++)
{%>
<%=inp.getString(i)%>
<%
}
%>
My preferred solution to this problem involves using a JSON parser that provides an output that implements the java.util.Map and java.util.List interface. This allows for simple parsing of the JSON structure in the JSP Expression language.
Here is an example using JSON4J provided with Apache Wink. The sample imports JSON data from a URL, parses it in a java scriptlet and browses the resulting structure.
<c:import var="dataJson" url="http://localhost/request.json"/>
<%
String json = (String)pageContext.getAttribute("dataJson");
pageContext.setAttribute("parsedJSON", org.apache.commons.json.JSON.parse(json));
%>
Fetch the name of the node at index 1 : ${parsedJSON.node[1].name}
To make this clean, it would be preferable to create a JSTL tag to do the parsing and avoid java scriplet.
<c:import var="dataJson" url="http://localhost/request.json"/>
<json:parse json="${dataJson}" var="parsedJSON" />
Fetch the name of the node at index 1 : ${parsedJSON.node[1].name}
You can parse the input string to JSONValue and then cast it to JSONOject as like shown below
JSONObject inp = (JSONObject) JSONValue.parse(request.getParameter("param1"));
The svenson JSON library can also be used from JSP.
You've got several syntax errors in your example code.
First, request.getParameter returns a String, so setting it to a JSONObject won't work. Secondly, your for loop is incomplete.
I suggest looking into the various JSON libraries available for Java and using one of those.
To help get you started, I'd look at some decoding samples.
In general, you won't be passing JSON within query parameters -- too much quoting needed. Rather, you should POST with JSON as payload (content type 'application/json') or such.
But beyond this, you need a json parser; Json.org lists tons; my favorite is Jackson, which like most alternatives from the page can also be invoked from jsp.

Fetchinng JSON data from servlet to display on JSP [duplicate]

I have a form in JSP. I have to populate it based on the request object (from the servlet). How do I use Java Script for accessing request object attributes or if you can suggest me any other better way to populate form dynamically?
You need to realize that Java/JSP is merely a HTML/CSS/JS code producer. So all you need to do is to just let JSP print the Java variable as if it is a JavaScript variable and that the generated HTML/JS code output is syntactically valid.
Provided that the Java variable is available in the EL scope by ${foo}, here are several examples how to print it:
<script>var foo = '${foo}';</script>
<script>someFunction('${foo}');</script>
<div onclick="someFunction('${foo}')">...</div>
Imagine that the Java variable has the value "bar", then JSP will ultimately generate this HTML which you can verify by rightclick, View Source in the webbrowser:
<script>var foo = 'bar';</script>
<script>someFunction('bar');</script>
<div onclick="someFunction('bar')">...</div>
Do note that those singlequotes are thus mandatory in order to represent a string typed variable in JS. If you have used var foo = ${foo}; instead, then it would print var foo = bar;, which may end up in "bar is undefined" errors in when you attempt to access it further down in JS code (you can see JS errors in JS console of browser's web developer toolset which you can open by pressing F12 in Chrome/FireFox23+/IE9+). Also note that if the variable represents a number or a boolean, which doesn't need to be quoted, then it will just work fine.
If the variable happens to originate from user-controlled input, then keep in mind to take into account XSS attack holes and JS escaping. Near the bottom of our EL wiki page you can find an example how to create a custom EL function which escapes a Java variable for safe usage in JS.
If the variable is a bit more complex, e.g. a Java bean, or a list thereof, or a map, then you can use one of the many available JSON libraries to convert the Java object to a JSON string. Here's an example assuming Gson.
String someObjectAsJson = new Gson().toJson(someObject);
Note that this way you don't need to print it as a quoted string anymore.
<script>var foo = ${someObjectAsJson};</script>
See also:
Our JSP wiki page - see the chapter "JavaScript".
How to escape JavaScript in JSP?
Call Servlet and invoke Java code from JavaScript along with parameters
How to use Servlets and Ajax?
If you're pre-populating the form fields based on parameters in the HTTP request, then why not simply do this on the server side in your JSP... rather than on the client side with JavaScript? In the JSP it would look vaguely like this:
<input type="text" name="myFormField1" value="<%= request.getParameter("value1"); %>"/>
On the client side, JavaScript doesn't really have the concept of a "request object". You pretty much have to parse the query string yourself manually to get at the CGI parameters. I suspect that isn't what you're actually wanting to do.
Passing JSON from JSP to Javascript.
I came here looking for this, #BalusC's answer helped to an extent but didn't solve the problem to the core. After digging deep into <script> tag, I came across this solution.
<script id="jsonData" type="application/json">${jsonFromJava}</script>
and in the JS:
var fetchedJson = JSON.parse(document.getElementById('jsonData').textContent);
In JSP file:
<head>
...
<%# page import="com.common.Constants" %>
...
</head>
<script type="text/javascript">
var constant = "<%=Constants.CONSTANT%>"
</script>
This constant variable will be then available to .js files that are declared after the above code.
Constants.java is a java file containing a static constant named CONSTANT.
The scenario that I had was, I needed one constant from a property file, so instead of constructing a property file for javascript, I did this.
In JSP page :
<c:set var="list_size" value="${list1.size() }"></c:set>
Access this value in Javascipt page using :
var list_size = parseInt($('#list_size').val());
I added javascript page in my project externally.

How to compare hash map key dynamically inside the closure in Grails?

Here I have hash map passed from the controller to GSP page.
Controller:
Map<String, List<String>> nameFiles = new HashMap<String, List<String>>();
nameFiles.put('patient1',["AA","BB","CC"]);
nameFiles.put('patient2',["DD","EE","FF"]);
model.put("nameFiles", nameFiles);
GSP page:
var patient = getPatient(); // lets say we get random patient through some jQuery function, could be not available in the nameFiles key
//check If nameFiles contain key same as patient varaible
<% nameFiles.each { fm -> %>
<% if (fm.containsKey(patient)) { %> // This if statement cannot compare dynamic sting varaaible. How to do this.
alert("Yes nameFiles contain the patient");
<% } %>
<% } %>
Assuming you have :
Map<String, List<String>> nameFiles = new HashMap<String, List<String>>();
nameFiles.put('patient1',[id:1,name:'Fred'])
nameFiles.put('patient2',[id:2,name:'Tom'])
It is as simple as this to get current patient:
<% def aa = nameFiles?.find{it.key=='patient1'}?.value %>
<g:if test="${aa}">
// we definitely have ${aa} and it has been made null safe
<g:if>
This returns {id:1, Name:Fred} on gsp which is the list iteration
My goodness all that else if it is as if you are in a controller, I understand why you are having to do this but it isn't good practice you could just create a tagLib that takes current value and processes the entry according to something in a given list or maybe against db fresh on the fly all correctly presented produced.
Final edit whilst you can declare variables like jsp you can also use
<g:set var="aa" value="${nameFiles?.find{it.key=='patient1'}?.value}" scope="page|session|..."/>
By default variable is set for the page but could be made into a session variable either way it is a lot cleaner than <% %>
Hopefully final edit
I think people should think carefully about what their actual problem is and try to present the problem clearly otherwise the audience ends up answering something else due to the poor quality of the post.
If I understand correctly you have something happening in a controller as in some list being produced. The missing bit must be you are then doing some form of form check maybe a select box selection that then ends up in jquery by that you mean you have some form of java script check going on against a form field check.
There are two ways of pumping such information into the javascript world for such purposes
Method 1:
//I haven't tested this, hopefully gives you the idea
var array = []
<g:each in="${namedFiles}" var="${pa}">
array.push({code:'${pa.key} listing:'${pa.value}'})
</g:each>
Method 2
Controller
//where you now push named files as a json
return [namedFiles as JSON].toString()
// or alternatively in gsp javascript segment something like this
var results=$.parseJSON('<%=namedFiles.encodeAsJSON()%>');
var results = results['patient1']
Honestly speaking I didn't get what are you asking and what kind of problem do you have as a result, but I guess that you tried to implement something like that:
<g:if test="${nameFiles[patient]}">
alert("Yes nameFiles contain the patient");
</g:if>
As you may be noticed I tried to avoid the scriptlet mess and used grails custom tags.
Also I hardly imagine how are you going to call the jQuery function to get a variable and then use it for generating a view on the server side. But try to define some mock "patient" variable at first to test my sample.
If the "patient" variable value is only available at the client side - so you have to change the approach and generate your alerts not on the server.
UPD
From the other hand you could return your nameFiles as JSON in your controller and then parse this JSON with javascript on the client side like that:
var nameFiles = JSON.parse("${nameFiles}")
if (nameFiles.hasOwnProperty(patient)) {
alert("Yes nameFiles contain the patient");
}
I haven't test this code, but at least you are pointed that gsp are rendered on server and you can convert your map to JSON, pass it to the view, parse with JavaScript and generate the needed alert.
Variable Declaration in GSP
You can declare variables within <% %> brackets:
<% patientIdentifier = 'randomName' %>
For more details see the Grails documentation on Variables and Scopes.
Checking if Patient is contained in namedFiles
You don't need to iterate over the map. Just checking the map if it contains the key.
// check if nameFiles contains key same as patient variable
<% if (nameFiles.containsKey(patient)) { %>
alert("Yes nameFiles contains the patient");
<% } %>

Converting array from Spring bean into JSON to reference in JSP

My aim is to take an array of objects from a Spring bean and convert these to a JSON object to be referenced in a JavaScript. I'm trying to do this all in JSP.
The key components are :
homePageManager - Spring Bean which manages home pages for users. I have made this visible as a bean through 'InternalResourceViewResolver'.
getHomePages - Method on homePageManager which returns List
static String UIUtils.toJSONObject(object) - utility method which converts any object to its JSON equivalent (basically wrappers call to Jackson lib)
I want to take the returned object, convert it to its JSON equivalent, and use this in Javascript for switching between tab pages, all through JSP.
But because of my limited knowledge of JSPs/Javascript etc. I'm tying myself in knots here.
The Javascript part which handles the JSON object afterwards etc. is all working fine as I've 'mocked' the JSON object with static values to test it. It's just the plumbing in between.
I could create a method on homePageManager which returns a JSON-version of the tablist, but for me this is wrong as it is not the responsibility of this bean to do that.
One of my latest attempts is :-
<%# page import="com.adv.e5ahr.jasperserver.ui.utils.UIUtils" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="tabList" value="${homePageManager.getHomePages()}"/>
<script>
var tabs = ${tabList};
console.log('tabs='+tabs));
var tablist = <% UIUtils.toJSONObject(tabs); %>;
console.log('tablist=' + tablist);
...
</script>
If you say that homePageManager is not responsible to create a JSON-version of tablist, then you can always create a bean which does this translation for you.
Before loading this jsp, add the json to the model / session and only do the dom modifications in java script. Having scriptlets on your page is probably not a good idea.

How can I access Java list elements from my client-side JavaScript code?

I have the following simple script, which I am using to dynamically create the list elements in a <ul>
<script type="text/javascript">
function generate(){
var arr = new Array();
<c:forEach items="${articles}" var="a" varStatus="status">
$('#listitems').append(
"<li>"+${a.title}+"</li>"
);
arr[${status.index}] ="${a.slideShow.images}";
</c:forEach>
}
</script>
My problem stems from the images attribute. Every article has a slideshow and every slideshow has a list of images. I want to pull out the very first image from the list of images via the jave list.get(index); I want to do something like "${a.slideShow.images.get(0)}";. The get() is a java method from the list object.
Any ideas?
In EL you can use the brace notation to access a List element by index. Thus, the following should do:
arr[${status.index}] = "${a.slideShow.images[0]}";
This will behind the scenes do exactly as you proposed: a.getSlideShow().getImages().get(0).
That said, you normally declare JS arrays like follows:
var arr = [];
The new keyword is considered discouraged in JS.
As those who commented on your question suggest, this is a common misunderstanding. By the time your JavaScript executes (in the browser), Java and JSP and JSTL are no longer available. The JSTL/JSP execute at the server to create source/HTML that is then sent to the client.
View source on your page - it might shed some light. You should not see the JSP/JSTL you include above.

Categories

Resources