How to use JSTL within JSP declaration - java

I want to use JSTL within JSP declaration. I have code like:
<%! void fetchData(String .., String ..){
//some code...
pageContext.setAttribute("test",valueForJSTL); // Wont work until I pass pageContext from calling scriptlet
//some code...
%><%
//use pageContext variable set above to user in JSP (c:out, wcf:getData etc)**
%><%
}%>
I wonder why is it not allowed to used scriptlet (line 5-7) within JSP declaration. Or is there any other way to handle this?
I am calling above function from a scriptlet and I want this method to do some manipulation, add a variable in pageContext/request and fetch the variable in JSTL to fetch the data from DB .
You can find complete file at:
http://wikisend.com/download/738986/MyView.jsp
The JSTL within declaration "fetchCatalogEntries" is not working.

This is because the generated code for the scriptlet <% %>goes in the service method which is like called again and over the same object using multiple request threads
Whereas <%!, goes into the global class space or simply to declare methods and variables global for a JSP page.
Hence in your scriptlet you can call the method say fetchData() or any other like you would inside a service() method like in a normal java class.
You can even declare a field as below and refer it as in the example below :
<%!
private final Logger logger = new Logger(this.getClass());
private UserService userService = null;
public void jspInit() {
userService = new UserService();
}
private String getUserStatus(String userID) {
return userServce.getUserStatus(userID);
}
%>
<%
String userID = request.getParameter("userid");
String userStatus = getUserStatus(userID);
%>
Finally I would recommend you to NOT use scriptlets and use JSTL tags and libraries like the core-tag-libs and many others, these will help you in the long term.

Related

How to get class public string in JSP? [duplicate]

