I have the code below to display the exception in the error page.
<h:outputText value="Exception message" />
<h:outputText value="#{requestScope['javax.servlet.error.message']}" />
I put a command button to pass the stacktrace in the backing bean in the following way:
<p:commandButton value="Error" action="#{reportError.reportError(requestScope['javax.servlet.error.message'])}"/>
I even tried to pass it using f:attribute or binding but did not succeeed. I am unable to retrieve it in the backing bean. Moreover, if instead of stacktrace I try to put any string hard coded it works but the stack trace doesn't.
Any suggestions?
Related
I've been trying to understand JSF templating and include attributes and passing parameters between components. In Mastering JavaServer Faces 2.2 by Anghel Leonard, I came across the following example of passing parameters, which I don't fully understand.
Given this bean:
#Named
#ViewScoped
public class TemplatesBean implements Serializable {
private String msgTopDefault="";
private String msgBottomDefault="";
private String msgCenterDefault="No center content ... press the below button!";
public void centerAction(){
this.msgCenterDefault="This is default content";
}
// Getters and setters
}
Parameters are passed to contentDefault.xhtml with:
<ui:insert name="content">
<ui:include src="/template/default/contentDefault.xhtml">
<ui:param name="templatesBeanName" value="#{templatesBean}"/>
<ui:param name="contentPropertyName" value="msgCenterDefault"/>
</ui:include>
</ui:insert>
Then, within contentDefault.xhtml the parameters are used as follows:
<ui:composition>
<h:outputText value="#{templatesBeanName[contentPropertyName]}"/>
<h:form>
<h:commandButton value="Center Button" action="#{templatesBeanName['centerAction']()}"/>
</h:form>
</ui:composition>
I've never used the square-bracket syntax before, but if a reference to templatesBean is being passed in, why not just use that to access the properties or invoke action methods? For example, the following code works for me too and seems simpler:
<h:form>
<h:commandButton value="Center Button" action="#{templatesBeanName.centerAction()}"/>
</h:form>
Recognising that the example in the book may be a contrived example to illustrate a point, are there use cases where the other syntax is appropriate?
I do not know or own the book, so I cannot investigate that way what they want to illustrate, but I can sort of deduce that by looking at the full example you posted, not just the part about the centerAction.
If you look at
<ui:insert name="content">
<ui:include src="/template/default/contentDefault.xhtml">
<ui:param name="templatesBeanName" value="#{templatesBean}"/>
<ui:param name="contentPropertyName" value="msgCenterDefault"/>
</ui:include>
</ui:insert>
you'll see that 2 params are passesd on, templatesBeanName and contentPropertyName
In
<ui:composition>
<h:outputText value="#{templatesBeanName[contentPropertyName]}"/>
<h:form>
<h:commandButton value="Center Button" action="#{templatesBeanName['centerAction']()}"/>
</h:form>
</ui:composition>
from which you just pointed to the line with action="#{templatesBeanName['centerAction']()}", a dynamic bean with a static value in suqare brackets made into a method by adding () as a postfix, you'll see another line of code above it
<h:outputText value="#{templatesBeanName[contentPropertyName]}"/>
What effectively is done here is to have a dynamic bean AND a dynamic property name being used.
So my conclusion is that with this example what they are trying to illustrate is that you are able to pass on a dynamic bean, and on that bean use either both static or dynamic methods and properties(static properties and dynamic methods not being in the example)
I'm new to JSF, my question may be silly for you.. It is very much valuable for me..
<h:form id="form1">
<p:messages autoUpdate="true" showDetails="true" />
<p:dataTable id='form1ID'>....</dataTable>
<p:inputText value="#{bean.name}" required="true"
requiredMessage="Please Enter Name!" label="Name ">
</p:inputText>
</h:form>
<h:form id="form2">
<p:messages autoUpdate="true" showDetails="true" />
<p:dataTable id='form2ID'>....</dataTable>
<p:inputText value="#{bean.name}" required="true"
requiredMessage="Please Enter Name!" label="Name ">
</p:inputText>
<p:commandButton value="Submit" update=":form1:form1ID"
actionListener="#{mgmtBean.doCreateType}" />
</h:form>
I have two forms. when I click on form2 command button with empty fields, it will show error messages perfectly since i have added <p:messages autoUpdate="true" showDetail="true"/>.
The bad thing or surprising thing here for me is, it is showing error messages on top of form1 also may be because of <p:messages autoUpdate="true" showDetail="true"/> added in form1 and i'm trying to update form1 on command button click in form2.
I don't want to show error messages on form1 when form2 is throwing validation error messages. How can i fix this ? I googled it out.. but couldn't find the solution.
Evironment i'm using is jsf-api-2.1.5 and primefaces 4.0 version and view technology is facelets(XHTML)
Hope it is clear..
Any idea is highly appreciated.
Try to disable rendering of messages on the form1:
<p:messages autoUpdate="true" showDetails="true" rendered="#{bean.renderedmessage}"/>
And in the bean, add the renderedmessage variable:
public Boolean getRenderedmessage() {
return renderedmessage;
}
/**
* #param renderedmessage the renderedmessage to set
*/
public void setRenderedmessage(Boolean renderedmessage) {
this.renderedmessage = renderedmessage;
}
And, for the doCreateType() method, add:
public void doCreateType(){
..............
setRenderedmessage(false);
.............
}
After the form1 is updated, you can choose some event or method, where you can setRenderedmessage(true);
What you're currently experiencing should indicate to you that you usually don't need two <p:messages/>s in the same JSF view; one is enough.
Regardless of the fact that you have two <h:form/>s on your page, there's still only one FacesContext associated with that view (The FacesContext object is a JSF construct that encapsulates all the information/data/components etc that's associated with a given JSF page request).
By default the <p:messages/> will display every FacesMessage that is queued within it's associated instance of FacesContext, regardless of the source of the message (well, almost: if you set globalOnly="true" on the <p:messages/>, you can change that behaviour).
That being said, you basically have two options:
Get rid of the extra <p:messages/> and rely on (and appropriately position) only one to display all errors/warnings for that view
Specify the for attribute, set to the desired component. Doing so, you'll guarantee that only one input component can trigger the display of its associated message component. For example
<h:form id="form1">
<p:messages for="inputName" autoUpdate="true" showDetails="true" />
<p:dataTable id='form1ID'>....</dataTable>
<p:inputText id="inputName" value="#{bean.name}" required="true"
requiredMessage="Please Enter Name!" label="Name ">
</p:inputText>
</h:form>
Note that I've set an id attribute on the <p:inputText/> component; this is necessary so you can use it in the for attribute for the messages component.
Further reading:
What is FacesContext used for?
I have fixed the issue by using the following code
<p:messages autoUpdate="true" showDetails="true" visibility="info"/>
so it is just displaying info messages and other pop up error messages will not be showun.
i m using JSF2.0 and i m making one dataTable in that datatable i m getting the value from managed bean.And in managed bean in post construct annoted method i m calling my web service from another file.
Following is code for that
<h:dataTable
value="#{bean1.getList}" var="c" styleClass="order-table"
headerClass="order-table-header" width="100%"
rowClasses="order-table-odd-row,order-table-even-row" rows="8"
columnClasses="first,second">
<h:column>
<f:facet name="header">
<h:selectBooleanCheckbox></h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox value="#{c.id}"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<!-- <f:facet name="header"/> -->
<h:outputLabel value="From: "></h:outputLabel>
<h:outputLabel value="#{c.from}"></h:outputLabel>
<br></br>
<!-- -->
<h:outputLabel value="Sub: "></h:outputLabel>
<h:outputLabel value="#{c.sub}"/>
<h:commandLink immediate="true" action="#{bean2.doRead}" value="Read" id="Read"></h:commandLink>
</h:column>
<!-- Footer Setting -->
<f:facet name="footer">
</f:facet>
</h:dataTable>
My Bean1 class
#PostConstruct
public void prepareList(){
{
web service call
}
public List<InboxBean> getemailList(){
return list;
}
Now when i m clicking on commandlink which has id Read at that time my bean1 post construct taged property also called. That i dont want to perform. So,how to get out from this problem and i also want to set the subject value in bean2 setProperty. Thanks in advance
That can happen if the bean is put in request scope. Every single HTTP request will then reconstruct the bean. Put the bean in view or session scope instead.
E.g. in the view scope:
#ManagedBean
#ViewScoped
public class Bean {}
A view scoped bean lives as long as you're interacting with the same view by returning null or void in action methods.
Or in the session scope:
#ManagedBean
#SessionScoped
public class Bean {}
A session scoped bean lives as long as the established browser session. That is, from the very first HTTP request involving the bean until the client closes the entire browser instance or when the session expires on the server side (which defaults to 30 minutes).
For your particular case, a view scoped bean is most likely the best choice.
See also:
How to choose the right bean scope?
I'm getting this error java.util.NoSuchElementException when i tried to check one of my checkbox under h:selectManycheckBox when i submit the form.
The many checkbox is dynamically populated from the bean. Here is my code.
<h:form id="eF">
<h:inputText id="i" value="#{aklat.suggest}">
<a4j:support event="onkeyup" action="#{aklat.complete}" reRender="m"></a4j:support>
</h:inputText>
<s:div>
<h:selectManyCheckbox value="#{aklat.selectedBooks}" layout="pageDirection" id="m">
<s:selectItems value="#{aklat.books}" var="_book" itemLabel="#{_book}" itemValue="#{_book}" label="#{_book.bookName}"/>
</h:selectManyCheckbox>
<a4j:commandButton value="Add Users" action="#{aklat.fire}"></a4j:commandButton>
</s:div>
</h:form>
The weird part is it renders some data output but when i checked the source code. there are no input type checkbox element.
Is something I am missing.
I assume your managed bean is request scope...
because you are making an ajax request, you have to enable "aklat.books" to persist its value longer than request but shorther than session scope.
If you have tomahawk between your app libraries you can use savestate like this (put it after the h:form tag) :
<t:saveState value="#{aklat.books}"/>
if no tomahawk, you can use a4j:keepAlive:
<a4j:keepAlive beanName = "#{aklat.books}"/>
in a way similar to here I am using an abstract class to type the item set list
of ui:repeat. Concrete subclasses override the getType() method, that is used to
conditionally render the respective subtype with its particular properties:
<!-- AbstractAction Rule#getActions() -->
<ui:repeat value="#{rule.actions}" var="action">
<!-- render when "action" instance of NotificationAction -->
<h:panelGroup rendered="#{action.type == 'notification'}">
... UI for NotificationAction properties
<h:panelGroup rendered="#{action.type == 'callback'}">
...
When run on Glassfish 3 there is an error about properties not being defined on list
members of other subclasses (PropertyNotFoundException), which occurs in a branch that
is actually switched off by the rendered property. c:forEach/c:choose do not seem
appropriate. Any ideas how to make the rendering really conditional and bypass the
property checking are highly appreciated!
Thank you.
Jaro
after some testing it turned out, that the ui:repeat component itself caused the error.
Despite being in the final RenderResponse phase it tries to save the status of its child input components. Here a shortened exception dump:
Caused by: javax.el.PropertyNotFoundException: ... The class FOO does not have a readable property 'BAR'.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:104)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:343)
at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:428)
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:522)
at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:926)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
Hereby the rendered condition is ignored and the EL interpreter complains about non-existent properties. There is a simple solution by using the h:dataTable iterator with a single column instead:
<h:dataTable value="#{rule.systemActions}" var="action">
<c:set var="name" value="#{action.class.simpleName.toLowerCase()}" />
<h:column>
<h:panelGroup rendered="#{name == 'notification'}">
<h:outputLabel for="phone">Phone:</h:outputLabel>
<h:inputText value="#{action.phone}" id="phone" />
</h:panelGroup>
<h:panelGroup rendered="#{name == 'reminder'}">
...
</h:panelGroup>
</h:column>
</h:dataTable>
Cheers.
Jaro