我有一个基本的选择数据表,其中包含电子邮件列表和 SessionScope bean。当我编辑电子邮件时,会出现一个对话框,其中包含要编辑的电子邮件。我选择的第一个电子邮件是正确的电子邮件,但当我选择另一封电子邮件时,会出现随机电子邮件。我不明白为什么会发生这种情况。我检查了官方 Primefaces 5 文档并尝试了代码中提到的所有方法,以及仅使用操作并直接在操作中传递电子邮件。问题是,当我取消对话框时,下一个选定的电子邮件以及除第一个之外的所有其他电子邮件都是随机电子邮件。感谢您的帮助。
我的xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pe="http://primefaces.org/ui/extensions"
xmlns:c="http://java.sun.com/jsp/jstl/core"
template="/facelets/template.xhtml">
<ui:define name="headpage">
<ui:include src="/facelets/head.xhtml"></ui:include>
</ui:define>
<ui:define name="bodypage">
<f:event type="preRenderView" listener="#{emailBean.cargaListaEmail}" />
<f:event
listener="#{busquedaSugerenciasExpedientesBean.resetCajita()}"
type="preRenderView" />
<pe:importConstants
className="es.ja.csalud.sas.intranet.buzoncontacto.constantes.NombreAtributos"
var="nombreAtributos" />
<pe:importConstants
className="es.ja.csalud.sas.intranet.buzoncontacto.constantes.Cadenas"
var="cadenas" />
<pe:importConstants
className="es.ja.csalud.sas.intranet.buzoncontacto.constantes.NavigationRules"
var="navigationRules" />
<div class="container">
<div class="cajaConfiguracion">
<h:form id="formApertura" styleClass="formApertura">
<div class="cabeza">
<h2 class="pageTitle">#{lbl.configuracion_titulo_emails}</h2>
</div>
<p:accordionPanel multiple="true" activeIndex="0" id="acordeon">
<p:tab title="#{lbl.configuracion_titulo_emails}">
<div class="fluido anchoCompleto">
<p:dataTable id="tablaEmails" var="email"
styleClass="dt_configuracion"
tableStyle="table-layout: auto; width:100%" widgetVar="email"
value="#{emailBean.listaEmails}" editable="true"
sortBy="#{email.nombreEmail}" rows="10" paginator="true"
paginatorTemplate="{PreviousPageLink} {PageLinks} {NextPageLink} {CurrentPageReport} {RowsPerPageDropdown}"
currentPageReportTemplate="{currentPage} DE {totalPages}"
rowsPerPageLabel="Mostrar"
rowsPerPageTemplate="5,10,50,100,{ShowAll|'Todo'}"
paginatorPosition="bottom" rowKey="#{email.idEmail}"
emptyMessage="#{msg.tbl_noRegist}"
>
<p:ajax event="rowSelect"
listener="#{grupoBean.onRowSelect}" update="@this" />
<p:column headerText="#{lbl.nombre_email}"
sortBy="#{email.nombreEmail}">
<h:outputText value="#{email.nombreEmail}" />
</p:column>
<p:column headerText="#{lbl.editor}"
sortBy="#{email.modificador}">
<h:outputText value="#{email.modificador}" />
</p:column>
<p:column headerText="#{lbl.f_modificado}"
sortBy="#{email.fechaModificacion}">
<h:outputText value="#{email.fechaModificacion.toDate()}">
<f:convertDateTime pattern="dd/MM/yyyy HH:mm:ss" />
</h:outputText>
</p:column>
<p:column headerText="#{lbl.activo}" sortBy="#{email.activo}">
<h:outputText value="#{email.activo ? 'Si' : 'No'}" />
</p:column>
<p:column styleClass="enlaceEdicion accionConfiguracion"
headerText="#{lbl.list_acciones}">
<h:outputText value="" />
<p:commandButton value="#{lbl.bt_editar}"
title="#{lbl.bt_editar}"
icon="fa fa-edit"
action="#{emailBean.editarEmail()}"
process="@this"
update=":formApertura:acordeon:dialogAnadirEmail"
oncomplete="PF('dialogAnadirEmail').show();"
>
<!-- <p:ajax event="click" listener="#{emailBean.setEmailSeleccionada(email)}" update="@none" /> -->
<!-- <p:confirm header="Editar Email" -->
<!-- message="¿Está seguro que desea editar #{email.nombreEmail}?" -->
<!-- icon="ui-icon-alert" /> -->
<!-- <f:setPropertyActionListener value="#{email}" -->
<!-- target="#{emailBean.emailSeleccionada}"/> -->
<f:actionListener
binding="#{emailBean.setEmailSeleccionada(email)}" />
</p:commandButton>
<p:commandButton value="#{lbl.bt_eliminar}" id="btnEliminar"
title="#{lbl.bt_eliminar}" icon="far fa-trash-alt"
action="#{emailBean.borrarEmail()}" process="@this"
update=":msgs :formApertura:acordeon:tablaEmails">
<f:setPropertyActionListener value="#{email}"
target="#{emailBean.emailSeleccionada}" />
<p:confirm header="Eliminar Email"
message="¿Está seguro que desea eliminar #{email.nombreEmail}?"
icon="ui-icon-alert" />
</p:commandButton>
</p:column>
</p:dataTable>
</div>
<!-- DIALOGO PARA AÑADIR/EDITAR TIPO DE GESTION MASIVA -->
<p:dialog header="#{lbl.email_configuracion}"
widgetVar="dialogAnadirEmail" id="dialogAnadirEmail"
modal="true" minimizable="false" maximizable="false"
closable="true" styleClass="modal1Filas1Campos"
resizable="false">
<h:panelGroup id="panel">
<div class="grupoFiltrosAlineados">
<div class="classFiltrosAlineados">
<h:outputLabel class="labelFiltrosAlineados labelEstilo"
value="#{lbl.nombre_email}" />
<p:inputText styleClass="uiFiltrosAlineados"
label="#{lbl.nombre_email}" required="true"
value="#{emailBean.emailEditar.nombreEmail}">
<f:validateLength maximum="200" />
<f:validator validatorId="com.emailValidator" />
</p:inputText>
</div>
<div class="classFiltrosAlineados">
<h:outputLabel class="labelFiltrosAlineados labelEstilo"
value="#{lbl.activo} " />
<p:selectBooleanCheckbox
styleClass="botonCheckbox labelCheck checkMargen"
value="#{emailBean.emailEditar.activo}">
<p:ajax event="change" process="@this" update="@this" />
</p:selectBooleanCheckbox>
</div>
</div>
</h:panelGroup>
<br />
<p:commandButton styleClass="botonOtros"
value="#{lbl.bt_aceptar}" process="@this dialogAnadirEmail"
action="#{emailBean.saveEmail()}"
update=":msgs formApertura:acordeon:tablaEmails">
</p:commandButton>
<p:commandButton styleClass="botonOtros"
value="#{lbl.bt_cancelar}" type="button"
action="#{emailBean.cleanData()}"
onclick="PF('dialogAnadirEmail').hide();"
/>
</p:dialog>
<!-- BOTONES -->
<h:panelGroup id="botonera">
<div class="botones grandes izquierda">
<p:commandButton value="#{lbl.bt_anadir}"
styleClass="botonOtros"
action="#{emailBean.editarEmailCrear()}" immediate="true"
oncomplete="PF('dialogAnadirEmail').show();" process="@this"
update=":formApertura:acordeon:dialogAnadirEmail" />
</div>
</h:panelGroup>
<!-- -->
</p:tab>
</p:accordionPanel>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Sí" styleClass="ui-confirmdialog-yes"
icon="ui-icon-check" />
<p:commandButton value="No" styleClass="ui-confirmdialog-no"
icon="ui-icon-close" />
</p:confirmDialog>
</h:form>
</div>
</div>
</ui:define>
<ui:define name="footpage">
<ui:include src="/facelets/foot.xhtml"></ui:include>
</ui:define>
</ui:composition>
我的豆类:
package es.ja.csalud.sas.intranet.buzoncontacto.configuracion.presentation.boundary;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.joda.time.DateTime;
import org.primefaces.PrimeFaces;
import org.primefaces.event.SelectEvent;
import es.ja.csalud.sas.intranet.buzoncontacto.centros.business.entity.Centro;
import es.ja.csalud.sas.intranet.buzoncontacto.configuracion.business.boundary.Emails;
import es.ja.csalud.sas.intranet.buzoncontacto.configuracion.business.entity.Email;
import es.ja.csalud.sas.intranet.buzoncontacto.constantes.Cadenas;
import es.ja.csalud.sas.intranet.buzoncontacto.constantes.Presentacion;
import es.ja.csalud.sas.intranet.buzoncontacto.gestoresInternos.business.boundary.GestoresInternos;
import es.ja.csalud.sas.intranet.buzoncontacto.grupo.business.boundary.Grupos;
import es.ja.csalud.sas.intranet.buzoncontacto.grupo.business.entity.Grupo;
import es.ja.csalud.sas.intranet.buzoncontacto.presentation.BaseBean;
import es.ja.csalud.sas.intranet.buzoncontacto.presentation.helper.Util;
import es.ja.csalud.sas.intranet.buzoncontacto.springsecurity.presentation.boundary.UserReclamacionesBean;
@Named
@SessionScoped
public class EmailBean extends BaseBean implements Serializable{
/**
*
*/
private static final long serialVersionUID = -2075577773794936417L;
@Inject
private Emails emails;
@Inject
protected transient UserReclamacionesBean userReclamacionesBean;
@Inject
protected Grupos grupos;
@Inject
private GestoresInternos gestoresInternos;
private List<Email> listaEmails;
private Email emailSeleccionada;
@Inject
private UserReclamacionesBean user;
private Email emailEditar;
private Centro centroUsuario = null;
/**
* Inits the.
*/
@PostConstruct
public void init() {
// Obtener la lista de Emails que pertenecen al Centro Hopitalario del Usuario
this.listaEmails = new ArrayList<>();
this.cargaListaEmail();
this.emailSeleccionada = new Email();
this.emailEditar = new Email();
}
/**
* Actualiza a traves de la sesion el Centro Hospitalario al que pertenece (o ha
* seleccionado) el Usuario.
*/
public void actualizaCentroSeleccionadoUsuario() {
Object objCentro = getSession().getAttribute(Cadenas.CENTRO_SELECCIONADO_USUARIO);
if (objCentro instanceof Centro) {
centroUsuario = (Centro) objCentro;
}
}
public void cargaListaEmail() {
this.actualizaCentroSeleccionadoUsuario();
if (null != this.listaEmails) {
if (this.userReclamacionesBean.getRole().equals(Cadenas.BCS_ADMINISTRADOR)) {
this.listaEmails = this.emails.findByCentro(centroUsuario.getId());
}else if(this.userReclamacionesBean.getRole().equals(Cadenas.BCS_GESTOR_INTERNO)) {
Grupo grupo = grupoEmail();
this.listaEmails = this.emails.findByCentroYGrupo(grupo, centroUsuario.getId());
}
}
}
private Grupo grupoEmail() {
Grupo grupo;
if (this.userReclamacionesBean.getRole().equals(Cadenas.BCS_ADMINISTRADOR)) {
grupo = this.grupos.getById(0L);
} else {
grupo = this.gestoresInternos.getGestorInternoByDNI(userReclamacionesBean.getIdentificador())
.getGrupoGestorInterno();
}
return grupo;
}
public void editarEmail() {
this.emailEditar = new Email(this.emailSeleccionada);
System.out.println("editarEmail = " + this.emailEditar.getNombreEmail());
}
public void prepararEdicion(Email email) {
this.emailSeleccionada = email;
System.out.println("email = " + email.getNombreEmail());
editarEmail();
}
public void saveEmail() {
boolean insert = true;
Grupo grupo = this.grupoEmail();
// Validacion
if (this.validateEmail()) {
if (null == this.emailEditar.getId()) {
this.emailEditar.setFechaInicioVigencia(new DateTime());
this.emailEditar.setCreador(user.getNameUser());
this.emailEditar.setFechaCreacion(new DateTime());
this.emailEditar.setFechaModificacion(new DateTime());
this.emailEditar.setModificador(user.getNameUser());
this.emailEditar.setGrupo(grupo);
this.emailEditar.setIdCentro(centroUsuario.getId());
} else {
this.emailEditar.setFechaInicioVigencia(new DateTime());
this.emailEditar.setFechaModificacion(new DateTime());
this.emailEditar.setModificador(user.getNameUser());
this.emailEditar.setGrupo(grupo);
insert = false;
}
this.emails.guardar(this.emailEditar);
this.emails.flush();
if (insert) {
this.addMessageInfo(Presentacion.LBL.getString("Guardado_correcto"),
Presentacion.LBL.getString("EMAIL_CONFIGURACION_CREADA"));
}
if (!insert) {
this.addMessageInfo(Presentacion.LBL.getString("Guardado_correcto"),
Presentacion.LBL.getString("EMAIL_CONFIGURACION_MODIFICADA"));
}
PrimeFaces.current().executeScript("PF('dialogAnadirEmail').hide()");
this.emailEditar = new Email();
this.cargaListaEmail();
}
}
public void cleanData() {
this.emailEditar = new Email();
//this.emailSeleccionada = new Email();
//PrimeFaces.current().ajax().update("formApertura:acordeon:dialogAnadirEmail");
}
public void borrarEmail() {
emailSeleccionada.setFechaFinVigencia(new DateTime());
emailSeleccionada.setActivo(false);
this.emails.update(emailSeleccionada);
this.emails.flush();
this.emailEditar = new Email();
this.emailSeleccionada = new Email();
this.addMessageInfo(Presentacion.EXITO_ELIMINAR, "");
this.cargaListaEmail();
}
protected boolean validateEmail() {
boolean validacion = true;
// Validamos que sea un email correcto
if (!Util.validateEmailNoCorporativo(this.emailEditar.getNombreEmail())) {
this.addMessageError(Presentacion.ERROR_VALID, Cadenas.ERR_CORREO_INVALIDO);
validacion = false;
}
return validacion;
}
public void onRowSelect(SelectEvent event) {
final Email p = (Email) event.getObject();
this.emailSeleccionada = p;
}
public void editarEmailCrear() {
this.emailEditar = new Email();
}
public List<Email> getListaEmails() {
return listaEmails;
}
public void setListaEmails(List<Email> listaEmail) {
this.listaEmails = listaEmail;
}
public Email getEmailSeleccionada() {
return emailSeleccionada;
}
public void setEmailSeleccionada(Email tipoMasivaSeleccionada) {
this.emailSeleccionada = tipoMasivaSeleccionada;
}
public Email getEmailEditar() {
return emailEditar;
}
public void setEmailEditar(Email tipoMasivaEditar) {
this.emailEditar = tipoMasivaEditar;
}
public Centro getCentroUsuario() {
return centroUsuario;
}
public void setCentroUsuario(Centro centroUsuario) {
this.centroUsuario = centroUsuario;
}
}
罪魁祸首就在这里:
This basically reloads the model behind the
<p:dataTable>
during every HTTP request. Note that an Ajax request also counts as a HTTP request. When that Ajax request doesn't include anupdate
of the<p:dataTable>
, then the presentation won't necessarily reflect the actual contents of the reloaded model. By default the records are selected by list index, so when the reloaded model has a different item in the selected index than being presented to the enduser, then the enduser will have the experience of seeing a "random" item.Just remove that
preRenderView
listener. You don't need it here. You're already explicitly loading the model in the@PostConstruct
and in the save method of your backing bean. That's more than sufficient.In case you really need to reload the model during every request for some reason, then you can alternatively also instruct the
<p:dataTable>
to select the records by entity ID instead of list index. You can do so by specifying therowKey
attribute.See also:
That said, PrimeFaces 5.x is ancient (released May 2014, thus currently almost 10 years old!) and has serious security bugs. Try to keep your software up to date. See also among others JSF Cryptojacking Malware.