How do you reference an constants with EL on a JSP page?
I have an interface Addresses with a constant named URL. I know I can reference it with a scriplet by going: <%=Addresses.URL%>, but how do I do this using EL?
EL 3.0 or newer
If you're already on Java EE 7 / EL 3.0, then the #page import will also import class constants in EL scope.
<%# page import="com.example.YourConstants" %>
This will under the covers be imported via ImportHandler#importClass() and be available as ${YourConstants.FOO}.
Note that all java.lang.* classes are already implicitly imported and available like so ${Boolean.TRUE} and ${Integer.MAX_VALUE}. This only requires a more recent Java EE 7 container server as early versions had bugs in this. E.g. GlassFish 4.0 and Tomcat 8.0.0-1x fails, but GlassFish 4.1+ and Tomcat 8.0.2x+ works. And you need to make absolutely sure that your web.xml is declared conform the latest servlet version supported by the server. Thus with a web.xml which is declared conform Servlet 2.5 or older, none of the Servlet 3.0+ features will work.
Also note that this facility is only available in JSP and not in Facelets. In case of JSF+Facelets, your best bet is using OmniFaces <o:importConstants> as below:
<o:importConstants type="com.example.YourConstants" />
Or adding an EL context listener which calls ImportHandler#importClass() as below:
#ManagedBean(eager=true)
#ApplicationScoped
public class Config {
#PostConstruct
public void init() {
FacesContext.getCurrentInstance().getApplication().addELContextListener(new ELContextListener() {
#Override
public void contextCreated(ELContextEvent event) {
event.getELContext().getImportHandler().importClass("com.example.YourConstants");
}
});
}
}
EL 2.2 or older
This is not possible in EL 2.2 and older. There are several alternatives:
Put them in a Map<String, Object> which you put in the application scope. In EL, map values are accessible the usual Javabean way by ${map.key} or ${map['key.with.dots']}.
Use <un:useConstants> of the Unstandard taglib (maven2 repo here):
<%# taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
<un:useConstants className="com.example.YourConstants" var="constants" />
This way they are accessible the usual Javabean way by ${constants.FOO}.
Use Javaranch's CCC <ccc:constantsMap> as desribed somewhere at the bottom of this article.
<%# taglib uri="http://bibeault.org/tld/ccc" prefix="ccc" %>
<ccc:constantsMap className="com.example.YourConstants" var="constants" />
This way they are accessible the usual Javabean way by ${constants.FOO} as well.
If you're using JSF2, then you could use <o:importConstants> of OmniFaces.
<html ... xmlns:o="http://omnifaces.org/ui">
<o:importConstants type="com.example.YourConstants" />
This way they are accessible the usual Javabean way by #{YourConstants.FOO} as well.
Create a wrapper class which returns them through Javabean-style getter methods.
Create a custom EL resolver which first scans the presence of a constant and if absent, then delegate to the default resolver, otherwise returns the constant value instead.
The following does not apply to EL in general, but instead to SpEL (Spring EL) only (tested with 3.2.2.RELEASE on Tomcat 7).
I think it is worth mentioning it here in case someone searches for JSP and EL (but uses JSP with Spring).
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:eval var="constant" expression="T(com.example.Constants).CONSTANT"/>
You usually place these kinds of constants in a Configuration object (which has getters and setters) in the servlet context, and access them with ${applicationScope.config.url}
You can't. It follows the Java Bean convention. So you must have a getter for it.
I'm defining a constant in my jsp right at the beginning:
<%final String URI = "http://www.example.com/";%>
I include the core taglib in my JSP:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
Then, I make the constant available to EL by following statement:
<c:set var="URI" value="<%=URI%>"></c:set>
Now, I can use it later. Here an example, where the value is just written as HTML comment for debugging purposes:
<!-- ${URI} -->
With your constant class, you can just import your class and assign the constants to local variables. I know that my answer is a sort of quick hack, but the question also bumps up when one wants to define constants directly in the JSP.
I implemented like:
public interface Constants{
Integer PAGE_SIZE = 20;
}
-
public class JspConstants extends HashMap<String, String> {
public JspConstants() {
Class c = Constants.class;
Field[] fields = c.getDeclaredFields();
for(Field field : fields) {
int modifier = field.getModifiers();
if(Modifier.isPublic(modifier) && Modifier.isStatic(modifier) && Modifier.isFinal(modifier)) {
try {
Object o = field.get(null);
put(field.getName(), o != null ? o.toString() : null);
} catch(IllegalAccessException ignored) {
}
}
}
}
#Override
public String get(Object key) {
String result = super.get(key);
if(StringUtils.isEmpty(result)) {
throw new IllegalArgumentException("Check key! The key is wrong, no such constant!");
}
return result;
}
}
Next step put instance of this class into servlerContext
public class ApplicationInitializer implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute("Constants", new JspConstants());
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
add listener to web.xml
<listener>
<listener-class>com.example.ApplicationInitializer</listener-class>
</listener>
access in jsp
${Constants.PAGE_SIZE}
Static properties aren't accessible in EL. The workaround I use is to create a non-static variable which assigns itself to the static value.
public final static String MANAGER_ROLE = 'manager';
public String manager_role = MANAGER_ROLE;
I use lombok to generate the getter and setter so that's pretty well it. Your EL looks like this:
${bean.manager_role}
Full code at https://rogerkeays.com/access-java-static-methods-and-constants-from-el
Yes, you can. You need a custom tag (if you can't find it somewhere else). I've done this:
package something;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;
/**
* Get all class constants (statics) and place into Map so they can be accessed
* from EL.
* #author Tim.sabin
*/
public class ConstMapTag extends TagSupport {
public static final long serialVersionUID = 0x2ed23c0f306L;
private String path = "";
private String var = "";
public void setPath (String path) throws JspException {
this.path = (String)ExpressionUtil.evalNotNull ("constMap", "path",
path, String.class, this, pageContext);
}
public void setVar (String var) throws JspException {
this.var = (String)ExpressionUtil.evalNotNull ("constMap", "var",
var, String.class, this, pageContext);
}
public int doStartTag () throws JspException {
// Use Reflection to look up the desired field.
try {
Class<?> clazz = null;
try {
clazz = Class.forName (path);
} catch (ClassNotFoundException ex) {
throw new JspException ("Class " + path + " not found.");
}
Field [] flds = clazz.getDeclaredFields ();
// Go through all the fields, and put static ones in a Map.
Map<String, Object> constMap = new TreeMap<String, Object> ();
for (int i = 0; i < flds.length; i++) {
// Check to see if this is public static final. If not, it's not a constant.
int mods = flds [i].getModifiers ();
if (!Modifier.isFinal (mods) || !Modifier.isStatic (mods) ||
!Modifier.isPublic (mods)) {
continue;
}
Object val = null;
try {
val = flds [i].get (null); // null for static fields.
} catch (Exception ex) {
System.out.println ("Problem getting value of " + flds [i].getName ());
continue;
}
// flds [i].get () automatically wraps primitives.
// Place the constant into the Map.
constMap.put (flds [i].getName (), val);
}
// Export the Map as a Page variable.
pageContext.setAttribute (var, constMap);
} catch (Exception ex) {
if (!(ex instanceof JspException)) {
throw new JspException ("Could not process constants from class " + path);
} else {
throw (JspException)ex;
}
}
return SKIP_BODY;
}
}
and the tag is called:
<yourLib:constMap path="path.to.your.constantClass" var="consts" />
All public static final variables will be put into a Map indexed by their Java name, so if
public static final int MY_FIFTEEN = 15;
then the tag will wrap this in an Integer and you can reference it in a JSP:
<c:if test="${consts['MY_FIFTEEN'] eq 15}">
and you don't have to write getters!
You can. Try in follow way
#{T(com.example.Addresses).URL}
Tested on TomCat 7 and java6
Even knowing its a little late, and even knowing this is a little hack - i used the following solution to achieve the desired result. If you are a lover of Java-Naming-Conventions, my advice is to stop reading here...
Having a class like this, defining Constants, grouped by empty classes to create kind of a hierarchy:
public class PERMISSION{
public static class PAGE{
public static final Long SEE = 1L;
public static final Long EDIT = 2L;
public static final Long DELETE = 4L;
...
}
}
can be used from within java as PERMISSION.PAGE.SEE to retrieve the value 1L
To achieve a simliar access-possibility from within EL-Expressions, I did this:
(If there is a coding-god - he hopefully might forgive me :D )
#Named(value="PERMISSION")
public class PERMISSION{
public static class PAGE{
public static final Long SEE = 1L;
public static final Long EDIT = 2L;
public static final Long DELETE = 4L;
...
//EL Wrapper
public Long getSEE(){
return PAGE.SEE;
}
public Long getEDIT(){
return PAGE.EDIT;
}
public Long getDELETE(){
return PAGE.DELETE;
}
}
//EL-Wrapper
public PAGE getPAGE() {
return new PAGE();
}
}
finally, the EL-Expression to access the very same Long becomes: #{PERMISSION.PAGE.SEE} - equality for Java and EL-Access. I know this is out of any convention, but it works perfectly fine.
#Bozho already provided a great answer
You usually place these kinds of constants in a Configuration object (which has getters and setters) in the servlet context, and access them with ${applicationScope.config.url}
However, I feel an example is needed so it brings a bit more clarity and spare someone's time
#Component
public Configuration implements ServletContextAware {
private String addressURL = Addresses.URL;
// Declare other properties if you need as also add corresponding
// getters and setters
public String getAddressURL() {
return addressURL;
}
public void setServletContext(ServletContext servletContext) {
servletContext.setAttribute("config", this);
}
}
There is a workaround that is not exactly what you want, but lets you active almost the same with touching scriptlets in a quite minimal way. You can use scriptlet to put value into a JSTL variable and use clean JSTL code later in the page.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# page import="com.whichever.namespace.Addresses" %>
<c:set var="ourUrl" value="<%=Addresses.URL%>"/>
<c:if test='${"http://www.google.com" eq ourUrl}'>
Google is our URL!
</c:if>

JSP String To Java Class

I have a jsp page. Page have a requested field as string.
<% String token = ""+request.getParameter(); %>
In this jsp page also has a test class.
<%!
public static String usetoken()
{
String testtoken = ""+token;
}
%>
This usetoken class can not solve the token string. How can I solve that ? I need to call a string inside a class which inside a jsp page.
Thanks,
Firstly, as you may know, a jsp will be compiled to a servlet. All scriptlet code will be "inserted" into service() method and all declarations will be inserted to servlet class. So, for your situation, we'll have something like this(simplified):
public class FooServlet extends HttpServlet {
public static String useToken() {
String testtoken = ""+ token;
return testtoken;
}
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String token = ""+ request.getParameter();
}
}
As you see, userToken() method can't know about 'token' local variable inside service() method.
Also, you can't access HttpServletRequest in your jsp declaration, because it's a parameter of service() method.
BUT
You can use JSTL for something like this. You can declare variable:
<c:set var="token" value="${requestScope.token}"/>
And access it anywhere in your jsp using expression language(EL):
${token}
If you don't know, writing scriptlets inside your jsp considered bad practice. You need to do business logic somewhere outside and provide view as jsp. So use JSTL, your custom tags and EL.

