This question already has answers here:
How to reference constants in EL?
(12 answers)
Closed 6 years ago.
I have a class that defines the names of various constants, e.g.
class Constants {
public static final String ATTR_CURRENT_USER = "current.user";
}
I would like to use these constants within a JSP without using Scriptlet code such as:
<%# page import="com.example.Constants" %>
<%= Constants.ATTR_CURRENT_USER %>
There appears to be a tag in the Apache unstandard taglib that provides this functionality. However, I cannot find any way to download this taglib. I'm beginning to wonder if it's been deprecated and the functionality has been moved to another (Apache) tag library?
Does anyone know where I can get this library, or if it's not available, if there's some other way I can access constants in a JSP without using scriptlet code?
Cheers,
Don
On application startup, you can add the Constants class to the servletContext and then access it in any jsp page
servletContext.setAttribute("Constants", com.example.Constants);
and then access it in a jsp page
<c:out value="${Constants.ATTR_CURRENT_USER}"/>
(you might have to create getters for each constant)
Turns out there's another tag library that provides the same functionality. It also works for Enum constants.
Looks like a duplicate of accessing constants in JSP (without scriptlet)
My answer was:
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
What kind of functionality do you want to use?
That tag sould be able to access any public class field by class name and field name?
Scriptlets linking done at compile time but taglib class field access has to use such java API as reflection at runtime. Do You really need that?
I'll use jakarta-taglibs-unstandard-20060829.jar in my project but, you're true, it seems not available for download anymore.
I've got that in my pom.xml in order to get that library but I think It will work only because that library is now on my local repository (I cannot find it in official repositories) :
<dependency>
<groupId>jakarta</groupId>
<artifactId>jakarta-taglibs-unstandard</artifactId>
<version>20060829</version>
</dependency>
I do not know if there's another alternative.
I hope so because it was a good way to access constants in JSP.
Why do you want to print the value of the constant on the JSP? Surely you are defining them so that in the JSP you can extract objects from the session and request before you present them?
<%# page import="com.example.Constants" %>
<%# page import="com.example.model.User" %>
<%
User user = (User) session.getAttribute(Constants.ATTR_CURRENT_USER);
%>
<h1>Welcome <%=user.getFirstName()%></h1>
Related
This question already has answers here:
Check a collection size with JSTL
(4 answers)
Closed 6 years ago.
This is a simple question, I should know the answer and I'm ashamed to admit I don't. I am sending a compound object to my JSP page:
public class MyObject {
private List<MyFoo> myFoo;
public getMyFoo();
public setMyFoo();
}
// In the controller...
model.addAttribute("myObject", myObject);
When this goes into the JSP page I can address the model instance of myObject as:
${myObject}
and the list inside as
${myObject.myFoo}
What I want to do is list the size of myFoo on my JSP output, like so:
${myObject.myFoo.size}
But of course size() is not a bean property, so a JSPException is thrown.
Is there a simple, elegant way of doing this in the JSP page or do I need to stick another attribute on the model and put the size in there?
You could use JSTL tag libraries, they are often useful for common JSP operations. Here's a quick reference:
https://code.google.com/p/dlcode/downloads/detail?name=jstl-quick-reference.pdf
Include the taglib with this line:
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
Then your case would be:
${fn:length(myObject.myFoo)}
One plausible (but may not be elegant enough) way is to add a getter function:
public getMyFooSize() { return myFoo.size(); }
And then use the following in JSP:
${myObject.myFooSize}
I'm working on a componentization system based on JSPs. This means that parts of the JSP can be moved from one JSP to an other one via drag and drop and leads to a need for a local page scope as variable of a component defined in one JSP my collide in an other JSP.
I can use Servlet 3.0 / JSP 2.2 / JSTL 1.2.
++ Tag File ++
The straight way of doing that would be to create a tag file for a component or something similar as they have this local page scope. But for every change in the tag file it would need to get redeployed and needing to create a tag file needs some time by itself. But if there is no other solution this direction (custom tags, tag files, JSP includes,...) is probably the way to go.
++ Namespace prefixing/suffixing ++
In Portlets one is supposed to concatenate each variable with a namespace provided from the portlet response object. I could do something similar but this can lead to side effects and unexpected behavior. If someone forgets to prefix/suffix the namespace it might work for some time but stops working at an other time without changing the code when the component moved to an other JSP with a conflicting variable name.
++ Custom Tag wrapping ++
I was hoping that I as a component framework developer can wrap the component code of a component developer with a tag file for a component tag like this
<a:component>
<div data-component-id="9">
<c:set var="componentId" value="9"/>
<c:set var="path" value='${abc:getCurrentPath()}_${componentId}'/>
<c:set var="resource" value='${abc:getResourceFromPath(path)}'/>
<c:set var="val" value="${resource.getValue('paragraphValue')"/>
<p><c:out value="${value}"/></p>
</div>
</a:component>
to have the variable in the local page context of the tag file. But instead they are in the context of the surrounding page. I'm looking for something like this
<% { %>
<div data-component-id="9">
<%
String componentId = 9;
String path = obj.getCurrentPath()+componentId;
Resource resource = otherObj.getResourceFromPath(path);
String value = resource.getValue("paragraphValue");
%>
<p><c:out value="<%=value%>"/></p>
</div>
<% } %>
which would create a code block in which variables have their own namespace. But of course for JSTL and JSTL-EL instead of scriptlet code.
I had a look at the JSTL specification but did not find out if there is a way to create such a local page scope. But I didn't check everything as it's huge and I'm not sure if it's possible with custom tags.
It is clear to me that bigger code blocks should not be in the JSP but with the framework I would like to provide simple solutions for smaller components.
++ Changing the JSP code ++
When components are initially placed on a JSP or moved around via drag 'n drop I actually move the JSP code of a component from one JSP to an other or within a JSP. This means I can also programmatically manipulate the JSP code of a component if it doesn't get too complex and it helps solving the problem.
As I thought that custom tag wrapping could be the ideal solution I created an other more specific question and I've got an answer here that solves the problem.
It's simply to remove all pageContext attributes before the evaluation of the body and adding them again at doEndTag().
I am having trouble referencing a static inner class in a JSP tag file. I am using Glassfish Jersey and Jetty 6.1.X. I am using JSP 2.0 and tagfiles, and I don't have any TagHandler classes or any .tld files. My web.xml also doesn't contain anything specific about JSPs or tag files.
I have broken down the problem into the smallest reproducible:
This is the structure of the class I am using:
package test;
public class OuterClass {
public static class InnerClass {
}
}
This is the complete contents of my .tag file:
<%# attribute name="inner" required="true" type="test.OuterClass.InnerClass" %>
<h1>${inner}</h1>
(The tag file shows an error in IntelliJ):
I use this tag in my parent jsp like so:
<%#taglib tagdir="/WEB-INF/tags" prefix="test" %>
<test:test inner="${inner}"/>
The exception that I get when attempting to use it this way is:
org.apache.jasper.JasperException: /WEB-INF/jsp/test.jsp(54,4)
Unknown attribute type (test.OuterClass.InnerClass) for attribute inner
If I change the type to use the binary notation (OuterClass$InnerClass) I get this error instead:
The nested type test.OuterClass$InnerClass cannot be referenced using its binary name
I have searched Google for this and found others with the same problem, but all of these seem to have been resolved by a fix to Jasper years ago.
https://issues.apache.org/bugzilla/show_bug.cgi?id=41824
https://issues.apache.org/bugzilla/show_bug.cgi?id=35351
I have bypassed the problem by splitting the class into many top level classes instead, but the nested classes in my use case necessarily belong to the top level class, and shouldn't be used outside of this so it feels wrong to change the design due to the limitation I am finding here.
If there is a way to properly used static nested classes in a tag attribute, then that would be the ideal solution.
I have a class language having features ID and Name.
I have another class Language_List that has ArrayList<language> lang as a member variable.
In my JSP page I want to access the Name variable of ArrayList<language> lang using EL and For each Loop.
<c:forEach var="language" items="${languages.lang}">
${language}<br>
</c:forEach>
However, it doesn't show ant result and intellisense doesn't work too. Anyone who can help me with this
PS: languages is a Bean variable contain list of languages from DB
I tried this and got this
<b>${languages.lang}</b>
HTML
[sakila.language#f1541c, sakila.language#63c8fabf, sakila.language#1fc644c7, sakila.language#11cd751d, sakila.language#47c3cc0c, sakila.language#7894ca3, sakila.language#47066532, sakila.language#74ddda0b, sakila.language#1116441e, sakila.language#4cd21655, sakila.language#74b84dd9, sakila.language#6fff1d6c, sakila.language#55e4d6e5, sakila.language#22d88071, sakila.language#33d88c96, sakila.language#4df5e671, sakila.language#4aec2cb3, sakila.language#576ac232, sakila.language#76a6dbd7, sakila.language#44ab3d1c, sakila.language#46391c7c, sakila.language#4f7d34e8, sakila.language#251c941d, sakila.language#77400ef3]
The EL doesn't access fields of your objects. It accesses bean properties of your objects. This means that ${languages.lang} is translated to a call to languages.getLang().
If you don't have such a getter, you'll get an exception though. If it just doesn't display anything, it's probably because languages is null, or because its lang list is null or empty. To confirm or infirm those guesses, we need to see the code where you create and populate the bean and its list of languages, and where you store it somewhere to make it accessible from the JSP.
Another possibility is that you forgot to declare the core taglib at the beginning of the JSP. To confirm or infirm that, paste the code of the JSP, and the HTML code generated by the JSP (using View page source in the browser)
How can I expose a Java bean to a JSP page by using struts? I know how to configure a StrutsAction to include a form-bean, but I wonder if there are other ways to interact with Java code from a JSP page? I ask this question because I don't understand fully a likely answer to a problem that I have asked here:
Clean way for conditionally rendering HTML in view?
EDIT:
I understand that a JavaBean is defined as a class that contains mainly getters and setters for its properties.
My problem was that I did not see how I can access parameters from Java classes in my JSP. Currently, I use a DynaForm to communicate parameters to the view. E.g. in the ActionClass I set the parameter, and in the JSP I can access it with
bean:write name="MyFormBean" property="myParameter"
My question was basically if there are other classes than a DynaForm class that can easily be accessed from inside the JSP with tags, and if so, if someone could provide an example.
In your action class:
MyBean myBean = new MyBean();
myBean.setSomeProperty("someValue");
request.setAttribute("myBean", myBean);
In your JSP:
<bean:write name="myBean" property="someProperty" scope="request"/>
You can do the same with session as well. Note that you don't have to explicitly specify the scope in <bean:write> tag - if you don't, Struts will look in all scopes from page to application.
More information on scopes is available in Java EE tutorial.