h:inputFile setter and action not invoked anymore since adding Spring Boot - spring

I work with Spring Boot 2.4.5 and JSF 2.2.20.
The h:inputFile is not working anymore since adding Spring Boot. The action method is not called, also the setter is not called.
I have written the following backing bean:
package com.dpdhl.gmppp.portal.webapp;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.Serializable;
#Component("uploadTestController")
#Scope("request")
public class UploadTestController implements Serializable {
private static final long serialVersionUID = 1L;
private Part file1;
private String message;
public String uploadFile() throws IOException {
boolean file1Success = false;
if (file1 != null && file1.getSize() > 0) {
file1Success = true;
}
if (file1Success) {
setMessage("File successfully uploaded");
} else {
setMessage("Error, select atleast one file!");
}
return null;
}
public Part getFile1() {
return file1;
}
public void setFile1(Part file1) {
this.file1 = file1;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
and this view:
<h2>Select and upload a file</h2>
<p>
<h:outputText value="#{uploadTestController.message}"
rendered="#{!empty uploadTestController.message}"></h:outputText>
<h:form prependid="false" enctype="multipart/form-data">
<h:panelGrid>
<h:inputFile value="#{uploadTestController.file1}"></h:inputFile>
<h:commandButton action="#{uploadTestController.uploadFile()}"
value="Upload"></h:commandButton>
</h:panelGrid>
</h:form>
</p>
If I use JSF without Spring Boot, then it works.
Can anyone help me here?

Related

How to display form validation constraints message on GWT Material inputs using Editor and Validation Framework from Presenter's class?

I use:
Gwt-platform
Gwt Validation
Gwt UiEditor framework
Gwt Material inputs
After constraints validation I would like to display error messages. This is supported by gwt material inputs, like MaterialTextBox using method:  materialTextBox.setError("Please provide your name");
The problem is that it can be only executed from view class:
public class LoginView extends ViewWithUiHandlers<LoginUiHandlers> implements LoginPresenter.MyView {
interface Binder extends UiBinder<Widget, LoginView> {}
/** The driver to link the proxy bean with the view. */
public interface EditorDriver extends SimpleBeanEditorDriver<LoginModel, LoginView> { }
#UiField MaterialTextBox email;
#UiField MaterialTextBox password;
#UiField MaterialButton loginButton;
#UiField MaterialCheckBox keepMeLoggedInCheckbox;
#Inject
LoginView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
addClickHandlerToLoginButton();
}
//#UiHandler("loginButton")
private void onLoginButtonClick(ClickEvent e){
getUiHandlers().onLoginButtonClick();
}
private void addClickHandlerToLoginButton() {
loginButton.addClickHandler(new ClickHandler() {
#Override public void onClick(ClickEvent event) {
onLoginButtonClick(event);
}
});
}
#Override
public SimpleBeanEditorDriver<LoginModel, ?> createEditorDriver() {
EditorDriver driver = GWT.create(EditorDriver.class);
driver.initialize(this);
return driver;
}
public void test() {}
}
But I do all my editor/validation action in Presenter, and I do not have there any View connection I could use:
public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> implements LoginUiHandlers {
public interface MyView extends BeanEditView<LoginModel>, HasUiHandlers<LoginUiHandlers> {}
public static final Type<RevealContentHandler<?>> SLOT_Login = new Type<RevealContentHandler<?>>();
#ProxyStandard
#NameToken(NameTokens.login)
public interface MyProxy extends ProxyPlace<LoginPresenter> {}
// Editor
private SimpleBeanEditorDriver<LoginModel, ?> editorDriver;
private static final LoginService service = GWT.create(LoginService.class);
private LoginModel model = new LoginModel("","");
#Override
public void onLoginButtonClick() {
if (editorDriver.isDirty()) {
model = editorDriver.flush();
validateModel();
if (editorDriver.hasErrors()) {
MaterialToast.fireToast("Errors occur");
StringBuilder errorBuilder = new StringBuilder();
for (EditorError error : editorDriver.getErrors()) {
errorBuilder.append(error.getMessage() + "\n");
}
MaterialToast.fireToast(errorBuilder.toString());
} else {
service.login(
model, new MethodCallback<Integer>() {
#Override
public void onSuccess(Method method, Integer response) {
MaterialToast.fireToast("Succefully set info. status code: " + response);
}
#Override
public void onFailure(Method method, Throwable exception) {
MaterialToast.fireToast("Error setting");
}
});
}
} else {
MaterialToast.fireToast("Data has not changed");
}
}
private void validateModel() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<LoginModel>> violations = validator.validate(model);
if (violations.size() > 0) {
editorDriver.setConstraintViolations(new ArrayList<ConstraintViolation<?>>(violations));
}
}
#Inject
LoginPresenter(EventBus eventBus,MyView view, MyProxy proxy) {
super(eventBus, view, proxy, RevealType.Root);
getView().setUiHandlers(this);
editorDriver = getView().createEditorDriver();
editorDriver.edit(model);
}
}
I think that I should add an interface where I will declare methods to access inputs in view. And do implementation of that. But I don't know how. Please help me.
I've make it working. But really I am not quite sure what did happened that it start to work. So I will just share my working code:
Presenter
package pl.korbeldaniel.cms.client.login;
import java.util.ArrayList;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.MethodCallback;
import gwt.material.design.client.ui.MaterialToast;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
import com.gwtplatform.mvp.client.HasUiHandlers;
import pl.korbeldaniel.cms.client.editor.BeanEditView;
import pl.korbeldaniel.cms.client.model.LoginModel;
import pl.korbeldaniel.cms.client.place.NameTokens;
import pl.korbeldaniel.cms.client.service.LoginService;
public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> implements LoginUiHandlers {
#ProxyStandard
#NameToken(NameTokens.login)
public interface MyProxy extends ProxyPlace<LoginPresenter> {}
public interface MyView extends BeanEditView<LoginModel>, HasUiHandlers<LoginUiHandlers> {}
public static final Type<RevealContentHandler<?>> SLOT_Login = new Type<RevealContentHandler<?>>();
// Editor
private SimpleBeanEditorDriver<LoginModel, ?> editorDriver;
private static final LoginService service = GWT.create(LoginService.class);
private LoginModel model = new LoginModel();
#Override
public void onLoginButtonClick() {
if (editorDriver.isDirty()) {
model = editorDriver.flush();
validateModel();
if (editorDriver.hasErrors()) {
MaterialToast.fireToast("Errors occur");
} else {
service.login(
model, new MethodCallback<Integer>() {
#Override
public void onSuccess(Method method, Integer response) {
MaterialToast.fireToast("Succefully set info. status code: " + response);
}
#Override
public void onFailure(Method method, Throwable exception) {
MaterialToast.fireToast("Error setting");
}
});
}
} else {
MaterialToast.fireToast("Data has not changed");
}
}
private void validateModel() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<LoginModel>> violations = validator.validate(model);
GWT.log(String.valueOf(violations.size()));
if (violations.size() > 0) {
editorDriver.setConstraintViolations(new ArrayList<ConstraintViolation<?>>(violations));
}
model.validate();
}
#Inject
LoginPresenter(EventBus eventBus,MyView view, MyProxy proxy) {
super(eventBus, view, proxy, RevealType.Root);
getView().setUiHandlers(this);
editorDriver = getView().createEditorDriver();
editorDriver.edit(model);
}
public enum EditorMode {
VIEW, EDIT, CREATE
};
}
Ui Handler
package pl.korbeldaniel.cms.client.login;
import com.gwtplatform.mvp.client.UiHandlers;
interface LoginUiHandlers extends UiHandlers {
void onLoginButtonClick();
}
ValidatorFactory
package pl.korbeldaniel.cms.client.login;
import javax.validation.Validator;
import pl.korbeldaniel.cms.client.model.LoginModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.validation.client.AbstractGwtValidatorFactory;
import com.google.gwt.validation.client.GwtValidation;
import com.google.gwt.validation.client.impl.AbstractGwtValidator;
public final class SampleValidatorFactory extends AbstractGwtValidatorFactory {
/**
* Validator marker for the Validation Sample project. Only the classes and
* groups listed in the {#link GwtValidation} annotation can be validated.
*/
#GwtValidation(LoginModel.class)
public interface GwtValidator extends Validator {
}
#Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
View
package pl.korbeldaniel.cms.client.login;
import gwt.material.design.client.ui.MaterialButton;
import gwt.material.design.client.ui.MaterialCheckBox;
import gwt.material.design.client.ui.MaterialTextBox;
import javax.inject.Inject;
import pl.korbeldaniel.cms.client.model.LoginModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.gwtplatform.mvp.client.ViewWithUiHandlers;
public class LoginView extends ViewWithUiHandlers<LoginUiHandlers> implements LoginPresenter.MyView {
interface Binder extends UiBinder<Widget, LoginView> {}
/** The driver to link the proxy bean with the view. */
public interface EditorDriver extends SimpleBeanEditorDriver<LoginModel, LoginView> { }
#UiField MaterialTextBox email;
#UiField MaterialTextBox password;
#UiField MaterialButton loginButton;
#UiField MaterialCheckBox keepMeLoggedInCheckbox;
#Inject
LoginView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
addClickHandlerToLoginButton();
}
//#UiHandler("loginButton")
private void onLoginButtonClick(ClickEvent e){
getUiHandlers().onLoginButtonClick();
}
private void addClickHandlerToLoginButton() {
loginButton.addClickHandler(new ClickHandler() {
#Override public void onClick(ClickEvent event) {
onLoginButtonClick(event);
}
});
}
#Override
public SimpleBeanEditorDriver<LoginModel, ?> createEditorDriver() {
EditorDriver driver = GWT.create(EditorDriver.class);
driver.initialize(this);
return driver;
}
}
View Binder
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:m="urn:import:gwt.material.design.client.ui"
xmlns:e="urn:import:pl.korbeldaniel.cms.client.login">
<m:MaterialRow ui:field="loginWidget">
<m:MaterialColumn grid="s12 m4 l4" offset="l4 m4" >
<m:MaterialTitle title="Login" description="Please provide your account credentials."/>
<m:MaterialPanel padding="5" shadow="1" addStyleNames="{style.panel}">
<m:MaterialPanel addStyleNames="{style.fieldPanel}">
<!-- <m:MaterialImage url="http://b.vimeocdn.com/ps/339/488/3394886_300.jpg" type="CIRCLE" addStyleNames="{style.imgProfile} z-depth-1"/> -->
<m:MaterialTextBox ui:field="email" type="EMAIL" placeholder="Email"/>
<m:MaterialTextBox ui:field="password" type="PASSWORD" placeholder="Password"/>
<m:MaterialRow addStyleNames="{style.rowAction}">
<m:MaterialColumn grid="s12 m12 l6">
<m:MaterialCheckBox ui:field="keepMeLoggedInCheckbox" text="Keep me logged in"/>
</m:MaterialColumn>
</m:MaterialRow>
<m:MaterialButton ui:field="loginButton" waves="LIGHT" text="Log In" width="100%"/>
</m:MaterialPanel>
</m:MaterialPanel>
</m:MaterialColumn>
</m:MaterialRow>
</ui:UiBinder>

