Display IOException into Primefaces Messages - jsf

I am trying to display IOException into Primefaces messages but the text is not formated properly
In my code I catch the exception:
} catch (Exception ex) {
System.out.println(ex);
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, null,ex.toString());
facesGetCurrentInstance(msg);
}
Then add the message:
public void facesGetCurrentInstance(FacesMessage msg) {
FacesContext.getCurrentInstance().addMessage(null, msg);
}
In the XHTML I am using growl to display the message
<p:growl id="messages" showDetail="true" sticky="true" autoUpdate="true" />
Thus far everything works, but I am having an issue with how the message is getting displayed. I am assuming this because I am using .toString. So, is there another way to do this?

try this:
FacesContext.getCurrentInstance().addMessage(FacesMessage.SEVERITY_ERROR,exception.getMessage());

Related

How to show a primefaces growl message on the next page? [duplicate]

This question already has answers here:
How to use Primefaces' p:growl and redirect to a page
(3 answers)
Closed 6 years ago.
I'm using primefaces 3.5 and I can't figure it out how to growl a message on the next page. For instance I want to add a record in database and after that I make a redirection to another page where I want to show a growl message with "The record has been added with success!"
I tried something like this:
public String addLabelInDB() {
try {
//logic to add a record in DB
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success!", "Label has been added with success!"));
} catch (Exception e) {
logger.debug(e.getMessage());
}
return "listLabelsPage";
}
and in listLabelsPage.xhtml I have:
<p:growl id="msgs" showDetail="true" autoUpdate="true"/>
but it doesn't work.
I supposed the message is getting lost because is another request or something? It's there any possibility to store the message on request and show it on the next page? Thanks!
You can have a preRender set on the listLabelsPage.xhtml page you're loading
<f:event type="preRenderView" listener="#{yourBean.showGrowl}" />
and a showGrowl method having only
public void showGrowl() {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success!", "Label has been added with success!"));
}
I post an answer to my own question in order to help another people which face the same problem like I did:
public String addLabelInDB() {
try {
//some logic to insert in db
//below I set a flag on context which helps me to display a growl message only when the insertion was done with success
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.getRequestMap().put("addedWithSuccess","true");
} catch (Exception e) {
logger.debug(e.getMessage());
}
return "listLabelsPage";
}
public void showGrowl() {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
String labelAddedWithSuccess = (String) ec.getRequestMap().get("addedWithSuccess");
//if the flag on context is true show the growl message
if (labelAddedWithSuccess!=null && labelAddedWithSuccess.equals("true")) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success!", "Label has been added with success!"));
}
}
and in my xhtml I have:
<f:event type="preRenderView" listener="#{labelsManager.showGrowl}" />
How about this? Make a separated redirect button which will be hit after showing msg:
HTML:
<h:form prependId="false">
<p:growl />
<p:button outcome="gotoABC" id="rdr-btn" style="display: none;" />
<p:commandButton action="#{bean.process()}" update="#form" />
</form>
Bean:
public void process(){
addInfoMsg(summary, msgDetail); //Add msg func
RequestContext.getCurrentInstance().execute("setTimeout(function(){ $('#rdr-btn').click(); }, 3000);"); // 3 seconds delay. I put the script in Constants to config later.
}

show FacesMessage when invoking wizard.getOldStep()

I'm trying to show a FacesMessage built in onFlowProcess of a primefaces wizard.
public String onFlowProcess(FlowEvent event) {
if (event.getOldStep().equalsIgnoreCase("otherTab")){
if (!hasImage){
FacesUtils.addMessage(null, "Error", "image is required", FacesMessage.SEVERITY_ERROR);
return event.getOldStep();
}
}
return event.getNewStep();
}
The message should be send to the growl but I believe that by invoking getOldStep(), the message is lost along the way.
My growl is declared as :
<p:growl life="2500" showDetail="true" globalOnly="true"/>
and the wizard contains flowListener="#{bean.onFlowProcess}".
I tried to keep my FacesMessage with
FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
but this seems to work only for page redirect...
If anybody has any idea... Thx
I solved the problem by updating the <p:growl> from the bean:
RequestContext.getCurrentInstance().update("form:growl");

JSF button is not working after AJAX call

I have this JSF button which calls Java method when it's pressed:
<h:commandButton id="editdata" value="HiddenDelete" style="position:absolute; bottom:25px; right:650px;" actionListener="#{bean.saveData}" rendered="#{bean.editable}">
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
public void saveData() throws SQLException
{
.....
}
When I make a AJAX call the button is not working properly. Can you help me to find why the Java method is not called after AJAX call?
You're not passing the event:
public void saveData(AjaxBehaviorEvent event) { ... }
Also, what do you expect to happen with the Exception you're throwing? Shouldn't you catch it?
try {
// logic
}
catch(SQLException ex) {
FacesContext facesContext = FacesContext.getCurrentInstance();
FacesMessage facesMessage = new FacesMessage(
"There was an error, ....");
facesContext.addMessage(null, facesMessage);
}
This will be printed in HTML by <h:messages />.

