Is it possible to use Spring SpEL expression in c:set to instantiate new class? - spring

I would like to do something like:
<c:set var="customer" value="${new com.test.Customer()}" />
but this doesn't work.
Is there something like this possible?

You can use the new spring:eval JSP tag that allows you to evaluate SpEL expressions from JSP pages, instead of c:set.

Related

Can I use Spring Expression Language in an "alias" definition?

I am trying to create an alias in a spring context config like this:
<alias name="#{ ... code to lookup from config file ...}" alias="BeanName"/>
but it doesn't seem to execute the EL in the "name" attribute. Is this not allowed?
It's not that it's not allowed, it's that there is no registered BeanExpressionResolver for aliases. You can use property placeholders ${}, but that's a whole different component that handles it.

How to disable interpolation of property values in property placeholders

I'm using Spring 3 and Spring's property-placeholders in my application context:
<context:property-placeholder location="my.properties"/>
my.properties contains:
key1=value1
key2=some JSP code ${some-model-attr}
The issue is, the values in my.properties are also evaluated against the placeholders, but in my case the values contain JSP EL, which causes "property not found" errors during Spring initialization:
java.lang.IllegalArgumentException: Could not resolve placeholder 'some-model-attr'
So far I have this workaround, but it's ugly:
key1=value1
key2=some JSP code #{'$'}{some-model-attr}
Hence my question:
Is it possible to tell Spring not to interpolate property placeholder values, or, in other words, not to evaluate placeholders recursively?
It looks like it isn't possible to tell Spring not to recursively evaluate placeholders.
The placeholders are evaluated by org.springframework.util.PropertyPlaceholderHelper which (in Spring 3) contains the following line:
// Recursive invocation, parsing placeholders contained in the placeholder key.
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
So the recursive call is hard-coded into the evaluation.
However I think you could change the default prefix and suffix for placeholders so that you use a different syntax for Spring placeholders. <context:property-placeholder> is just a convenient way of constructing the org.springframework.beans.factory.config.PropertyPlaceholderConfigurer class, and that class has methods setPlaceholderPrefix() and setPlaceholderSuffix(). You could use those methods to change the syntax of the Spring placeholders to something like:
$[property]
instead of
${property}
Then I expect Spring won't parse your JSP properties any more because they're in a different syntax:
key2=some JSP code ${some-model-attr}
As a workaround you can use SpEL expression templating. For example:
key2=some JSP code $#{'{some-model-attr}'}
This works because Spring no longer sees the configured property placeholder prefix of ${. However, the SpEL expression evaluates to the String concatenation of:
'some JSP code $' + '{some-model-attr}'
which is the same as
some JSP code ${some-model-attr}

Replacement for spring form tag in facelets

since I know I can't use the Spring tag library in Facelets, I wonder if anyone can tell me what should I use instead of
<sf:form method="POST" modelAttribute="spitter">
.....
</sf:form>
Where prefix sf refers to (in JSP only):
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
I really like the idea of this form, that it binds all properties directly to modelAttribute object.
Is there any possibility that <h:form>...</h:form> can do the same?
Or is there any other tag, that can handle it?
I can't use JSP because i want to use PrimeFaces.
I'm just a beginner in J2EE, so please be patient :)
Thank you in advance
Yes, <h:form> does a similar thing. Even though the JSF approach is a bit different, the end result is similar: With spring the object gets submitted, and with jsf the field values end up in your managed bean. You will just have to use
<h:inputText value="#{bean.property}" />
(where bean is a #ManagedBean-annotated class (for jsf2), or declared in faces-config (for jsf1))
This difference is that the spring form is submitted to the target url, and spring finds the target method based on the mapping, while here you specify which method of the managed bean to invoke in your <h:commandButton />

Conditions in Spring expression language(SpEL) used in bean definition

As far SpEL is used in Spring 3.0,
I would like to ask, is it possible to do following(in bean definition .xml):
<c:choose>
<c:when test="#{prop=='a'}">
<bean class="BeanA"/>
</c:when>
<c:otherwise>
<bean class="BeanB"/>
</c:otherwise>
</c:choose>
Someth. like in jstl.
Thank you for help.
Environment profiles/Environment specific beans will be available in Spring 3.1 which should be released shortly - so you might want to wait for that.
There is no built in support for conditional beans in Spring 3.0. However, it could be achieved by using PropertyPlaceholderConfigurers and/or FactoryBeans.
There's no conditional mechanism for XML Spring bean defintion files.
However, maybe this would work:
<bean class="#{prop=='a' ? BeanA : BeanB}"/>
But even if this approach worked, it wouldn't be the most readable one. My suggestion would be to use different set of XML configuration files and pick them depending on some global settings. Naturally you would put all the common beans (i.e. these whose definition is always the same) in a separate file and have it always included.
it is not a question of using spel, but more of XML,afaik you can't do this in XML (but xslt)
the proper spring way for this scenario might be http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-class in combination with a "parent" interface for BeanA and BeanB
you could pass the parameter (system ? runtime specific ?) to the factory, which would create either BeanA or BeanB

Get Request and Session Parameters and Attributes from JSF pages

I'm using JSF with facelets and I need to get the request and session parameters inside the JSF page. In JSP pages I got this parameter like that: "${requestScope.paramName}" or "${sessionScope.paramName}". But now after using JSF there are only beans and you can't get any value except bean attributes.
NOTE: The session attributes what I need is auto filled using acegi security so I can't get any access to them.
So what to do now?
You can get a request parameter id using the expression:
<h:outputText value="#{param['id']}" />
param—An immutable Map of the request parameters for this request, keyed by
parameter name. Only the first value for each parameter name is included.
sessionScope—A Map of the session attributes for this request, keyed by
attribute name.
Section 5.3.1.2 of the JSF 1.0 specification defines the objects that must be resolved by the variable resolver.
You can also use a bean (request scoped is suggested) and directly access the context by way of the FacesContext.
You can get the HttpServletRequest and HttpServletResposne objects by using the following code:
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse res = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
After this, you can access individual parameters via getParameter(paramName) or access the full map via getParameterMap() req object
The reason I suggest a request scoped bean is that you can use these during initialization (worst case scenario being the constructor. Most frameworks give you some place to do code at bean initialization time) and they will be done as your request comes in.
It is, however, a bit of a hack. ;) You may want to look into seeing if there is a JSF Acegi module that will allow you to get access to the variables you need.
You can either use
<h:outputText value="#{param['id']}" /> or
<h:outputText value="#{request.getParameter('id')}" />
However if you want to pass the parameters to your backing beans, using f:viewParam is probably what you want. "A view parameter is a mapping between a query string parameter and a model value."
<f:viewParam name="id" value="#{blog.entryId}"/>
This will set the id param of the GET parameter to the blog bean's entryId field. See http://java.dzone.com/articles/bookmarkability-jsf-2 for the details.
You can like this:
#{requestScope["paramName"]} ,#{sessionScope["paramName"]}
Because requestScope or sessionScope is a Map object.
You can also use a tool like OcpSoft's PrettyFaces to inject dynamic parameter values directly into JSF Beans.
Assuming that you already put your object as attribute on the session map of the current instance of the FacesContext from your managed-bean, you can get it from the JSF page by :
<h:outputText value="#{sessionScope['yourObject'] }" />
If your object has a property, get it by:
<h:ouputText value="#{sessionScope['yourObject'].anyProperty }" />
Are you sure you can't get access to request / session scope variables from a JSF page?
This is what I'm doing in our login page, using Spring Security:
<h:outputText
rendered="#{param.loginFailed == 1 and SPRING_SECURITY_LAST_EXCEPTION != null}">
<span class="msg-error">#{SPRING_SECURITY_LAST_EXCEPTION.message}</span>
</h:outputText>
In the bean you can use session.getAttribute("attributeName");

Resources