JSF holds the values in components in different users

I'm new in JSF, and I'm trying to use JSF 2 and Richfaces + Spring (3.2.3) + Hibernate (3.6). The application server is JBoss 7.1. The problem is when I deploy my application and use it in my computer it works well, but when I use it in another computer in my LAN or other browser in my same computer, all the values stored in the first use are set in all the fields. I have to say that the application works well but it seems that one user is using it even if I use it in different computers at the same time.
I also deployed it in Cloudbees but it has the same problem through internet.
PD. I searched other similar questions but I couldn't find an answer.
My login.xhtml:
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="Usuario "/>
<h:inputText id="txt_usuario" value="#{login.usuario}" required="true" requiredMessage="Debe ingresar su usuario."/><br/>
<h:message for="txt_usuario" />
<h:outputLabel value="Password "/>
<h:inputSecret id="pwd_password" value="#{login.password}" required="true" requiredMessage="Debe ingresar su password."/><br/>
<h:message for="pwd_password" />
</h:panelGrid>
<h:commandButton value="Login" action="#{login.iniciarSesion()}"/>
</h:form>
package com.ejemplo.app.controller;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.ejb.PostActivate;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ejemplo.app.entidades.Usuario;
import com.ejemplo.app.service.UsuarioService;
import com.ejemplo.app.util.Constantes;
#Component("login")
#ManagedBean(name = "login")
#SessionScoped
public class LoginController {
#Autowired
private UsuarioService usuarioService;
private String usuario;
private String password;
public LoginController() {
}
public String iniciarSesion() {
try {
Usuario login = usuarioService.validarIngreso(usuario, password);
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getApplication().createValueBinding("#{sessionScope.user}").setValue(facesContext, login);
if(login.getTipo().equalsIgnoreCase(Constantes.CARGO_RESIDENTE))
return "residente/home";
else if(login.getTipo().equalsIgnoreCase(Constantes.CARGO_LOGISTICA))
return "logistica/home";
else if(login.getTipo().equalsIgnoreCase(Constantes.CARGO_ADMINISTRADOR))
return "administrador/home";
else
System.err.println("Usuario no encontrado.");
} catch (Exception e) {
System.err.println(e.getMessage());
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario no encontrado.", "Descripcion del mensaje."));
}
return "solicitud_materiales";
}
public String getUsuario() {
return usuario;
}
public void setUsuario(String usuario) {
this.usuario = usuario;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

login jsf spring and hibernate error

i'm working on a login application using jsf, spring and hibernate.
I have a problem, i get invalid password and username even if i put valid username and password. i don't understand why. please help me :)
login.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<h:head>
<title>Facelet Title</title>
<link href="http://localhost:8084/jsf/resources/css/login.css" type="text/css" rel="stylesheet"/>
</h:head>
<h:body>
<div class="container">
<h:form id="formLogin">
<p:growl id="growl" sticky="true" showDetail="true" life="3000" />
<p:panel header="Login">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="username" value="Username:" />
<p:inputText id="username" value="#{utilisateurBean.utilisateur.username}" required="true" label="username" />
<h:outputLabel for="password" value="Password:" />
<p:password id="password" value="#{utilisateurBean.utilisateur.password}" required="true" label="password" />
<f:facet name="footer">
<p:commandButton value="Login" update="growl" actionListener="#{utilisateurBean.login(actionEvent)}"
oncomplete="handleLoginRequest(xhr, status, args)" />
</f:facet>
</h:panelGrid>
</p:panel>
</h:form>
</div>
<script type="text/javascript">
function handleLoginRequest(xhr, status, args) {
if(args.validationFailed || !args.loggedIn) {
PF('#formLogin').jq.effect("shake", {times:5}, 100);
}
else {
location.href = args.route;
}
}
</script>
</h:body>
</html>
UtilisateurBean.java
package controller;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import model.services.UtilisateurMetier;
import model.services.UtilisateurMetierImpl;
import net.vo.Utilisateur;
import org.primefaces.context.RequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component
#Scope("view")
public class UtilisateurBean{
private Utilisateur utilisateur;
#Autowired
private UtilisateurMetier utilisateurMetier;
String route = "";
public UtilisateurBean() {
this.utilisateurMetier = new UtilisateurMetierImpl();
if(this.utilisateur == null)
{
this.utilisateur = new Utilisateur();
}
}
public Utilisateur getUtilisateur() {
return utilisateur;
}
public void setUtilisateur(Utilisateur utilisateur) {
this.utilisateur = utilisateur;
}
public void login(ActionEvent actionEvent)
{
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage msg;
boolean loggedIn;
this.utilisateur = this.utilisateurMetier.verify(this.utilisateur);
if (this.utilisateur != null)
{
loggedIn = true;
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("utilisateur", this.utilisateur.getUsername());
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", this.utilisateur.getUsername());
route ="/jsf/faces/annee.xhtml";
System.out.println(this.utilisateur.getUsername());
} else {
loggedIn = false;
msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Login Error", "Invalid mot de passe");
if(this.utilisateur == null)
{
this.utilisateur = new Utilisateur();
}
}
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("loggedIn", loggedIn);
context.addCallbackParam("route", route);
}
}
UtilisateurMetier.java
package model.services;
import java.util.List;
import net.vo.Utilisateur;
public interface UtilisateurMetier {
public Utilisateur verify(Utilisateur utilisateur);
}
UtilisateurMetierImpl.java
package model.services;
import dao.UtilisateurDao;
import java.util.List;
import javax.faces.context.FacesContext;
import net.vo.Utilisateur;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class UtilisateurMetierImpl implements UtilisateurMetier{
#Autowired
private UtilisateurDao dao;
public void setDao(UtilisateurDao dao) {
this.dao = dao;
}
#Override
public Utilisateur verify(Utilisateur utilisateur)
{
return dao.verify(utilisateur);
}
}
UtilisateurDao.java
package dao;
import java.util.List;
import net.vo.Utilisateur;
public interface UtilisateurDao {
public Utilisateur getUtilisateur(Integer id);
public Utilisateur verify(Utilisateur utilisateur);
}
UtilisateurHibernateDao.java
package dao;
import java.util.List;
import net.vo.Utilisateur;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.stereotype.Repository;
#Repository
public class UtilisateurHibernateDao implements UtilisateurDao{
private List<Utilisateur> listeUtilisateurs;
#Override
public Utilisateur getUtilisateur(Integer id) {
Session session = HibernateUtil.getSession();
try
{
session.beginTransaction();
Query q = session.createQuery("from Utilisateur as u where u.idUtilisateur=" + id);
return (Utilisateur) q.uniqueResult();
}
finally
{
session.close();
}
}
#Override
public Utilisateur verify(Utilisateur utilisateur) {
Utilisateur user = this.getUtilisateur(utilisateur.getIdUtilisateur());
if(user != null)
{
if(!utilisateur.getPassword().equals(user.getPassword()))
{
user = null;
}
}
return user;
}
}
Utilisateur.java
package net.vo;
// Generated 21 mai 2014 21:08:45 by Hibernate Tools 3.6.0
/**
* Utilisateur generated by hbm2java
*/
public class Utilisateur implements java.io.Serializable {
private int idUtilisateur;
private String username;
private String password;
public Utilisateur() {
}
public Utilisateur(int idUtilisateur, String username, String password) {
this.idUtilisateur = idUtilisateur;
this.username = username;
this.password = password;
}
public int getIdUtilisateur() {
return this.idUtilisateur;
}
public void setIdUtilisateur(int idUtilisateur) {
this.idUtilisateur = idUtilisateur;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
edit
public void login(ActionEvent actionEvent)
{
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage msg;
boolean loggedIn;
this.utilisateur = this.utilisateurMetier.verify(this.utilisateur);
if (this.utilisateur != null)
{
loggedIn = true;
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("utilisateur", this.utilisateur.getUsername());
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", this.utilisateur.getUsername());
route ="/jsf/faces/index.xhtml";
System.out.println(this.utilisateur.getUsername());
} else {
loggedIn = false;
msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Login Error", "Invalid mot de passe");
if(this.utilisateur == null)
{
this.utilisateur = new Utilisateur();
}
}
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("loggedIn", loggedIn);
context.addCallbackParam("route", route);
}
In UtilisateurHibernateDao#verify you're trying to retrieve the user from its id:
Utilisateur user = this.getUtilisateur(utilisateur.getIdUtilisateur());
But you only have the username ans password. I suggest to create another method that can return the user from its username:
public Utilisateur getUtilisateurByUsername(String username) {
Session session = HibernateUtil.getSession();
try {
session.beginTransaction();
Query q = session.createQuery("from Utilisateur as u where u.username=:username")
.setString("username", username);
return (Utilisateur) q.uniqueResult();
}
finally {
session.close();
}
}
And use this method in verify:
Utilisateur user = this.getUtilisateurByUsername(utilisateur.getUsername());
//rest of the code...
Not part of the main problem but IMO the verify method should be at service level, not at dao. Data Access Objects are meant to only retrieve and update the data to the data source, while the business rules should be in service layer.

Service not Autowired in JSF Converter [duplicate]

This question already has answers here:
How to inject #EJB, #PersistenceContext, #Inject, #Autowired, etc in #FacesConverter?
(5 answers)
Closed 7 years ago.
I am working on a web application using PrimeFaces, JPA, Hibernate and JSF 2.0.
I have a converter for my JSF p:selectOneMenu. My problem is, when I run my application the Service descriptifService is not autowired, it return NULL !
The converter :
#Component
#FacesConverter(value = "descriptifConverter")
public class DescriptifConverter implements Converter {
#Autowired
#RmiClient
private IDescriptifService descriptifService;
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
if (arg2 == null || arg2.isEmpty()) {
return null;
}
String descriptif = arg2;
Long value = Long.valueOf(descriptif);
DescriptifDto result = new DescriptifDto();
result = descriptifService.findById(value);
return result;
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
if(arg2 == null || ((DescriptifDto) arg2).getIdDescriptif() == null) return null;
DescriptifDto descriptif = new DescriptifDto();
if(arg2 instanceof DescriptifDto) {
descriptif = (DescriptifDto) arg2;
String idDescriptif = descriptif.getIdDescriptif().toString();
return (idDescriptif != null) ? String.valueOf(idDescriptif) : null;
} else throw new ConverterException("Something wrong!" + arg2.hashCode() + arg2.toString());
}
}
The JSF code :
<p:selectOneMenu value="#{lotController.selectedDescriptif}"
effect="fade">
<f:selectItems value="#{lotController.listDescriptifs}" var="descriptif"
itemLabel="#{descriptif.libelle}" itemValue="#{descriptif}" />
<f:converter binding="#{descriptifConverter}" />
</p:selectOneMenu>
Here you have two options:
1 - Register a context provider bean:
AppContext Class:
import org.springframework.context.ApplicationContext;
public class AppContext {
private static ApplicationContext ctx;
public static void setApplicationContext(
ApplicationContext applicationContext) {
ctx = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return ctx;
}
}
ApplicationContextProvider class:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ApplicationContextProvider implements ApplicationContextAware {
#Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
AppContext.setApplicationContext(applicationContext);
}
}
Register the bean:
<bean id="contextApplicationContextProvider" class="com.example.ApplicationContextProvider" />
Now, through the context, you can get a reference to your service bean anyware:
IDescriptifService descriptifService = AppContext.getApplicationContext().getBean(
IDescriptifService.class);
2 - Store the converted values inside the ViewMap (inspired in this post)
I like this solution because it doesn't required database access which improves the performance of the application.
AbstractConverter class
import java.util.HashMap;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
public abstract class AbstractConverter implements Converter {
private static final String KEY = "com.example.converters.AbstractConverter";
protected Map<String, Object> getViewMap(FacesContext context) {
Map<String, Object> viewMap = context.getViewRoot().getViewMap();
#SuppressWarnings({ "unchecked", "rawtypes" })
Map<String, Object> idMap = (Map) viewMap.get(KEY);
if (idMap == null) {
idMap = new HashMap<String, Object>();
viewMap.put(KEY, idMap);
}
return idMap;
}
#Override
public final Object getAsObject(FacesContext context, UIComponent c,
String value) {
if (value == null || value.isEmpty()) {
return null;
}
return getViewMap(context).get(value);
}
#Override
public final String getAsString(FacesContext context, UIComponent c,
Object value) {
if (value != null) {
String id = getConversionId(value);
if (id == null || id.isEmpty()) {
throw new IllegalArgumentException(
"Objeto não pode ser convertido.");
}
getViewMap(context).put(id, value);
return id;
}
return null;
}
//Every concrete class must provide an unique conversionId String
//to every instance of the converted object
public abstract String getConversionId(Object value);
}
Here we create a storage place inside the ViewMap. We can now use it to store any converter object we need.
Here is an example of a concrete converter:
EntityConverter class
import javax.faces.convert.FacesConverter;
import com.example.AbstractEntity;
#FacesConverter("entity")
public class EntityConverter extends AbstractConverter {
#Override
public String getConversionId(Object value) {
if (value instanceof AbstractEntity) {
AbstractEntity entity = (AbstractEntity) value;
StringBuilder sb = new StringBuilder();
sb.append(entity.getClass().getSimpleName());
sb.append("#");
sb.append(entity.getId());
return sb.toString();
}
return null;
}
}
A late response, but I had the same problem of not being able to Autowire Spring beans into a JSF Converter, so I removed the #FacesConverter annotation and declared the converter component as session scoped, then, as you did, using the f:converter tag with binding attribute solved the problem. In your case:
#Component
#Scope(WebApplicationContext.SCOPE_SESSION)
public class DescriptifConverter implements Converter {
...
}
should work...

Spring/JSF2 and #ViewScoped

I want to use spring managed beans for my JSF2 controllers so that autowiring works. I know that there is no #ViewScoped in spring and I know a few implementations of #ViewScoped floating around various blogs (one from the primefaces lead).
Is any of them used in a real application and considered stable? Maybe one of them is recommended or widely used and I'm just not able to find it.
There is one :) Without memory leaks and with #PreDestroy support. Tested in production. Here.
package org.nkey.primefaces.scopes.test.spring.scope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PreDestroyViewMapEvent;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
/**
* #author m.nikolaev Date: 21.11.12 Time: 0:37
*/
public class ViewScope implements Scope, Serializable, HttpSessionBindingListener {
private static final Logger LOGGER = LoggerFactory.getLogger(ViewScope.class);
private final WeakHashMap<HttpSession, Set<ViewScopeViewMapListener>> sessionToListeners = new WeakHashMap<>();
#Override
public Object get(String name, ObjectFactory objectFactory) {
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (viewMap) {
if (viewMap.containsKey(name)) {
return viewMap.get(name);
} else {
LOGGER.debug("Creating bean {}", name);
Object object = objectFactory.getObject();
viewMap.put(name, object);
return object;
}
}
}
#Override
public Object remove(String name) {
throw new UnsupportedOperationException();
}
#Override
public String getConversationId() {
return null;
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
LOGGER.debug("registerDestructionCallback for bean {}", name);
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
ViewScopeViewMapListener listener =
new ViewScopeViewMapListener(viewRoot, name, callback, this);
viewRoot.subscribeToViewEvent(PreDestroyViewMapEvent.class, listener);
HttpSession httpSession = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
final Set<ViewScopeViewMapListener> sessionListeners;
synchronized (sessionToListeners) {
if (!sessionToListeners.containsKey(httpSession)) {
sessionToListeners.put(httpSession, new HashSet<ViewScopeViewMapListener>());
}
sessionListeners = sessionToListeners.get(httpSession);
}
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (sessionListeners) {
Set<ViewScopeViewMapListener> toRemove = new HashSet<>();
for (ViewScopeViewMapListener viewMapListener : sessionListeners) {
if (viewMapListener.checkRoot()) {
toRemove.add(viewMapListener);
}
}
sessionListeners.removeAll(toRemove);
sessionListeners.add(listener);
}
if (!FacesContext.getCurrentInstance().getExternalContext().getSessionMap().containsKey("sessionBindingListener")) {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("sessionBindingListener", this);
}
}
#Override
public Object resolveContextualObject(String key) {
return null;
}
#Override
public void valueBound(HttpSessionBindingEvent event) {
LOGGER.debug("Session event bound {}", event.getName());
}
#Override
public void valueUnbound(HttpSessionBindingEvent event) {
LOGGER.debug("Session event unbound {}", event.getName());
final Set<ViewScopeViewMapListener> listeners;
synchronized (sessionToListeners) {
if (sessionToListeners.containsKey(event.getSession())) {
listeners = sessionToListeners.get(event.getSession());
sessionToListeners.remove(event.getSession());
} else {
listeners = null;
}
}
if (listeners != null) {
for (ViewScopeViewMapListener listener : listeners) {
listener.doCallback();
}
}
}
public void clearFromListener(ViewScopeViewMapListener listener) {
LOGGER.debug("Removing listener from map");
HttpSession httpSession = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
if (httpSession != null) {
synchronized (sessionToListeners) {
if (sessionToListeners.containsKey(httpSession)) {
sessionToListeners.get(httpSession).remove(listener);
}
}
}
}
}

Resources