Checking for messages existence

I use a method like this for sending error messages to my facelet:
public static void addErrorMessage(String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(null, facesMsg);
}
Then I show them inside a dialog with:
<p:messages id="messagesFattura" autoUpdate="true" />
And that works well. Now, my question is:
how can I "check" for messages existence?
I mean, there's another portion of code (a primefaces ) which I want to show/hide conditionally, via the rendered attribute.
I already tried the #{empty facesContext.messageList} EL variable, without success (empty list)

JSF PrimeFaces FileDownload problem

I'm using PrimeFaces for a new project and it's quite an impressive set of components.
Anyway, I have problem with "real world" use of filedownload component.
In my page I have a datalist that shows the attachments related to a particular document, and I want provide a link to directly download that file inside the datalist item.
Here's my xhtml code:
<p:dataList id="ListaAllegati" value="#{documentBean.documento.allegati}" type="definition" var="attach" style="border: none" ">
<f:facet name="description">
<h:outputText value="#{attach.name}" />
<p:commandLink ajax="false" title="Download" action="#{documentBean.selectAttach}>
<h:graphicImage style="margin-left: 10px; border: none" value="./images/article.png" height="24" width="24" ></h:graphicImage>
<p:fileDownload value="#{documentBean.downloadFile}"/>
<f:setPropertyActionListener target="#{documentBean.selectedAttach}" value="#{attach}" />
</p:commandLink>
</f:facet>
</p:dataList>
and the relative java bean (request scoped):
private StreamedContent downloadFile;
public StreamedContent getDownloadFile() {
log.info("getter dell'allegato invocato");
InputStream stream = null;
byte[] rawFile = null;
if (selectedAttach == null) {
log.warn("Nessun allegato passato");
return null;
} else {
try {
log.info("Recupero del file " + selectedAttach.getGuid());
rawFile = attachManager.retrieveFile(selectedAttach.getGuid());
} catch (Exception e) {
String msg = "Errore durante il recupero del file";
log.error(msg, e);
FacesMessage fmsg = new FacesMessage(msg, "");
FacesContext.getCurrentInstance().addMessage(null, fmsg);
}
stream = new ByteArrayInputStream(rawFile);
DefaultStreamedContent file = new DefaultStreamedContent(stream,
selectedAttach.getMimeType(), selectedAttach.getName());
return file;
}
}
public void selectAttach() {
log.info("commandLink action invocata");
}
private Allegato selectedAttach;
public Allegato getSelectedAttach() {
return selectedAttach;
}
public void setSelectedAttach(Allegato selectedAttach) {
log.info("Allegato selezionato");
if (selectedAttach==null) log.warn("L'allegato passato รจ nullo");
this.selectedAttach = selectedAttach;
}
So, couple of question:
Am I doing the right thing trying to pass the selected attachment that way? Otherwise, how can I pass a parameter to tell the bean wich attachment has been clicked?
Why the first time I click the command link, nothing happen? It make a roundtrip with server, but nothing happens. Second time, it gives me an exception.
Why documentBean.selectAttach is never called and the documentBean.selectedAttach property is never set (neither the second time)?
Thanks to anyone for any hint
How to get the row object from the datatable is answered in this question:
How can I pass selected row to commandLink inside dataTable?
This answers basically all the three questions.
As to the exception in the second click, that's likely because you didn't return from the catch block when an exception is been thrown in your getDownloadFile() method. You're continuing the remnant of the code flow while the rawFile is still null. Fix it accordingly as well. Add a return null to the end of catch or something. Better yet, you should be posting the entire stacktrace in the question as you don't seem to be able to understand it. It basically already contains the answer :)
Primefaces has its own dedicated servlet for file download and upload components that handle all of this asynchronously.
Try doing something like what I have in my code
<p:commandLink ajax="false" actionListener="#{managedBean.downloadAction(object)}">
<span class="ui-icon icoFolderGo" style="padding-right: 1.5em;" />
<p:fileDownload value="#{managedBean.downloadContentProperty}" />
</p:commandLink>
And in the managed bean,
public void downloadAction(Object object) {
try {
InputStream stream = // get input stream from argument
this.setDownloadContentProperty(new DefaultStreamedContent(stream, "application/pdf", "filename.pdf");
} catch (Exception e) {
log.error(e);
}
}
public void setDownloadContentProperty(StreamedContent downloadContentProperty) {
this.downloadContentProperty = downloadContentProperty;
}
public StreamedContent getDownloadContentProperty() {
return downloadContentProperty;
}

Resources