how to pass values from jsp to java class

My Jsp page
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#page contentType="application/xml" trimDirectiveWhitespaces="true" %>
<%# page import="com.raos.kookooivr.CallStatusValues" %>
<c:choose>
<c:when test='${(param.event == "Conference" || param.event == "Hangup" || param.event == "Disconnect") && requestScope.state == "conferenceStarted"}'>
<%
String session_id = request.getParameter("sid");
out.print(CallStatusValues.getsessionid(session_id));
String called_no = request.getParameter("cid");
out.print(CallStatusValues.getcalledno(called_no));
String actualtime = request.getParameter("total_call_duration");
out.print(CallStatusValues.getactualtime(actualtime));
String start_time = request.getParameter("start_time");
out.print(CallStatusValues.getstarttime(start_time));
String end_time = request.getParameter("time");
out.print(CallStatusValues.getendtime(end_time));
%>
</c:when>
</c:choose>
My Java Class
package com.raos.kookooivr;
public class CallStatusValues
{
public static String getsessionid(String session_id)
{
System.out.println(session_id);
return session_id;
}
public static String getcalledno(String called_no)
{
System.out.println(called_no);
return called_no;
}
public static String getactualtime(String actualtime)
{
System.out.println(actualtime);
return actualtime;
}
public static String getstarttime(String start_time)
{
System.out.println(start_time);
return start_time;
}
public static String getendtime(String end_time)
{
System.out.println(end_time);
return end_time;
}
}
I am getting 500 Error.
I am trying to pass the values of "String session_id = request.getParameter("sid");" to my java class and trying to print the session id
public static String getsessionid(String session_id)
{
System.out.println(session_id);
return session_id;
}
I need help to get the values from jsp to be printed using my java class. Example my sid is 123456. Then, that session id should be passed from my jsp file to my java class.
I'm afraid there are multiple problems with your code.
You can't use static methods - web servlets are multi-threaded, and need model class instances per thread (which usually maps to an instance per web session).
Your naming conventions are non-standard. The correct name for your session_id variable is sessionId and the getter should be getSessionId() - note the capitalization. This meets the Java Bean naming conventions.
The way you are coupling code to the model class (which incidentally has nowhere to store the data) is non-standard.
Writing java code in a JSP is generally regarded as code smell for new projects. It is more normal to just use EL and tags in the JSP and move any Java code out into the model and controller.
I suggest you download a simple working J2EE JSP servlet project and analyse how it works. Then start to modify it to suit your requirements. Something like http://crunchify.com/servlet-tutorial-getting-starting-with-jsp-servlet-example should get you started.
Unsure that you are doing what you want to do.
Here is what actually happens :
a client sends a request that ends in calling the JSP page
the servlet container calls the JSP with the context of the calling request
the JSP runs server side with the context of the calling request meaning that:
nothing has been rendered at that time
all the parameters "sid", "cid", etc. are those that the caller passed
if any of the required parameters were not passed in calling request, you get a NullPointerException that ends in an Error 500
BTW using a class with static methods that way from a JSP, is at least uncommon... It could make sense if you need to be able to to complex computations inside the JSP, but in that case, you'd better use a servlet to do the processing, store result in request attribute and forward to the servlet.

