Para optimizar los converter cuando utilizamos componentes como podemos recurrir a crear un services que contenga la lista de objetos a utilizar y hacemos la conversión buscando en esa lista en lugar de realizar una consulta al microservicios que devuelve el resultado, esto mejora el desempeño de la aplicación y reduce la cantidad de peticiones al microservicio.
Converter
El Converter lo usaremos para selectOneMenu y Autocomplete de Primefaces. Por lo tanto recibirá una lista de objetos delimitados por la cantidad máxima que se especifique en la variable de configuración en el archivo microprofile-config.properties denominada: #-- converter
converter.max.number.of.elements =25
Como valor predeterminado serán 25 elementos. Para evitar cargar listas muy grandes.
Cuando se realiza una selección en un selectOneMenu o Autocomplete de un elemento que excede los 25 se buscara en el microservicio, en caso contrario se buscara en la lista almacenada en la memoria.
Crear el Services
@ViewScoped
@Named
public class TipoTarjetaConverterServices implements Serializable {
@Inject
TipotarjetaServices tipotarjetaServices;
List<Tipotarjeta> tipotarjetas = new ArrayList<>();
public List<Tipotarjeta> getTipotarjetas() {
return tipotarjetas;
}
public void setTipotarjetas(List<Tipotarjeta> tipotarjetas) {
this.tipotarjetas = tipotarjetas;
}
// <editor-fold defaultstate="collapsed" desc="Optional<Tipotarjeta> get(Long id)">
public Optional<Tipotarjeta> get(Long id) {
Optional<Tipotarjeta> result;
try {
result = tipotarjetas.stream().filter(x -> x.getIdtipotarjeta().equals(id)).findFirst();
if (!result.isPresent()) {
Tipotarjeta tipotarjeta = tipotarjetaServices.findByIdtipotarjeta(id);
if (tipotarjeta != null) {
tipotarjetas.add(tipotarjeta);
return Optional.of(tipotarjeta);
}
result = Optional.empty();
}
return result;
} catch (Exception e) {
FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
}
return Optional.empty();
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="void add(List<Tipotarjeta> tipotarjetas)">
public void add(List<Tipotarjeta> tipotarjetas) {
try {
destroyed();
this.tipotarjetas = tipotarjetas;
} catch (Exception e) {
FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="void destroyed()">
public void destroyed() {
try {
this.tipotarjetas = new ArrayList<>();
} catch (Exception e) {
FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
}
}
// </editor-fold>
}
Crear el Converter
@Named
@FacesConverter(forClass = Tipotarjeta.class, managed = true)
public class TipotarjetaConverter implements Converter<Tipotarjeta> {
@Inject
TipoTarjetaConverterServices tipoTarjetaConverterServices;
// <editor-fold defaultstate="collapsed" desc="String getAsString(FacesContext fc, UIComponent uic, Tipotarjeta t)">
@Override
public String getAsString(FacesContext fc, UIComponent uic, Tipotarjeta t) {
try {
if (t == null) {
return "";
}
if (t.getIdtipotarjeta() != null) {
return t.getIdtipotarjeta().toString();
}
} catch (Exception e) {
new FacesMessage("Error en converter " + e.getLocalizedMessage());
}
return "";
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Tipotarjeta getAsObject(FacesContext fc, UIComponent uic, String submittedValue)">
@Override
public Tipotarjeta getAsObject(FacesContext fc, UIComponent uic, String submittedValue) {
Tipotarjeta result = new Tipotarjeta();
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
Integer id = Integer.parseInt(submittedValue);
Long idTipotarjeta = id.longValue();
Optional<Tipotarjeta> optional = tipoTarjetaConverterServices.get(idTipotarjeta);
if (optional.isPresent()) {
result = optional.get();
}
return result;
} catch (Exception e) {
System.out.println("====================");
System.out.println(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
ConsoleUtil.test("\t " + FacesUtil.nameOfClassAndMethod() + " submittedValue " + submittedValue);
System.out.println("====================");
throw new ConverterException(new FacesMessage(submittedValue + " is not a valid selecction from Converter"), e);
}
}
// </editor-fold>
}
SelectOneMenu
Para el selectOneMenu se pasa la lista completa al services.
En la clase Faces
Necesita agregar en su clase
// # Converter
@Inject
private Config config;
@Inject
@ConfigProperty(name = "converter.max.number.of.elements")
private Provider<Integer> converterMaxNumberOfElements;
@Inject
TipoTarjetaConverterServices tipoTarjetaConverterServices;
/**
* invoca al método para cargar la lista en el ConverterServices
*/
@PostConstruct
public void init() {
try {
loadTipotarjetaByProyecto(proyectoSelected);
} catch (Exception e) {
FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
}
}
/**
Carga la lista de tipotarjeta en el ConverterServices
*/
private void loadTipotarjetaByProyecto(Proyecto proyecto) {
try {
tipoTarjetaConverterServices.add(tipotarjetaServices.loadTipotarjetaByProyecto(proyecto))
);
} catch (Exception e) {
FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
}
}
/**
/**
* Limpia la lista
*/
@PreDestroy
public void preDestroy() {
tipoTarjetaConverterServices.destroyed();
}
En las paginas xhtml
<p:selectOneMenu value="#{tableroFaces.tarjetaSelected.tipotarjeta}"
var="item">
<f:selectItems value="#{tipoTarjetaConverterServices.tipotarjetas}"
var="item"
itemLabel="#{item.tipotarjeta}" itemValue="#{item}"
/>
<p:column>
<i class="#{item.tipotarjeta}" /> #{item.tipotarjeta}
</p:column>
</p:selectOneMenu>
Autocomplete
Pasamos el máximo de registros permitidos que se configuraron en el archivo microprofile-config.properties. Mediante el método:
calcularConverterMaxNumberOfElements(result.size(),converterMaxNumberOfElements.get())
// <editor-fold defaultstate="collapsed" desc="List<Tipotarjeta> completeTipotarjeta(String query)">
public List<Tipotarjeta> completeTipotarjeta(String query) {
List<Tipotarjeta> result = new ArrayList<>();
try {
query = query.trim();
result = tipotarjetaServices.likeByTipotarjeta(query);
tipoTarjetaConverterServices.add(result.subList(0,
calcularConverterMaxNumberOfElements(result.size(),converterMaxNumberOfElements.get()))
);
} catch (Exception e) {
FacesUtil.errorMessage(FacesUtil.nameOfClassAndMethod() + " " + e.getLocalizedMessage());
}
return result;
}
En la pagina xhtml
<p:autoComplete id="tipotarjeta"
multiple="false"
value="#{tipoTarjetaFaces.tipotarjetaSelectedAutocomplete}"
completeMethod="#{tipoTarjetaFaces.completeTipotarjeta}"
var="tipotarjeta"
itemLabel="#{tipotarjeta.tipotarjeta}"
itemValue="#{tipotarjeta}"
forceSelection="true"
title="#{msg['autocomplete.minimo3caracteres']}"
dropdown="true"
minQueryLength="3"
scrollHeight="250"
converter="#{tipotarjetaConverter}"
>
<p:column>
<h:outputText style="vertical-align: middle; margin-left: .5rem" value="#{tipotarjeta.tipotarjeta} - #{tipotarjeta.grupoTipoTarjeta.grupoTipoTarjeta}"/>
</p:column>
<p:ajax event="itemSelect"
listener="#{tipoTarjetaFaces.autocompleteSelectedEvent}"
update=":form:growl, tipotarjeta, dataTable" />
<p:ajax event="itemUnselect"
process="@this"
listener="#{tipoTarjetaFaces.autocompleteUnselectListener}"
update=":form:growl, tipotarjeta, dataTable"
/>
</p:autoComplete>
Top comments (0)