JSF holds the values in components in different users - spring

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;
}
}

Related

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

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?

Display user name in Spring

I can login and logout, and display a list of users on a page doing this:
<li th:each="user : ${users}">
<span th:text="${user.firstname}+' '+${user.lastname}"></span>
</li>
I would now simply like to display the name of the currently logged in user, but I am not sure how. I would like to add it to a header fragment so every page shows clearly who the user logged in is.
LoginForm.java:
package com.demo.spring.domain;
import org.hibernate.validator.constraints.NotEmpty;
public class LoginForm {
public String getAccountname() {
return accountname;
}
public void setAccountname(String accountname) {
this.accountname = accountname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#NotEmpty
String accountname;
#NotEmpty
String password;
}
login.html:
<h3>User Login</h3>
<form action="#" th:action="#{/user/login}" th:object="${user}" method="post">
<!--<input type="hidden" th:field="*{id}"/>-->
<p>Account Name:</p> <input type="text" th:field="*{accountname}"/>
<p>Password:</p> <input type="password" th:field="*{password}"/>
<p/><input type="submit" value="Login"/>
</form>
<div th:if="${message!=null}">
<br/>
<span th:text="${message}"/>
</div>
UserController code for logging in:
package com.demo.spring.controller;
import com.demo.spring.domain.LoginForm;
import com.demo.spring.domain.User;
import com.demo.spring.domain.UserSearchForm;
import com.demo.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.List;
#Controller
#RequestMapping(value = "/user")
public class UserController {
#Autowired
UserService userService;
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String loginView(Model model)
{
LoginForm user = new LoginForm();
model.addAttribute("user", user);
return "login";
}
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(Model model, #Valid #ModelAttribute("user") LoginForm user, BindingResult bindingResult, HttpSession session)
{
if(bindingResult.hasErrors())
{
model.addAttribute("user", user);
model.addAttribute("message", "Please provide information in each field");
return "login";
}
if (userService.validateLogin(user)==false)
{
model.addAttribute("user", user);
model.addAttribute("message", "Your accountname and/or password are incorrect");
return "login";
}
session.setAttribute("login", true);
return "redirect:/";
}
UserService
package com.demo.spring.service;
import com.demo.spring.domain.LoginForm;
import com.demo.spring.domain.UserSearchForm;
import com.demo.spring.domain.User;
import com.demo.spring.domain.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class UserService {
public boolean validateLogin(LoginForm user)
{
List<User> users = userRepository.checkUserInput(user.getAccountname(),user.getPassword());
return users !=null && users.size()>0;
}
We put the logged in users' name in the session
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(Model model, #Valid #ModelAttribute("user") LoginForm user, BindingResult bindingResult, HttpSession session)
{
...
session.setAttribute("accountName", user.getAccountName());
session.setAttribute("login", true);
return "redirect:/";
}
Once put in the session, the session variables can simply be accessed as ${session.accountName}. So you can use <span th:text="${session.accountName}"></span> in your header fragment.

Problems with AccessReferenceMap

I am using AccessReferenceMap from OWASP to secure my ids in URLs. The problem is that when list of IDs to be obfuscated is related to particular customer. Here is my configuration:
<bean id="hyperlinkMapping" class="web.security.HyperlinkMapping" scope="session">
<aop:scoped-proxy />
</bean>
<bean id="tracksAccessMap" class="web.security.EntityAccessMap"
scope="session" factory-method="create">
<constructor-arg index="0" ref="allTrackIdsForCustomer" />
<aop:scoped-proxy/>
</bean>
<bean id="allTrackIdsForCustomer" scope="session"
factory-bean="webTrackDAO"
factory-method="findAllTrackIdsForCustomer">
<aop:scoped-proxy/>
</bean>
<bean id="webTrackDAO" class="web.repository.impl.WebTrackDAOImpl"/>
EntityAccessMap:
package web.security;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.owasp.esapi.AccessReferenceMap;
import org.owasp.esapi.errors.AccessControlException;
import org.owasp.esapi.reference.RandomAccessReferenceMap;
import org.springframework.stereotype.Component;
import core.domain.Entity;
#Component
public class EntityAccessMap<T extends Entity> implements AccessMap<T> {
private static Logger logger = Logger.getLogger(EntityAccessMap.class);
private static final long serialVersionUID = -436098952674898327L;
private AccessReferenceMap<String> map = new RandomAccessReferenceMap();
public EntityAccessMap() {
}
private EntityAccessMap(final List<T> entities) {
logger.info("Entities size: " + entities.size());
for (final T entity : entities) {
map.addDirectReference(entity);
}
}
public <T extends Entity> AccessMap<T> create(final List<T> entities) {
logger.info("calling create with entities' size " + entities.size() );
return new EntityAccessMap<>(entities);
}
public String getIndirectReference(final T entity) {
for( Iterator it = map.iterator(); it.hasNext(); ) {
logger.info((String)it.next().toString());
}
logger.info("Entity: " + map.getIndirectReference(entity));
return map.getIndirectReference(entity);
}
public T getDirectReference(final String indirectReference) {
try {
return map.getDirectReference(indirectReference);
} catch (AccessControlException e) {
throw new IllegalArgumentException("Indirect Reference is not valid", e);
}
}
}
AccessMap:
package web.security;
import java.io.Serializable;
import core.domain.Entity;
public interface AccessMap<T extends Entity> extends Serializable {
String getIndirectReference(final T entity);
T getDirectReference(final String indirectReference);
}
HyperlinkMapping:
package web.security;
import java.io.Serializable;
import org.springframework.beans.factory.annotation.Autowired;
import core.domain.track.Track;
public class HyperlinkMapping implements Serializable {
private static final long serialVersionUID = -2011016815710653498L;
#Autowired AccessMap<Track> tracksAccessMap;
public String getTrackId(final Track track) {
return tracksAccessMap.getIndirectReference(track);
}
public Track getTrack(final String indirectId) {
return tracksAccessMap.getDirectReference(indirectId);
}
}
So, what I want to achieve: tracksAccessMap should be filled only with customer's related ids, not whole set. How to initialize all these beans after customer's login (and setting customerId session attribute)?
EDIT 1: additional code:
TracksController:
package web.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import core.constants.WebConstants;
import web.service.TrackService;
#Controller
#Secured("ROLE_USER")
#RequestMapping(WebConstants.WEB_MY)
#Scope("session")
public class TracksController {
#Autowired
private TrackService trackService;
#Autowired
private HyperlinkMapping hyperlinkMapping;
#RequestMapping(value=WebConstants.WEB_MYTRACKS, method = RequestMethod.GET, produces = "application/json")
public ModelAndView showTracks( HttpServletRequest request, #RequestParam(value = "pageSize", required = false) Integer pageSize ) {
ModelAndView mv = new ModelAndView();
mv.addObject("pagedListHolder",trackService.getTracksList(request, pageSize == null ? 10 : pageSize ));
mv.addObject("hyperlinkMapping",hyperlinkMapping);
return mv;
}
}
centerColTracks.jsp
<c:forEach items="${pagedListHolder.pageList}" var="item">
<tr>
<td>${item.id}</td>
<td style="color:blue;text-align:right">${item.name}</td>
<td style="color:blue;text-align:right">${item.trackDate}</td>
<td style="color:blue;text-align:right">${item.description}</td>
</tr>
</c:forEach>
hyperlinkMapping.getTrackId(item) should return ONLY trackId (taken from AccessReferenceMap) related ONLY for customer logged in. In other words - hyperlinkMapping should be instantiated right after the login.
I have two ideas how to do this: 1. AOP with after-returning advice, or 2. use SimpleUrlAuthenticationSuccessHandler, where I can instantiate HyperlinkMapping after login. Or I can use it with the current implementation and I just simply forgot something?

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.

Ajax loader is not getting called in a file upload custom component in JSF 2.0

In my current project I am trying to create a file upload custom component because we have a constraint that we can’t use any component library. Our requirement is to create single file upload, upon selecting and uploading a file it will get displayed in a data table below that component. User will be able to download the uploaded file and if required can delete the uploaded file also. There will be a ajax loader which needs to be fired upon uploading a file. Pictorially the UI looks like this.
________________________ __________ ____________
| | | Browse | | Upload |
|_______________________| |_________| |___________|
______________________________________________
| | |
| File1.pdf | * |
|_______________________________________|_____|
| | |
| File2.pdf | * |
|_______________________________________|_____|
To create this component I have taken help from Core JavaServer Pages(3e) to create custom component & BalusC’s blogs to trigger ajax call from a jsf page(jsf.ajax.addOnEvent). Here is the entire code of Renderer, xhtml, and managedbean. For the time being I have used a h:outputtext instead of h:datatable to update the page.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.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:corejsf="http://corejsf.com">
<h:head>
<title>A file upload test</title>
<h:outputScript name="jsf.js" library="javax.faces" target="head"/>
<script>
jsf.ajax.addOnEvent(function(data) {
var ajaxstatus = data.status;
var ajaxloader = document.getElementById("ajaxloader");
switch (ajaxstatus) {
case "begin": // This is called right before ajax request is been sent.
ajaxloader.style.display = 'block';
break;
case "complete":
ajaxloader.style.display = 'none';
break;
case "success": // NOOP.
break;
} });
</script>
</h:head>
<h:body>
<h:form>
<h:commandButton value="hello"></h:commandButton>
</h:form>
<h:form enctype="multipart/form-data">
Upload a photo of yourself:
<corejsf:upload uploadButton="upload"/>
<h:outputText id="updateText" value="#{user.value}"></h:outputText>
<h:commandButton action="#{user.submit}" value="Initiate"></h:commandButton>
</h:form>
<img id="ajaxloader" src="ajax-loader.gif" style="display: none;" />
</h:body>
</html>
The Renderer:
package com.corejsf;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
#FacesRenderer(componentFamily="javax.faces.Input",
rendererType="com.corejsf.Upload")
public class UploadRenderer extends Renderer {
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
if (!component.isRendered()) return;
ResponseWriter writer = context.getResponseWriter();
String ajax = "jsf.ajax.request(this, event,{render:'j_idt11:updateText'}); return false";
String clientId = component.getClientId(context);
System.out.println("parentid>>>>>>"+component.getParent().getClientId(context));
System.out.println(clientId);
System.out.println("upload button >>>>>>"+(String)component.getAttributes().get("uploadButton"));
writer.startElement("input", component);
writer.writeAttribute("type", "file", "type");
writer.writeAttribute("name", clientId+":INPUT_FILE", "clientId");
writer.endElement("input");
writer.startElement("input", component);
writer.writeAttribute("type", "submit", null);
writer.writeAttribute("name", clientId + ":FILE_UPLOAD", null);
writer.writeAttribute("value", "Upload", "value");
writer.writeAttribute("onclick", ajax, null);
writer.endElement("input");
writer.flush();
}
public void decode(FacesContext context, UIComponent component) {
Map<String,String> requestMap = context.getExternalContext ().getRequestParameterMap();
String clientId = component.getClientId(context);
System.out.println("getId>>>>>>>"+component.getId());
if(requestMap.containsKey(clientId+":FILE_UPLOAD")){
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("true");
ExternalContext external = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) external.getRequest();
//String clientIdFile = component.getClientId(context);
FileItem item = (FileItem) request.getAttribute(clientId+":INPUT_FILE");
System.out.println("filename>>>>"+item.getName()+">>>");
System.out.println("file blank>>>>"+item.getName().equals(""));
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
UserBean userBean = (UserBean) FacesContext.getCurrentInstance().getApplication()
.getELResolver().getValue(elContext, null, "user");
try {
userBean.setUploadedFile(item.getInputStream());
userBean.setValue(userBean.getUploadedFileList().size());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
System.out.println("false");
}
}
Managed bean:
package com.corejsf;
import java.io.Serializable;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
//import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import java.io.InputStream;
import java.util.ArrayList;
#ManagedBean(name="user")
#ViewScoped
public class UserBean implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private ArrayList<InputStream> uploadedFileList = new ArrayList<InputStream>();
public ArrayList<InputStream> getUploadedFileList() {
return uploadedFileList;
}
public void setUploadedFileList(ArrayList<InputStream> uploadedFileList) {
this.uploadedFileList = uploadedFileList;
}
private int value = 0;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public String getId() { return id; }
public void setId(String newValue) { id = newValue; }
public void setUploadedFile(InputStream inputStream){
uploadedFileList.add(inputStream);
}
}
UploadFilter:
package com.corejsf;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadFilter implements Filter {
private int sizeThreshold = -1;
private String repositoryPath;
public void init(FilterConfig config) throws ServletException {
repositoryPath = config.getInitParameter(
"com.corejsf.UploadFilter.repositoryPath");
try {
String paramValue = config.getInitParameter(
"com.corejsf.UploadFilter.sizeThreshold");
if (paramValue != null)
sizeThreshold = Integer.parseInt(paramValue);
}
catch (NumberFormatException ex) {
ServletException servletEx = new ServletException();
servletEx.initCause(ex);
throw servletEx;
}
}
public void destroy() {
}
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
boolean isMultipartContent
= ServletFileUpload.isMultipartContent(httpRequest);
if (!isMultipartContent) {
chain.doFilter(request, response);
return;
}
DiskFileItemFactory factory = new DiskFileItemFactory();
if (sizeThreshold >= 0)
factory.setSizeThreshold(sizeThreshold);
if (repositoryPath != null)
factory.setRepository(new File(repositoryPath));
ServletFileUpload upload = new ServletFileUpload(factory);
try {
#SuppressWarnings("unchecked") List<FileItem> items
= (List<FileItem>) upload.parseRequest(httpRequest);
final Map<String, String[]> map = new HashMap<String, String[]>();
for (FileItem item : items) {
String str = item.getString();
if (item.isFormField())
map.put(item.getFieldName(), new String[] { str });
else
httpRequest.setAttribute(item.getFieldName(), item);
}
chain.doFilter(new
HttpServletRequestWrapper(httpRequest) {
public Map<String, String[]> getParameterMap() {
return map;
}
// busywork follows ... should have been part of the wrapper
public String[] getParameterValues(String name) {
Map<String, String[]> map = getParameterMap();
return (String[]) map.get(name);
}
public String getParameter(String name) {
String[] params = getParameterValues(name);
if (params == null) return null;
return params[0];
}
public Enumeration<String> getParameterNames() {
Map<String, String[]> map = getParameterMap();
return Collections.enumeration(map.keySet());
}
}, response);
} catch (FileUploadException ex) {
ServletException servletEx = new ServletException();
servletEx.initCause(ex);
throw servletEx;
}
}
}
taglib.xml:
<facelet-taglib version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
<namespace>http://corejsf.com</namespace>
<tag>
<tag-name>upload</tag-name>
<component>
<component-type>javax.faces.Input</component-type>
<renderer-type>com.corejsf.Upload</renderer-type>
</component>
</tag>
</facelet-taglib>
The issue that I am facing with this code is that the ajax is updating the h:outputtext but the ajax loader is not working. It is not getting displayed upon uploading a file. It should get displayed on begin status and disappear on complete status. Besides, firefox error console shows a “Reference error: jsf is not defined” message.
I have put a :
<h:outputScript name="jsf.js" library="javax.faces" target="head"/>
inside h:head tag . But it did not help. The webpage is not responding after adding this line in firefox but it is working on IE, though ajax loader is not working in any case.
Please help.
Thanks in advance.

Resources