Get Request and Session Parameters and Attributes from JSF pages - session

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");

Related

How to extend the lifetime of a bean?

I need some JSF 2.1.29 advice. I have a bean:
public class PlayerCardBean{
private Integer playerId;
//GET, SET, Other fileds and methods
}
The facelet playerCard.xhtml for the bean contains <a> tag for redirecting to another page:
<a href="javascript://"
onclick="openPage('#{request.contextPath}/panels/playerExternalTransactionList.html?playerId=#{playerCardBean.playerId}');">
<h:outputText value="#msgs['playerCard.externalTransactionList.all']}" />
</a>
I need this bean stay alived when the user is on the playerCard.xhtml as well as we're redirecting from the playerCard.xhtml to by the link within the <a> tag.
The view scope is smaller. The bean is going to be destroyed after redirecting.
How can I keep that bean alive when we're redirecting between those two views? By the <a> tag and probably by the "back"-button in a browser.
I think that storing the fields within a session is not a good idea because they are not a true-session attributes.
You can use the #ConversationScope. This scope is started and ended programmatically.
http://www.byteslounge.com/tutorials/java-ee-cdi-conversationscoped-example
I can think of the following two solutions:
Use the conversation scope. It requires annotating your bean with the #ConversationScoped annotation and you will need to manage (begin and end) the conversation programatically. (This answer contains some useful sample code.)
Use the Flash.
There is no perfect solution in JSF 2.1 but you can create your own scope which will be good replacement for conversation scope.
More details:
https://blog.oio.de/2012/07/24/jsf-2-custom-scopes-without-3rd-party-libraries/

Conditional validation without binding attribute

I'm dealing with a legacy code base and come across a situation when it's necessary to validate a field "fieldToValidate" if some other field "otherField" has some value (otherwise field is not validated). However the field "otherField" doesn't have a binding attribute.
I can add a binding and then update code like this:
<h:inputTextarea id="fieldToValidate" value="#{MyBean.fieldToValidate}"
required="#{MyBean.otherField != 'special_value'}" />
However there is a plenty of places where validation should be added and I don't want to modify backing beans. Is there a way to implement validation without adding "binding"?
Validation with some JS library is not a option.
You do not necessarily need to bind it to a bean property. Just omit the MyBean. part to bind it to the view scope directly.
<h:selectOneMenu binding="#{otherField}" ... />
...
<h:inputTextarea ... required="#{otherField != 'special_value'}" />
See also:
JSF component binding without bean property
What is component binding in JSF? When it is preferred to be used?

use spring bean in JSP

i have bean that contain method [void return] and want access to this bean in JSP.
public class A {
public void run() {}
}
add below code to spring config file.
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
<bean id="a" class="com.example.A"
>
</bean>
now in my JSP page :
${a.run}
but this solution not work.please help me for access spring bean on JSP page.
Inject the bean into your controller and expose it as part of the model.
But why do you need to call run from the JSP?
JSP EL expects to follow JavaBean naming conventions; this example won't work the way you expect. The easiest option is to rename the method, or provide an additional method, that follows the JavaBean naming convention and calls run.
Edit to reply to comment.
If you need to call a method from a link, you have two (reasonable) options: link to a controller action that calls the injected service, or make an Ajax call to a controller method that calls the injected service.
There's still zero reason to be making the service call directly from the view layer (the JSP).
You cannot call a method with ${a.run} you need to do #{a.run}.
# Dave Newton's comment : "There's still zero reason to be making the service call directly from the view layer".
Consider a scenario, where you want to develop a custom tag (say a dropdown which fetches values from a service class based upon the tag's attribute value, in your core web project) . and you provide the TAG implementation in a .tag file.
Keeping the service call in the .tag file seems preferable than to update the model in every controller, called prior to render the view which uses the tag. What do you suggest, Using an onload AJAX call in .tag file to fetch the dorpdown content?
Have you tried this?
${a.run()}
I haven't used org.springframework.web.servlet.view.InternalResourceViewResolver (use it's superclass instead), but this works if your controller injects a Java object profile which has toJson() method implemented. Don't see why the same syntax wouldn't work as long as a is accessible to the JSP and implements run().
<script>
$(function() {
var profileJson = ${profile.toJson()};
....
})
</script>
This is how is pre-load my page with initial content and save a trip to the back-end on page load.
You could write a scriptlet for this something like
<%
ApplicationContext ctx = RequestContextUtils.getWebApplicationContext(request);
A a = (A) ctx.getBean("yourBeanName");
%>
or use WebApplicationContextUtils if the requests are routed through DispatcherServlet.
You should look into Spring MVC . This would suit you more.

Read a form bean property to pass on to a forward

I am using struts 1.3. I have a an action I am reusing in 3 different cases. The form bean backing this has a property that has the complete path(passed from the jsp) to which the action should forward in case of success/failure(the path is different for each case depending on what the user is doing). How do I specify this for the input attribute of the action in the struts config to read from that form bean property.
What you can do is return a dynamic ActionForward from your Action class. This lets you use an ActionForward that isn't defined in yourstruts-config.xml
return new ActionForward(path_to_forward, redirect_true_or_false);
This doesn't help you for the input, which expects a JSP and not an ActionForward, but you should be able to do that in the ActionForm's validate() method. The first parameter passed into that method is an ActionMapping. On that object, you should be able to call setInput(String) with the path of your JSP. I have not tried this, but it looks like it should work.

Is it possible to set a domain object as a hidden field in spring forum bean?

greetings all
i have a domain class named car
and i have an object from car retrieved from the DB
and i want to save this object in the form as a hidden field
in order when submitting to get this object
but when i tried
<form:hidden path=carObj />
it didn't work, any ideas why, and how to do such behaviour ?
Well carObj is a java object, and an HTML hidden field can only hold text, so how would Spring store one inside the other? If you want to use hidden fields, you're going to have to break down the object into individual fields.
It sounds like what you need is to tell Spring to store carObj in the session, so that's visible when the form is posted. You can use the #SessionAttributes annotation for this (see docs).
Spring's form tag library does indeed support hidden fields as you described.
See the Spring Reference for more information.

Resources