JSP declaration scriptlet access bean - java

I got a situation with a project I'm working on (not my code). I'm a somewhat beginner with JSPs, so it would be great to find out what happened.
So I have a code like this (it's a lot simplified):
<jsp:useBean id="accessManager" scope="session" class="AccessManager" />
<%! Object x = accessManager %>
<% Object y = accessManager %>
The second line doesn't work, it doesn't know what accessManager is. The third line (y) works.
I know that declaration scriptlets translate into java class attributes or methods, which are executed once when the jsp in initialized, and normal scriptlets (<% %>) are translated into the _jspService method. But what's the scope of the two? Or why can't I access the bean from the declaration scriptlet?
Thanks!

! is used to specify a no-context.
If you use <%! Object x = accessManager; %> it will produce Code like this.
class Index {
Object x = accessManager;
}
If you use <% Object x = accessManager; %> it will produce Code like this:
class Index {
public void foo(){
Object x = accessManager;
}
}
Look at C:\Program Files\apache-tomcat-*\work\Catalina\localhost\*\org\apache\jsp\ for the Generated .java-File.
(The example is simplyfied.)

Use either of the declaration depending on where you would like to add the code in the servlet.
Scriptlet of the form <% code %> that are inserted into the servlet's service method. So, it becomes part of your application logic.
Scriptlet Declarations of the form <%! code %> that are inserted into the body of the servlet class, outside of any existing methods. So, it becomes part of the servlet class. One very good use of it is to insert a method into servlet and use that method from within service method (under tag <% code %>) For ex:
<%!
public int sum(int a, int b) {
return a + b;
}
%>

Related

nullpointexception when i use those variables declared inside the scriptlet

I got the following code kind of inside of my <% %> in my jsp file.
Two problems here:
Why doesnt my breakpoint doesnt stop in those lines?
Why does have a nullpointerException happen when i use these variables somewhere inside my jsp like these <%=beneficiariesList%>. This value debugging in eclipse in the display view says " beneficiariesList cant be resolved" . For example tipoBeneciarioDatosClientes says the value which is "XXXX"
<% ...... bla bla bla
String tipoBeneficiarioDatosClientes = "XXXXX";
String beneficiariesList = "XXXXX";
if (null != polizaBean.xxxxx() && !polizaBean.getTipoBeneficiario().isEmpty()) {
tipoBeneficiarioDatosClientes = polizaBean.xxxxxx();
if(tipoBeneficiarioDatosClientes.equalsIgnoreCase("xxxxx")) {
JSONArray beneficiaries = JSONArray.fromObject(polizaBean.xxxxx());
beneficiariesList = beneficiaries.toString();
}
}
%>
You have a NullPointerException because variables which you are using inside Scriptlets <% ... %> are only available inside that scriplet.
If you want to declare variable which will be available in Expressions <%= %> you need to declare them inside a Declations block <%! %>.
From JSP 2.0 Specification :
Declarations are used to declare variables and methods in the
scripting language used in a JSP page.
...
Declarations are initialized when the JSP page is initialized and are made
available to other declarations, scriptlets, and expressions.

Scriptlets inserts arbitrary code into servlet's _jspService method

Scriptlets let you insert arbitrary code into servlet's _jspService method.
Can anyone explain this statement with an example containing a block of code?
I am aware about syntactical stuff of JSP and Servlets, what I need to know is
In what context arbitrary code is used?
_jspService() is a method of JSP life cycle then,
What does it mean by servlet's method?
A JSP is in fact transformed by the container into a Java class extending HttpServlet, that class is then compiled and executed exactly as a hand-coded servlet would be.
The code you have into the JSP is transformed into Java code that constitutes the _jspService method of the generated servlet. So, for example
<html>
<% String foo = "hello"; out.println(foo); %>
is transformed by the container, into something like
void _jspService(JspWriter out) {
out.println("<html>");
String foo = "hello"; out.println(foo);
}
So, whatever code you write into your scriptlets (arbitrary code) ends up in the _jspService method of the servlet created by the container from the JSP.

JSP inner function printing

Should be direct HTML printing in a JSP declaration tag function legal?
<%! void recursivePaintLevels(List<String> things, int deepLevel){ %>
<ul class="level-<%=deepLevel%>">
<% for (int i=0; i<things.size(); i++){ %>
<li class="whatever">
//(...)
</li>
<% } %>
</ul>
<% } %>
And then call it like this in normal JSP body flow:
//(...)
<% recursivePaintLevels(things, 1); %>
I mean would be like using same normal JSP logic of implicit out.println() but in a method.
For me it is not working (Eclipse says 'Syntax error, insert "Finally" to complete TryStatement') but I am not sure if my error has something to do with it.
I also know I should use JSLT and EL, but this is my choice.
No, it's not legal. The JSP page is effectively implemented as one big method that executes all of the code within the page. In java, you can't simply insert other methods nested within a method.
You code would generate something like this:
public void _jspService(...) {
...
void recursivePaintLevels(...) {
...
}
}
And that's simply not legal java.
Instead you should defer the code to a utility library class bundled with your web app.
You MIGHT be able to create a recursive tag file, I have not tried that.
I believe this is pretty much legal and valid though a bad practice.I think the problem here is because of the double quotes "level-<%=deepLevel%>"
Try separating that using
<% String str= "level-"+deepLevel; %>
and then use
<ul class="<%=str%>"> .
or simply replace the whole line with out.println
EDIT:
It appears that the body of the methods in jsp should not have any scriptlets. I have tried to embed one scriptlet with no content and observed that the generated java file adds the first part (from delcaration to the content before scriptlet )at the begging and the remaining part of the method at the end (and all member variables and other method declarations become part of this method). Apologies for providing wrong answer (as i have noticed that behavior with the cached jsp).
Looks like out.prinltn is the only solution for this problem

how to call inner class method or variable from outer jsp?

this is my index.jsp page:
<html>
<body>
<%!
public class myclass{
private final int foo = 42;
public int getFoo() {
return foo;
}
}
%>
</body>
</html>
how to call myclass method or variable in other jsp page ?
please help me .
You don't from any "other" JSP. Those declarations should be treated as local to the JSP. If you need a class to be used by multiple JSPs, write it as a separate Java source file, compile it, and include it in your webapp in WEB-INF/classes.
Did you try to use something like
<%# include file="/myFile.jsp" % >
???

How to write a JSP which renders a list of JSP fragments, without IF switching code

I have a JSP which composes a List of Objects, then renders JSP fragments depending on the Class of each of the objects in the List.
At the moment, this is done with a huge chain of if statements inside the 'parent' JSP:
if( bean.getFilterChildByType( Level.class ) != null )
{
%> <jsp:include page="filters/level.jsp"/> <%
}
if( bean.getFilterChildByType( Sources.class ) != null )
{
%> <jsp:include page="filters/sources.jsp"/> <%
}
...
So, my question is, in JSP (Tomcat) is it possible to achieve this same functionality without an if chain, just by iterating the Objects in the list and perhaps taking advantage of the naming convention "Class name".jsp ? I've played with:
<%# include file="filename" %>
but this doesn't seem to allow variables in the file-name either.
Something like this should work
<jsp:include page="filters/<%=filename%>.jsp"/>
Resolve the appropriate jsp to be included (based on bean.getFilterChildByType) at the controller side and then just pass the name of the jsp to the container jsp. Now this can be easily included.
This is a tough one!
If the included jsp files (level.jsp, source.jsp, etc) are not too complex, what about shifting the HTML from those files over to a function call of the objects you are calling bean.getFilterChildByType(...) on?
That way, instead of a large if/else tree, you could then just call:
String html = bean.getHtmlForType();
...would likely work out much cleaner in a loop too.

Categories