我有一个基本的选择数据表,其中包含电子邮件列表和 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>
我的 Bean 类:
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;
}
}
罪魁祸首就在这里:
<f:event type="preRenderView" listener="#{emailBean.cargaListaEmail}" />
这基本上会在每个 HTTP 请求期间重新加载
<p:dataTable>
后面的模型。请注意,Ajax 请求也算作 HTTP 请求。当该 Ajax 请求不包含 update
中的 <p:dataTable>
时,演示文稿不一定反映重新加载模型的实际内容。默认情况下,记录是按列表索引选择的,因此当重新加载的模型在所选索引中具有与呈现给最终用户不同的项目时,最终用户将获得看到“随机”项目的体验。
只需删除那个
preRenderView
监听器即可。你在这里不需要它。您已经在 @PostConstruct
和支持 bean 的 save 方法中显式加载模型。这已经足够了。
如果由于某种原因您确实需要在每个请求期间重新加载模型,那么您也可以指示
<p:dataTable>
通过实体 ID 而不是列表索引来选择记录。您可以通过指定 rowKey
属性来执行此操作。
<p:dataTable ...
value="#{emailBean.listaEmails}"
var="email"
rowKey="#{email.id}"
...>
也就是说,PrimeFaces 5.x 很古老(2014 年 5 月发布,因此目前已有近 10 年历史!)并且存在严重的安全错误。尝试使您的软件保持最新。另请参阅 JSF 加密劫持恶意软件。