Downloading image file using PrimeFaces - jsf

I have a web application that uses PrimeFaces components. I am trying to download a file from the database to be saved to someones client computer. In the code, I am writing the byte array to the file object shown below. However, I do not know how to trigger the download dialog bar when the function is triggered. Can someone please help?
Download function in Download bean
public void fileDownload(int id) throws IOException {
try {
Class.forName("com.mysql.jdbc.Driver");
DBConn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demeter2.0", "root", "root");
} catch (SQLException | ClassNotFoundException ex) {
Logger.getLogger(Animal.class.getName()).log(Level.SEVERE, null, ex);
}
PreparedStatement pst = null;
try {
if (DBConn != null) {
String sql = "Select * FROM graph WHERE id='" + id + "'";
pst = (PreparedStatement) DBConn.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
if (!rs.next()) {
} else {
rs.beforeFirst();
while (rs.next()) {
// File file = new File("c:/newfile.png");
Blob b = rs.getBlob(2);
byte barr[] = new byte[(int) b.length()];
barr = b.getBytes(1, (int) b.length());
InputStream is = new ByteArrayInputStream(barr);
System.out.print("hello");
file = new DefaultStreamedContent(is, "image/png", "chart.png");
System.out.print(file);
}//end while
}
}
} catch (Exception e) {
System.out.println(e);
} finally {
try {
pst.close();
DBConn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
download.xhtml
<h:form>
<p:dataTable var="download" value="#{download.allGraph()}">
<p:column headerText="Id">
<h:outputText value="#{download.id}" />
</p:column>
<p:column headerText="Date Added">
<h:outputText value="#{download.date}" />
</p:column>
<p:column headerText="Download">
<p:commandLink id="downloadLink" value="Download" ajax="false">
<p:fileDownload value="#{download.fileDownload(download.id)}" />
</p:commandLink>
</p:column>
</p:dataTable>
</h:form>

If you look carefully at showcase
you will see that you need to call function that returns StreamedContent. You could changed your function from void to StreamedContent and at the end add return file;

Related

FileDownload Primefaces error Stream Closed

I have a table with users and a i have to select one to get the list of files so i can download. Everything works fine but if i already download the file and i try to click again to download i get the java.io.IOException: Stream Closed , but if i download the file and select again the user to get the list of files i can download the file.
The problem is i can't download more than once without have to select the user and get the list of files.
This is how i get the files when i select the user to get the list of files.
public void obtenerRequisitos() {
try {
archivos = new ArrayList<>();
lstArchivos = new ArrayList<>();
if (SelectedInscripcion != null) {
lstArchivos = d.getArchivosInscripciones(String.valueOf(SelectedInscripcion.getId()));
for (Archivos a : lstArchivos) {
InputStream input = new FileInputStream(a.getRuta());
String extension = a.getRuta().substring(a.getRuta().lastIndexOf('.'));
file = new DefaultStreamedContent(input, a.getRequisitosPromo().getRequisitos().getTipoArchivo(), a.getRequisitosPromo().getRequisitos().getFormato() + extension);
archivos.add(new ClsArchivos(a.getRequisitosPromo().getRequisitos().getDescripcion(), file));
}
}
} catch (Exception ex) {
Logger.getLogger(AsignarEntrevistaBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
this is a class that i use to store the list of files
public class ClsArchivos implements Serializable{
private String descripcion;
private StreamedContent file;
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
public StreamedContent getFile() {
return file;
}
public void setFile(StreamedContent file) {
this.file = file;
}
public ClsArchivos() {
}
public ClsArchivos(String descripcion, StreamedContent file) {
this.descripcion = descripcion;
this.file = file;
}
}
and this is part of the xhtml where the filedownload is
<p:dataTable style="margin-bottom: 25px;" id="requisitos" value="#{asignarEntrevistaBean.archivos}" var="a">
<f:facet name="header">
Listas de Requisitos por Solicitud
</f:facet>
<p:column headerText="Descripcion">
<h:outputText value="#{a.descripcion}" />
</p:column>
<p:column headerText="Archivos">
<p:commandButton value="Download" ajax="false" icon="ui-icon-arrowthick-1-s">
<p:fileDownload value="#{a.file}" />
</p:commandButton>
</p:column>
</p:dataTable>

rendered attribute not working with request parameter

I am using JSF2.2 with primefaces 5.0. I have a xhtml file where there are two file Uploads where one should always be visible while other should be visible only when request parameter, named signmethod, is JAVAME.
<h:panelGrid>
<h:panelGroup>
<h:outputLabel for="selected_signmethod" value="Selected Signethod : "/>
<h:outputText id="selected_signmethod" value="#{param.signmethod}" />
</h:panelGroup>
<h:panelGroup>
<b>Select file(s) to upload:</b>
</h:panelGroup>
</h:panelGrid>
<h:form id="uploadForm" enctype="multipart/form-data">
<p:message for="file_upload"/>
<p:fileUpload id="file_upload" allowTypes="#{fileUploadView.allowedTypes}" label="Select file" fileUploadListener="#{fileUploadView.handleFileUpload}"
mode="advanced" dragDropSupport="false" update="growl" multiple="true" fileLimit="5"/>
<p:message for="javame_upload"/>
<h:panelGroup rendered="#{param.signmethod == 'JAVAME'}" >
<b>Select corresponding jar file(s) to upload:</b>
<p:fileUpload id="javame_upload" allowTypes="" label="Select Jar file for javame" fileUploadListener="#{fileUploadView.handleFileUpload}"
mode="advanced" dragDropSupport="false" multiple="true" fileLimit="5"/>
</h:panelGroup>
<p:commandButton ajax="false" id="signProceed" value="Proceed" action="#{fileUploadView.submit}"/>
</h:form>
But this seems to be not happening. Second upload component is not getting rendered at all. I am also printing value of param.signmethod so that to be sure that right value is getting into param.signmethod, which is correct. So whats stopping this component to get rendered.
Managed Bean code :
#ManagedBean
#ViewScoped
public class FileUploadView implements Serializable {
#ManagedProperty(value = "#{signBundleBean}")
private SignBundleBean signBundleBean;
static String uploadDirRoot = InitialisationHelper.getUploadDirRoot();
transient Map<String, Object> sessionMap;
ArrayList<Signing> signings;
String username;
SignMethod signMethod;
public FileUploadView() {
System.out.println("NEW FileUploadView created.");
}
#PostConstruct
public void init() {
System.out.println("#POstConstruct FileuploadView");
System.out.println("signMethod : " + signMethod);
sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
signings = signBundleBean.getSignings();
username = (String) sessionMap.get("username");
}
public void handleFileUpload(FileUploadEvent e) {
String signId = "" + DatabaseHelper.genrateSigningId();
FacesContext ctx = FacesContext.getCurrentInstance();
UploadedFile uploadedFile = e.getFile();
String filename = uploadedFile.getFileName();
if (signId.equals("-1")) {
FacesMessage fm = new FacesMessage();
fm.setDetail("Database Connection not working. Please try later.");
fm.setSummary("DBConnection_Error");
fm.setSeverity(FacesMessage.SEVERITY_ERROR);
//ctx.addMessage(null, fm);
ctx.addMessage("uploadForm:file_upload", fm);
return;
}
if (username == null) {
FacesMessage fm = new FacesMessage();
fm.setDetail("You are not in session to upload.");
fm.setSummary("Session_Error");
fm.setSeverity(FacesMessage.SEVERITY_ERROR);
ctx.addMessage("uploadForm:file_upload", fm);
return;
}
Signing sg;
sg = new Signing(signId, username, filename, signMethod, false);
signings.add(sg);
System.out.println("Signing added : " + sg);
signBundleBean.setMaxParameters(SignParametersInitialisation.getNumberOfParameters(signMethod));
try {
InputStream is = uploadedFile.getInputstream();
OutputStream os = new FileOutputStream(sg.getUploadfile());
byte[] bytes = new byte[1024];
int read = 0;
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
sg.setUploaded(true);
is.close();
os.close();
} catch (IOException ex) {
signings.remove(sg);
Logger.getLogger(FileUploadView.class.getName()).log(Level.SEVERE, null, ex);
}
FacesMessage fm = new FacesMessage();
fm.setDetail(filename);
fm.setSummary("FileUploaded");
fm.setSeverity(FacesMessage.SEVERITY_INFO);
//ctx.addMessage(null, fm);
ctx.addMessage(null, fm);
System.out.println(sg + " File uploaded to " + sg.getUploadfile());
}
}

JSF Primefaces pass parameter to fileupload

JSF 2.2 - Primefaces 4.0 - JBoss Wildfly
Hi, I am trying to pass a parameter value to the file upload handler.
I tried a few suggestions I found, but can't get it to work.
I stepped a few steps back
I need the #{fileUploadController.newItemId} in the controller
When going to the file update page it is done with i.e. this URL
/fileUpload.jsf?newItemId=10
I tried what it mentioned in
How to send parameter to fileUploadListener in PrimeFaces fileUpload
and
Passing value to the backing bean with PrimeFaces file upload
fileUpload.xhtml
<f:metadata>
<f:viewParam name="newItemId"
value="#{fileUploadController.newItemId}" />
<f:viewAction action="#{fileUploadController.loadData()}" />
</f:metadata>
<h:form id="item" enctype="multipart/form-data">
<p:messages id="messages" />
<p:panelGrid styleClass="panelGridCenter">
<p:row>
<p:column>
<p:fileUpload
fileUploadListener="#{fileUploadController.handleFileUpload}"
validator="#{fileUploadController.validateFile}" mode="advanced"
dragDropSupport="false" update="messages" sizeLimit="1000000"
fileLimit="100" allowTypes="/(\.|\/)(gif|jpe?g|png)$/">
</p:fileUpload>
</p:column>
</p:row>
</p:panelGrid>
</h:form>
FileUploadController.java
public void handleFileUpload(FileUploadEvent event) {
try {
// Need item id here :)
UploadedFile file = event.getFile();
InputStream inputStream = file.getInputstream();
FileOutputStream outputStream = new FileOutputStream(file.getFileName());
byte[] buffer = new byte[4096];
int bytesRead = 0;
while (true) {
bytesRead = inputStream.read(buffer);
if (bytesRead > 0) {
outputStream.write(buffer, 0, bytesRead);
} else {
break;
}
}
outputStream.close();
inputStream.close();
Long imageId = serviceSLSB.saveImage(itemId, file, buffer);
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded and saved with id." + imageId);
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (Exception e) {
String errorMessage = getRootErrorMessage(e);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Saving unsuccessful");
facesContext.addMessage(null, m);
}
}
public void loadData() {
if (newItemId == null) {
String message = "Bad request. Please use a link from within the system.";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
return;
} else {
String message = "Your are adding images to item with id : " + newItemId;
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, null));
return;
}
}
I just found that my controller was only request scoped, after changing it to
#ViewScoped
#Named
public class FileUploadController implements Serializable
I of cause still have the item id, and can now add images to that item.
Thanks for the comments guys

Datatable not saving any edits

Hi guys i have a datatable from the primefaces library, which i am trying to include the feature of editing each cell and when the user presses a "save" button at the row it will update the edited values to a database, however currently when a user edits a cell what ever they change the cell to the second they click off the cell the value goes the same as what it was before, it does not save the new values, and also another issues is when the user presses save at the end of the row the values passwed to the database is always Null, how can i solve these two issues ?
here is the xhtml
<p:dataTable id="dataTable" var="u" value="#{userBean.getUserList()}"
paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,25"
editable="true" editMode="cell"
>
<p:column>
<!--
<p:ajax event="rowEdit" listener="{u.onEdit}" update=":form:messages" />
<p:ajax event="rowEditCancel" listener="{u.onCancel}" update=":form:messages" />
-->
<f:facet name="header">
User ID
</f:facet>
#{u.userID}
</p:column>
<p:column headerText="Name" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.name}" />
</f:facet>
<f:facet name="input">
<p:inputText id="NameInput" value="#{u.name}"
style="width:96%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Email">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.email}" />
</f:facet>
<f:facet name="input">
<p:inputText id="EmailInput" value="#{u.email}"
/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Address">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.address}" />
</f:facet>
<f:facet name="input">
<p:inputText id="AddressInput" value="#{u.address}"
/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<f:facet name="header">
Created Date
</f:facet>
#{u.created_date}
</p:column>
<p:column>
<f:facet name="header">
Delete
</f:facet>
<h:commandButton value="Delete" action="#{user.delete(u.userID)}" />
</p:column>
<p:column>
<f:facet name="header">
Save Edit
</f:facet>
<h:commandButton value="Save" action="#{user.editData(u.userID)}" />
</p:column>
</p:dataTable>
and here is the backing bean although currently this is only updating the database with the values from the databale
public void editData(long userID) {
System.out.println(name);
PreparedStatement ps = null;
Connection con = null;
if (userID != 0) {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
System.out.println(name);
String sql = "UPDATE user1 set name = '" + name + "', email = '" + email + "', address = '" + address + "' WHERE userId=" + userID;
ps = con.prepareStatement(sql);
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("Row updated successfully");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
the datable originally gets its values from the database
Thanks
Here is how i populate the datatable with values from the database,/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import richard.test.User;
#ManagedBean(name = "userBean")
#SessionScoped
public class UserBean {
List<User> list;
PreparedStatement ps = null;
Connection con = null;
ResultSet rs = null;
public List<User> getList() {
return list;
}
public List<User> getUserList() {
list = new ArrayList<User>();
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
String sql = "select * from user1";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
User usr = new User();
usr.setUserID(rs.getLong("userId"));
usr.setName(rs.getString("name"));
usr.setEmail(rs.getString("email"));
usr.setAddress(rs.getString("address"));
usr.setCreated_date(rs.getDate("created_date"));
list.add(usr);
Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
List<User> checkedItems = new ArrayList<User>();
for (User item : list) {
if (checked.get(item.getUserID()) != null) {
checkedItems.add(item);
usr.delete(usr.getUserID());
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
}
HERE is the full user bean code
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.test;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIColumn;
import javax.faces.event.ActionEvent;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;
#ManagedBean
#RequestScoped
public class User {
List<User> list;
PreparedStatement ps = null;
Connection con = null;
ResultSet rs = null;
private long userID = 1;
private String name;
private String address;
private Date created_date;
private String email;
boolean editable;
public boolean isEditable() {
return editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
}
public String editAction(User order) {
order.setEditable(true);
return null;
}
public long getUserID() {
return userID;
}
public void setUserID(long userID) {
this.userID = userID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getCreated_date() {
return created_date;
}
public void setCreated_date(Date created_date) {
this.created_date = created_date;
}
public String add() {
System.out.println("In add");
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
int i = 0;
if (userID != 0) {
PreparedStatement ps = null;
Connection con = null;
try {
System.out.println("about to add to db");
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
String sql = "INSERT INTO user1( name, email, address, created_date) VALUES(?,?,?,?)";
ps = con.prepareStatement(sql);
ps.setString(1, name);
ps.setString(2, email);
ps.setString(3, address);
if (created_date != null) {
String date = fmt.format(created_date);
Object obj = date;
if (obj == null) {
ps.setDate(4, null);
} else {
java.sql.Date dt = java.sql.Date.valueOf(new String(date));
ps.setDate(4, dt);
}
}
i = ps.executeUpdate();
System.out.println("Data Added Successfully");
} catch (Exception e) {
System.out.println(e);
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (i > 0) {
return "output";
} else {
return "invalid";
}
} else {
return "invalid";
}
}
public void delete(long userID) {
PreparedStatement ps = null;
Connection con = null;
if (userID != 0) {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
String sql = "DELETE FROM user1 WHERE userId=" + userID;
ps = con.prepareStatement(sql);
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("Row deleted successfully");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void editData(long userID) {
PreparedStatement ps = null;
Connection con = null;
if (userID != 0) {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
System.out.println(name);
String sql = "UPDATE user1 set name = '" + name + "', email = '" + email + "', address = '" + address + "' WHERE userId=" + userID;
ps = con.prepareStatement(sql);
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("Row updated successfully");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
The main problem is that you have two User objects:
User u - currently selected user.
User user - just a ManagedBean, most probably with no state (no id, no name, no address).
When performing the edit operation you try to use u.id and user.name, user.address, etc.
What you need to do, is to take all the values from the u object.
There are many different approaches (I've never used the third one, but it should work and it's the closest to what you've already have):
A1. You can keep currently selected object in your UserBean and set it with setPropertyActionListener:
<f:setPropertyActionListener target="#{userBean.selectedUser}" value="#{u}" />
Then you can call the edit method implemented in the same bean (it has full access to selectedUser object and it can implement the edit itself of just delegate the action to object with edit method implementation).
A2. You can place your edit method in the UserBean and pass entire User object as a parameter:
<h:commandButton value="Save" action="#{userBean.editData(u)}" />
A3. Or you can just call:
<h:commandButton value="Save" action="#{u.editData()}" />
instead of:
<h:commandButton value="Save" action="#{user.editData(u.userID)}" />

Losing checked info in p:datatable while changing page

I know this is not a bug.
But i need a suggestion, what can i do not to lose checked knowledge of checked lines?
On JSF page:
<h:form prependId="false" id="searchUserFormTable" >
<p:dataTable id="selectUserTable" var="user"
value="#{userListController.lazyDataModel}" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rows="2" paginatorPosition="bottom" rowKey="#{user}"
lazy="true"
rowsPerPageTemplate="2,10,20,30,40,50"
rendered="#{userListController.lazyDataModel != null}" selection="#{systemMessageEditController.receiverList}"
scrollable="true" scrollHeight="250" resizableColumns="false" >
<p:column selectionMode="multiple" width="18" />
<f:facet name="header">
<h:outputText value=" Users (#{userListController.lazyDataModel.rowCount})" />
</f:facet>
<p:column filterBy="#{user.name}" headerText="Name" filterMatchMode="contains" width="80">
#{user.name}
</p:column>
<p:column filterBy="#{user.surname}" headerText="Surname" filterMatchMode="contains" width="80">
#{user.surname}
</p:column>
<p:column headerText="Gender" width="80">
#{user.gender}
</p:column>
<p:column headerText="City" width="80">
#{user.address.city.name}
</p:column>
<p:column headerText="Status" width="80">
#{user.userStatus}
</p:column>
<p:column headerText="User Detail" width="80">
<h:link value="User Detail" outcome="/view/admin/usermanagement/userInfo.jsf">
<f:param name="userId" value="#{user.id}" />
</h:link>
</p:column>
</p:dataTable>
<p:commandButton value="Tamam" oncomplete="userListDlg.hide();" update=":newMessageForm"></p:commandButton>
</h:form>
All the controller:
#ManagedBean(name="systemMessageEditController")
#ViewScoped
public class SystemMessageEditController {
#ManagedProperty(value = "#{systemMessageService}")
SystemMessageService systemMessageService;
#ManagedProperty(value = "#{securityBean}")
SecurityBean securityBean;
#ManagedProperty(value = "#{systemMessageReceiverService}")
SystemMessageReceiverService systemMessageReceiverService;
#ManagedProperty(value = "#{systemMessageAnswerService}")
SystemMessageAnswerService systemMessageAnswerService;
private SystemMessage systemMessage = new SystemMessage();
private SystemMessageAnswer systemMessageAnswer = new SystemMessageAnswer();
private SystemMessageReceiver systemMessageReceiver = new SystemMessageReceiver();
private User[] receiverList;
private boolean dummy;
public void prepareToEdit(){
systemMessage = systemMessageService.findById(systemMessage.getId());
}
public void prepareToSendMessage(){
systemMessage = new SystemMessage();
receiverList = null ;
}
public void sendMessage(){
if(Util.isNotNull(systemMessage.getTitle())){
boolean success = false;
systemMessageAnswer.setUser(securityBean.getUser());
systemMessage.getSystemMessageAnswerList().add(systemMessageAnswer);
systemMessage.setUserSender(securityBean.getUser());
systemMessageAnswer.setSystemMessage(systemMessage);
if(!systemMessage.isSendAll()){
addMessageReceiver();
}
systemMessage = systemMessageService.save(systemMessage);
systemMessageAnswer = new SystemMessageAnswer();
success = true;
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.send.success"), FacesUtils.getMessageByKey("systemmessage.send.success"));
FacesContext.getCurrentInstance().addMessage("", message);
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("success", success);
}
else{
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.null.title"), FacesUtils.getMessageByKey("systemmessage.null.title"));
FacesContext.getCurrentInstance().addMessage("", message);
}
}
public void setRead(SystemMessage message){
message.setReaded(true);
systemMessageService.save(message);
}
public void addMessageReceiver(){
for(User user : receiverList){
SystemMessageReceiver messageReceiver = new SystemMessageReceiver();
messageReceiver.setReceiver(user);
messageReceiver.setSystemMessage(systemMessage);
messageReceiver.setReaded(false);
systemMessage.getSystemMessageReceiverList().add(messageReceiver);
}
}
public void deleteMessage(){
boolean success = false;
systemMessageService.delete(systemMessageService.findById(systemMessage.getId()));
success = true;
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.delete.success"), FacesUtils.getMessageByKey("systemmessage.delete.success"));
FacesContext.getCurrentInstance().addMessage("", message);
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("success", success);
}
public void sendMessageAnswer(){
systemMessageAnswer.setUser(securityBean.getUser());
systemMessageAnswer.setSystemMessage(systemMessage);
systemMessageAnswerService.save(systemMessageAnswer);
if(!systemMessage.isSendAll()){
systemMessage.setSystemMessageReceiverList(systemMessageService.getReceiverListOfMessage(systemMessage));
for(SystemMessageReceiver systemMessageReceiver : systemMessage.getSystemMessageReceiverList()){
if(!systemMessageReceiver.getReceiver().getId().equals(securityBean.getUser().getId())){
systemMessageReceiver.setReaded(false);
systemMessageReceiver.setShowed(false);
systemMessageReceiverService.save(systemMessageReceiver);
}
}
}
systemMessage.getSystemMessageAnswerList().add(systemMessageAnswer);
systemMessageAnswer = new SystemMessageAnswer();
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, FacesUtils.getMessageByKey("systemmessage.send.success"), FacesUtils.getMessageByKey("systemmessage.send.success"));
FacesContext.getCurrentInstance().addMessage("", message);
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("success", true);
}
public SystemMessageService getSystemMessageService() {
return systemMessageService;
}
public void setSystemMessageService(SystemMessageService systemMessageService) {
this.systemMessageService = systemMessageService;
}
public SystemMessage getSystemMessage() {
return systemMessage;
}
public void setSystemMessage(SystemMessage systemMessage) {
ArrayList<String> fetchedAttributes = new ArrayList<String>();
fetchedAttributes.add("systemMessageAnswerList");
this.systemMessage = systemMessageService.loadWithFetchedAttributes(systemMessage.getId(),fetchedAttributes);
}
public SystemMessageAnswer getSystemMessageAnswer() {
return systemMessageAnswer;
}
public void setSystemMessageAnswer(SystemMessageAnswer systemMessageAnswer) {
this.systemMessageAnswer = systemMessageAnswer;
}
public SecurityBean getSecurityBean() {
return securityBean;
}
public void setSecurityBean(SecurityBean securityBean) {
this.securityBean = securityBean;
}
public SystemMessageReceiverService getSystemMessageReceiverService() {
return systemMessageReceiverService;
}
public void setSystemMessageReceiverService(
SystemMessageReceiverService systemMessageReceiverService) {
this.systemMessageReceiverService = systemMessageReceiverService;
}
public SystemMessageAnswerService getSystemMessageAnswerService() {
return systemMessageAnswerService;
}
public void setSystemMessageAnswerService(
SystemMessageAnswerService systemMessageAnswerService) {
this.systemMessageAnswerService = systemMessageAnswerService;
}
public SystemMessageReceiver getSystemMessageReceiver() {
return systemMessageReceiver;
}
public void setSystemMessageReceiver(SystemMessageReceiver systemMessageReceiver) {
this.systemMessageReceiver = systemMessageReceiver;
}
public User[] getReceiverList() {
return receiverList;
}
public void setReceiverList(User[] receiverList) {
this.receiverList = receiverList;
}
I am losing checked info while jumping one pagination number to another, when i checked some rows, then jump another pagination number in datatable, and go back to old pagination number i loose the checked info, i see nothing has changed.
This is how #ViewScoped works. See the following answer from BalusC:
A view scoped bean lives as long as you interact with the same view (i.e. you return void or null in bean action method). When you navigate away to another view, e.g. by clicking a link or by returning a different action outcome, then the view scoped bean will be trashed by end of render response and not be available in the next request.
which explains that in cases like yours (I just read in one of your comment that you jump to another page before you lose the selection, you should note that in your question too!) the bean is destroyed, so when you navigate back to your dataTable view it gets reconstructed again. This is the reason why receiverList is empty => no selection.
If you want to save your data while navigating between different views, use a bean with scope wider than #ViewScoped, or simply save the selection to a table in your DB.
EDIT
The problem could be in your rowKey attribute. In the current code it points to the user object, in this case make sure that this objects has proper hashCode, equals and toString implementations. If the user class actually has a key or something, it would be easier to change rowKey to rowKey="#{user.id}".
Check the Showcase. I think it works just like you want.
You are probably sending the data via ajax request you should make sure that it process dataTable itself

Resources