How to access to object method called "get" on jsp to avoid using scriplets?

I have following library class:
public class LibClass{
public int get(int a, String b) {
....
return 12;
}
}
How to invoke following method on jsp?
I want to render 12 on jsp.
P.S.
I have restriction that I cannot use scriplets
You can do that using expression language. For ex
Assuming that you've a ${instance} in the scope
${instance.get(1,"test")}
There is another way. You can make a simple Bean which gets this value
public String getDATE(){
String Date = String.valueOf(new java.util.Date());
return Date;
}
and then call the above method with the following jsp tag
<jsp:useBean id="now" class="beans.PropertyBean" />
<jsp:getProperty name="now" property="DATE" />
you can use anything returned from the bean, In above snippet 'PropertyBean' is the name of my custom bean class. Hope this answers your question.

Handling events in Tapestry layout

I have a problem in my tapestry project.
Every time I load one page, it triggers onActivate method if is defined in the page in question. But I don't know how to catch that event in my layout template.
If I define a variable in the layout.java, for example:
#Property
String a = "foo";
And I pick that variable value at the template (layout.tml):
<p>${a}</p>
Ok, that will print "foo" in the HTML of all pages that use that layout, but If I want to change that value every time that the page reloads, for example defining onActivate in the layout.java.
void onActivate(){
a="bar";
}
This method doesn't trigger in the layout.java, only in the child pages when it's defined.
(In the child pages I include the layout like Nathan Q says) How can I refresh the variable value?
Any ideas?
I guess layout is a component in this case. Only pages have an activation context, that's why the onActivate() is not fired.
I don't know your exact use case, but:
If it's a page specific variable then you can just pass a parameter to your Layout component.
Layout.java
#Parameter
#Property
private String a;
SomePage.tml
<html t:a="someString" t:type="Layout" ... />
SomePage.java
#Property
private String someString;
...
void onActivate() {
someString = "something specific for this page";
}
OR
If this variable needs to be set every render and it's not a page specific value, you can just use the SetupRender event of your Layout component.
void setupRender() {
a = ...;
}
Ok, I find a way to refresh my property value.
And It was very simple:
Instead of declare a property and update that value in the onActivate method, I declare a public method in the layout.java to get that value and make the updating changes there.
private String a = "foo";
public String getA(){
a = "bar";
return a;
}
This way, I can make any changes to the a variable every time the page loads.

Categories