JSF 2.2 - File upload return java.lang.NullPointerException - jsf-2.2

<h:inputFile/> return a NullPointerException error. I know there is already a lot of stuff about this exception and uploading files with JSF but I've read it all without any success to diagnose this problem.
I am using JSF 2.2 with GlassFish 4.1.1, without PrimeFaces or Tomahawk since you can handle the file upload with JSF 2.2. as I read.
The goal is just to upload a picture on the remote filesystem, and copy the path to the DB to retrieve it later through a datatable.
I've already checked :
1 - My form has the enctype="multipart/form-data" attribute.
2 - My form is not nested in another form though it is part of <ui:composition/>.
3 - I have set all proper filter to process multipart/form-data type :
<filter>
<filter-name>MyFacesExtensionsFilter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
4 - When I remove the <h:inputFile/> tag and its part in the create() method, sending data works without any problem.
5 - I tried to state the ManagedBean as #ApplicationScoped, #ViewScoped and #RequestScoped without any change.
6 - I tried to put the initialize Part attribute in the ManagedBean with abstract methods without any success.
Here is my form :
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:t="http://myfaces.apache.org/tomahawk">
<h:form enctype="multipart/form-data">
<h:outputLabel value="Marque : " />
<h:inputText value="#{carController.car.brand}" />
<br/>
few same inputText
<h:outputLabel value="Photo : " />
<h:inputFile value="#{carController.picture}" required="true" requiredMessage="No file selected."/>
<br/>
<h:commandButton value="Valider" action="#{carController.create}" />
</h:form>
</ui:composition>
Here is my ManagedBean, I've let comments as it is other ways to process the image upload that I've tried :
#Named(value = "carController")
#SessionScoped
public class CarController implements Serializable {
private static final long serialVersionUID = 1L;
#EJB
private CarFacade carFacade;
private Car car;
private Part picture;
private Collection<Car> carCollection;
public CarController() {car = new Car();}
public String create() throws IOException {
/*try ( InputStream inputStream = picture.getInputStream();
FileOutputStream outputStream = new FileOutputStream("D:" +
File.separator + "test" + File.separator +
picture.getSubmittedFileName())) {
int bytesRead = 0;
final byte[] chunck = new byte[1024];
while ((bytesRead = inputStream.read(chunck)) != -1) {
outputStream.write(chunck, 0, bytesRead);
}
}*/
/*Path folder = Paths.get("//resources//cars//");
String filename = FilenameUtils.getName(picture.getName());
String extension = FilenameUtils.getExtension(picture.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);
try (InputStream input = picture.getInputStream()) {
Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}*/
picture.write("\\resources\\cars\\"+picture.getSubmittedFileName()+"."+picture.getContentType());
car.setPicturePath(picture.getSubmittedFileName());
carFacade.create(car);
return "/index.xhtml";
}
Here is exception :
Caused by: java.lang.NullPointerException
at Controller.CarController.create(CarController.java:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.el.parser.AstValue.invoke(AstValue.java:289)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 41 more
Thank you for any idea that may help.
EDIT :
THIS is responsible of the error : picture.write("\resources\cars\"+picture.getSubmittedFileName()+"."+picture.getC‌​ontentType());
I've tried to add this to web.xml without any success :
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<multipart-config>
<location>\resources\cars\</location>
<max-file-size>1300000</max-file-size>
<max-request-size>20000000</max-request-size>
<file-size-threshold>50000</file-size-threshold>
</multipart-config>
</servlet>

Remove the MyFacesExtensionsFilter. That's only necessary when you're using <t:inputFileUpload> instead of <h:inputFile>.
See also:
How to upload file using JSF 2.2 <h:inputFile>? Where is the saved File?

Related

Spring with JSF 2 view scope losing injected values

I have implemented the custom view scope for spring. The page was a redirect from another bean with prerenderView listener that loads a p:datatable. The datatable is loaded with the values and then there is a p:command button to submit the data to a backing bean that calls a service to use the dao implement to update a table. The daoImpl has none of the injected properties now. Datasource and jdbctemplate are now null. I believe I have everything configured to let Spring managed my beans but it seems to me a new instance of the bean is created and spring is not aware therefore doesn't inject the values. Code below has been simplified.
Page
<ui:define name="content">
<h:form id="form1" >
<p:messages id="msgs" autoUpdate="true"/>
<p:panel id="panel1" >
<center>
<p:dataTable id="campaignQTable" var="campaignQ" value="#{campaign.campaignQRows}"
style="text-align:right" editable="true" >
<!-- paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink}
{PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" >
widgetVar="scrollist">
scrollable="true" scrollWidth="1100">
-->
<f:facet name="header">
Update Campaign Qualifications
</f:facet>
<p:column headerText="Contest Name" style="text-align:center">
<h:outputText value="#{campaignQuals.contestName}" />
</p:column>
</p:dataTable>
<p:commandButton value="Save Campaign Qualifications" action="#{campaign.saveCampaignQuals}"
process="#all" update="msgs,panel1" />
</center>
</p:panel>
</h:form>
Bean
#Component("campaign")
#Scope("view")
public class CampaignQualBeans implements Serializable {
private static final long serialVersionUID = 1L;
#Autowired
#Qualifier("CampaignServiceImpl")
CampaignService campaignService;
// CampaignQualsTblId - all rows
ArrayList<CampaignQualsTblId> campaignQNames = new ArrayList<CampaignQualsTblId>();
CampaignQualsTblId selectedCampaignQ;
String contestName;
String contestYear;
String conYearPlus1;
// CampaignQualsTbl - single Campaign all rows for a single year
ArrayList<CampaignQualsTbl> campaignQRows = new ArrayList<CampaignQualsTbl>();
// *************************************************************
// CONSTRUCTORS ************************************************
// *************************************************************
public CampaignQualBeans() {
super();
}
// Upon listener being running, get all the rows for that contest year (campaignQualsUpdate.xhtml)
public void loadCampaignQuals(ComponentSystemEvent event) {
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
return;
}else{
System.out.println("Campaign Qualifications Loaded");
campaignQRows = campaignService.getCampaignQualRows(contestName, contestYear);
int year = Integer.parseInt(contestYear) + 1;
conYearPlus1 = String.valueOf(year);
}
}
// Once button has been selected, save the data to the CampaignQualsTbl (campaignQualsUpdate.xhtml)
public String saveCampaignQuals() {
System.out.println("Contest Saved");
boolean success = campaignService.saveCampaignQRows(contestName, contestYear, campaignQRows);
if (success) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Campaign Qualifications were successfully entered for "
+ contestName + " - " + contestYear));
}
else {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Campaign Qualifications were not saved. Please check entry and save again. " +
"If the problem continues, please contact the Help Desk.",""));
}
return null;
}
}
view scope
public class ViewScope implements Scope{
public Object get(String name, ObjectFactory objectFactory) {
Map<String,Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
if(viewMap.containsKey(name)) {
return viewMap.get(name);
} else {
Object object = objectFactory.getObject();
viewMap.put(name, object);
return object;
}
}
public Object remove(String name) {
return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
}
public String getConversationId() {
return null;
}
public void registerDestructionCallback(String name, Runnable callback) {
//Not supported
}
public Object resolveContextualObject(String key) {
return null;
}
}
Service
#Service("CampaignServiceImpl")
public class CampaignServiceImpl implements CampaignService,ServletContextAware,Serializable{
private static final long serialVersionUID = 1L;
#Autowired
#Qualifier("campaignDao")
CampaignDao campaignDAO;
private transient ServletContext servletContext;
// call DAO to insert the campaign qualifications data into the Campaign_Quals_tbl table
#Override
public boolean saveCampaignQRows(String contestName, String contestYear,
ArrayList<CampaignQualsTbl> campaignQRows) {
boolean success = campaignDAO.insertCampaignQRows(contestName, contestYear, campaignQRows);
return success;
}
#Override
public void setServletContext(ServletContext arg0) {
// TODO Auto-generated method stub
}
}
Dao
#Repository("campaignDao")
public class CampaignDaoImpl implements CampaignDao,Serializable{
private static final long serialVersionUID = 1L;
#Autowired
#Qualifier("myDataSource")
private transient DataSource dataSource;
#Autowired
transient ServletContext context;
private transient JdbcTemplate JDBCTemplate;
private SimpleJdbcCall jdbcCall;
//setup JDBC sources/connections
public void setUserJDBCTemplate(JdbcTemplate userJDBCTemplate) {
this.JDBCTemplate = new JdbcTemplate(dataSource);
}
// *************************************************************
// SQL Statements for the Campaign_Quals_tbl********************
// *************************************************************
private static final String INSERT_CAMPAIGN_Q_ROW =
"Insert into Campaign_Quals_tbl (ContestName, ContestYear, Agent_Tenure, Torunament_Level, Placed_Applications " +
"Life_Premium, Contest_Premium, Min_Life_Premium" +
"Values (?, ?, ?, ?, ?, ?, ?, ?)";
// execute the query that inserts the new rows into the Campaign_Quals_tbl table
#Override
public boolean insertCampaignQRows(String contestName, String contestYear,
ArrayList<CampaignQualsTbl> campaignQRows) {
ArrayList<CampaignQualsTbl> rows = campaignQRows;
try {
JDBCTemplate = new JdbcTemplate(dataSource);
for (CampaignQualsTbl row : rows) {
Object[] parameters = new Object[] {contestName, contestYear, row.getAgentTenure(), row.getTournamentLevel(),
row.getPlacedApplications(), row.getLifePremium(), row.getContestPremium(), row.getMinLifePremium()};
JDBCTemplate.update(INSERT_CAMPAIGN_Q_ROW, parameters);
}
} catch (DataAccessException e){
e.printStackTrace();
return false;
}
return true;
}
}
Logs
START PHASE RESTORE_VIEW(1)
END PHASE RESTORE_VIEW(1)
START PHASE APPLY_REQUEST_VALUES(2)
[DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory - - Creating instance of bean 'campaignQuals'
[DEBUG] - org.springframework.beans.factory.annotation.InjectionMetadata - - Processing injected method of bean 'campaignQuals': AutowiredFieldElement for tfic.com.Campaign.service.CampaignService tfic.com.Campaign.beans.CampaignQualBean.campaignService
[DEBUG] - org.springframework.beans.factory.support.AbstractBeanFactory - - Returning cached instance of singleton bean 'CampaignServiceImpl'
[DEBUG] - org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata - - Invoking init method on bean 'campaignQuals': public void tfic.com.Campaign.beans.CampaignQualBean.loadCampaignQualNames()
[DEBUG] - org.springframework.jdbc.core.JdbcTemplate - - Executing SQL query [Select ContestName, Max(ContestYear) as ContestYear from Campaign_Quals_tbl group by ContestName]
[DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils - - Fetching JDBC Connection from DataSource
[DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils - - Returning JDBC Connection to DataSource
[DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory - - Finished creating instance of bean 'campaignQuals'
END PHASE APPLY_REQUEST_VALUES(2)
START PHASE PROCESS_VALIDATIONS(3)
END PHASE PROCESS_VALIDATIONS(3)
START PHASE UPDATE_MODEL_VALUES(4)
END PHASE UPDATE_MODEL_VALUES(4)
START PHASE INVOKE_APPLICATION(5)
tfic.com.Campaign.model.CampaignQualsTblId#11d93d05
END PHASE INVOKE_APPLICATION(5)
START PHASE RESTORE_VIEW(1)
END PHASE RESTORE_VIEW(1)
START PHASE APPLY_REQUEST_VALUES(2)
END PHASE APPLY_REQUEST_VALUES(2)
START PHASE PROCESS_VALIDATIONS(3)
[DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory - - Creating instance of bean 'campaign'
[DEBUG] - org.springframework.beans.factory.annotation.InjectionMetadata - - Processing injected method of bean 'campaign': AutowiredFieldElement for tfic.com.Campaign.service.CampaignService tfic.com.Campaign.beans.CampaignQualBeans.campaignService
[DEBUG] - org.springframework.beans.factory.support.AbstractBeanFactory - - Returning cached instance of singleton bean 'CampaignServiceImpl'
[DEBUG] - org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory - - Finished creating instance of bean 'campaign'
END PHASE PROCESS_VALIDATIONS(3)
START PHASE UPDATE_MODEL_VALUES(4)
END PHASE UPDATE_MODEL_VALUES(4)
START PHASE INVOKE_APPLICATION(5)
END PHASE INVOKE_APPLICATION(5)
START PHASE RENDER_RESPONSE(6)
Campaign Qualifications Loaded
[DEBUG] - org.springframework.jdbc.core.JdbcTemplate - - Executing prepared SQL query
[DEBUG] - org.springframework.jdbc.core.JdbcTemplate - - Executing prepared SQL statement [Select Agent_Tenure, Tournament_Level, Placed_Applications,Life_Premium, Contest_Premium, Min_Life_Premium from Campaign_Quals_tbl where ContestName = ? and ContestYear = ?]
[DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils - - Fetching JDBC Connection from DataSource
[DEBUG] - org.springframework.jdbc.datasource.DataSourceUtils - - Returning JDBC Connection to DataSource
END PHASE RENDER_RESPONSE(6)
START PHASE RESTORE_VIEW(1)
END PHASE RESTORE_VIEW(1)
START PHASE APPLY_REQUEST_VALUES(2)
END PHASE APPLY_REQUEST_VALUES(2)
START PHASE PROCESS_VALIDATIONS(3)
END PHASE PROCESS_VALIDATIONS(3)
START PHASE UPDATE_MODEL_VALUES(4)
END PHASE UPDATE_MODEL_VALUES(4)
START PHASE INVOKE_APPLICATION(5)
Lost injection datasource and jdbctemplate
END PHASE INVOKE_APPLICATION(5)
WEB.XML
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>SalesCampaignAdmin</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>
*.xhtml</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.PRETTY_HTML</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
Faces-config
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
app context
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/mvc/spring-tx-3.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/mvc/spring-jdbc-3.0.xsd">
<context:component-scan base-package="tfic.*" />
<mvc:annotation-driven/>
<import resource="mvc-dispatcher-servlet.xml"/>
<import resource="spring-datasource.xml"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="view">
<bean class="tfic.com.Campaign.helpers.ViewScope"/>
</entry>
</map>
</property>
</bean>
</beans>
Adding this to web.xml and the datasource is getting injected everytime now. Not sure of the repercussions yet.
<context-param>
<param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
<param-value>false</param-value>
</context-param>
Although I didn't get this exception, I still had the break of injections that the answer describes.
ViewScoped Bean cause NotSerializableException

p:fileUpload calls bean constructor for each file

I'm trying to use <p:fileUpload> to upload a file. Here's the view:
<h:form enctype="multipart/form-data">
<p:growl id="messages" showDetail="true" />
<p:fileUpload
fileUploadListener="#{viewscopedBean.handleFileUpload}"
mode="advanced" dragDropSupport="true" multiple="true"
update="messages" />
</h:form>
Bean:
#ManagedBean
#ViewScoped
public class ViewscopedBean implements Serializable{
private List<UploadedFile> uploadedFiles; //to remember which files have been uploaded
public ViewscopedBean() {
super();
System.out.println("#constructor");
uploadedFiles = new ArrayList<UploadedFile>();
}
public void handleFileUpload(FileUploadEvent event) {
System.out.println("! HANDLE FILE UPLOAD !");
// do something
}
public List<UploadedFile> getUploadedFiles() {
return uploadedFiles;
}
public void setUploadedFiles(List<UploadedFile> uploadedFiles) {
this.uploadedFiles = uploadedFiles;
}
}
web.xml
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>
org.primefaces.webapp.filter.FileUploadFilter
</filter-class>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>512000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
When I click on the upload button, the progressbar is filling up to 100% (like it does something), but then the page is reloaded (constructor is being called for every uploaded file) - the handleFileUpload method is never called.
There aren't any errors or warnings, it just doesn't do what it should. I have JSF 2.0 and use Primefaces 4, maybe there is a problem?
How is this caused and how can I solve it?
First things first, ensure that you have commons-fileupload and its compile-time dependency commons-io on your classpath. The handler not being called suggests that you have these dependencies missing.
Since 4.0, there is now an optional context-param which specifies the server-side engine for handling FileUpload uploads:
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>auto|native|commons</param-value>
</context-param>
In the absence of the context-param, PrimeFaces otherwise selects the most appropriate uploader engine by detection.
Given that you are not using JSF 2.2, this means that it will first select auto, and therefore will redirect to use commons.
So you can see how important it is that you have commons-fileupload and commons-io in your project.
When I copied and pasted your code into a Primefaces 3.5 project containing these dependencies, your code worked for me. The constructor was called once and only once, and the handle method was called each time I uploaded a file.
I repeated the test using 4.0 and again, the constructor was called once and only once.
Here's the configuration that I used in web.xml (needed by commons-fileupload):
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
Here's the backing bean:
package uk;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
#ManagedBean(name = "tempBean")
#ViewScoped
public class TempBean {
private List<UploadedFile> uploadedFiles; //to remember which files have been uploaded
public TempBean() {
super();
System.out.println("#constructor");
uploadedFiles = new ArrayList<UploadedFile>();
}
public void handleFileUpload(FileUploadEvent event) {
System.out.println("! HANDLE FILE UPLOAD !");
// do something
}
public List<UploadedFile> getUploadedFiles() {
return uploadedFiles;
}
public void setUploadedFiles(List<UploadedFile> uploadedFiles) {
this.uploadedFiles = uploadedFiles;
}
}
Here's the page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:body>
<h:form enctype="multipart/form-data">
<p:growl id="messages" showDetail="true" />
<p:fileUpload
fileUploadListener="#{tempBean.handleFileUpload}"
mode="advanced" dragDropSupport="true" multiple="true"
update="messages" />
</h:form>
</h:body>
</html>
And finally here is the snippet of my POM that contains the dependencies and versions for Apache Commons:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>

Spring + DWR fie upload size restriction

I have an application in which files can be uploaded into the application using MultiPartRequest or DWR.
I have the following configuration.
Web.xml
<servlet>
<servlet-name>nerp</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>fileUploadMaxBytes</param-name>
<param-value>5000</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>nerp</servlet-name>
<url-pattern>/nerp/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>nerp</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
nerp-servlet.xml
<beans:bean id="multipartResolver"
class="com.resources.erp.util.ERPMultiPartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<beans:property name="maxUploadSize" value="100000"/>
</beans:bean>
ERPMultiPartResolver
public class ERPMultiPartResolver extends CommonsMultipartResolver {
#Override
public boolean isMultipart(final HttpServletRequest request) {
boolean isMultiPartBoolean = true;
final String urlFromBrowserWithAppName = String.valueOf(request.getRequestURI());
String urlFromBrowser = "";
if(urlFromBrowserWithAppName != null) {
urlFromBrowser = urlFromBrowserWithAppName.replaceAll(String.valueOf(request.getContextPath()),"");
}
if(urlFromBrowser.indexOf("dwr") > 0) {
isMultiPartBoolean = false;
}
else {
isMultiPartBoolean = super.isMultipart(request);
}
return isMultiPartBoolean;
}
}
My MultiPartRequest related upload is getting restricted to the size specified in maxUploadSize property of the ERPMultiPartResolver. But I am not able to restrict the size of the DWR file upload.
I tried using the param-name fileUploadMaxBytes in web.xml but the image size is not getting restricted.
Can someone please help me out on how to restrict the size of the Image through DWR upload when both Spring 3.2.1 and Dwr 3.0 are being used in the project?
I have checked the link
The answer for my above question is that instead of declaring the fileUploadMaxBytes in web.xml in the manner I did above, the declaration should be in the place where you configure your dwrContoller. i.e.
<dwr:controller id="dwrController" debug="true" >
<dwr:config-param name="fileUploadMaxBytes" value="1048"/>
</dwr:controller>
Now with the help of this, I am able to restrict the image size to 1048 bytes.
Earlier my dwrController configuration is as shown below
<dwr:controller id="dwrController" debug="true" />

Managed bean not working after adding Spring configuration

I really do not know what's the cause of the problem. I created a website with hibenate and JSF and later decided to integrate Spring framework as well, but eventually faced a problem.
My managed bean "loginbean" was working perfectly. It also recognizes the method within a JSF page, but when I run the application I see an "error excusion" message.
My bean:
#ManagedBean(name="loginBean")
#SessionScoped
public class LoginBean {
private String username;
private String password;
private int activeindex;
public String Dirige(int a){
setActiveindex(a);
if (a == 0){
return "/Menu.jsf";
}else{
if (a == 1) {
return "/pagess/pagesFabricant/Fabricant.jsf";
}else{
if (a == 2) {
return "/pagess/pagesComposant/Composant.jsf";
}else{
if(a == 3){
return "/pagess/pagesDeq/DEQ.jsf";
}
}
}
}
return null;
}
}
I added SpringBeanFacesELResolver in faces-config.xml:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application> on faces.config.xml
and I also included the relevant listeners in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
My view:
<p:tabMenu activeIndex="#{loginBean.activeindex}">
<p:menuitem value="Home" icon="ui-icon-star" action="#{loginBean.Dirige(0)}" />
<p:menuitem value="Fabricants" icon="ui-icon-wrench" action="#{loginBean.Dirige(1)}" />
<p:menuitem value="Composants" icon="ui-icon-search" action="#{loginBean.Dirige(2)}"/>
<p:menuitem value="Dossier d'equivalence" icon="ui-icon-document" action="#{loginBean.Dirige(3)}"/>
</p:tabMenu>
And finally this is the error I've got:
Grave: javax.el.MethodNotFoundException: /templates/template.xhtml #42,95 action="#{loginBean.Dirige(1)}": Method not found: com.ardia.beans.LoginBean#1af73b2.Dirige(java.lang.Long)
javax.faces.el.MethodNotFoundException: javax.el.MethodNotFoundException: /templates/template.xhtml #42,95 action="#{loginBean.Dirige(1)}": Method not found: com.ardia.beans.LoginBean#1af73b2.Dirige(java.lang.Long)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:92)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
the problem is that I start the application in another tomcat server .. it works well it accepts bean method with parameters
Thx all for your cooperation

JSF2 disabled attribute for validator evaluated only for first cycle?

I found that disabled attribute for any validator I use in JSF2 is evaluated only in the first cycle if my managed bean is ViewScoped.
But I would like to make use of disabled attribute for my validators based on data I get from 4th update phase. So I would expect it reevaluated in all cycles performed on the same view.
Example xhtml page:
<!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">
<h:head></h:head>
<h:body>
<h:form>
<h:panelGrid id="pnlGrid">
<h:inputText id="someValueId" value="#{testPageBean.someValue}">
<f:validateLength minimum="2" maximum="4"
disabled="#{testPageBean.disableValidateLength}"/>
</h:inputText>
<h:messages for="someValueId"/>
<h:commandButton action="#{testPageBean.doSomething}"
value="Do something" />
</h:panelGrid>
</h:form>
</h:body>
</html>
and its view scoped managed bean
package cz.kamosh;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TestPageBean implements Serializable {
boolean disableValidateLength = false;
private String someValue;
public TestPageBean() {
System.out.println("Constructor TestPageBean");
}
public String getSomeValue() {
return someValue;
}
public void setSomeValue(String someValue) {
this.someValue = someValue;
}
/**
* Some action without any navigation as a result
*/
public void doSomething() {
disableValidateLength = !disableValidateLength;
System.out.printf(
"DoSomething, someValue: %1$s, disableValidateLength: %2$b\n",
someValue, disableValidateLength);
}
public boolean isDisableValidateLength() {
System.out.printf("IsValidateLength, disableValidateLength: %1$b\n",
disableValidateLength);
return disableValidateLength;
}
}
I know that I should blame implementation com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl:
private void applyNested(FaceletContext ctx,
UIComponent parent) {
// only process if it's been created
if (!ComponentHandler.isNew(parent)) {
return;
}
...
}
These three rows cause validator not being reevaluated its disabled attribute when I perform action:-(
Could some please give me a hint, what was the motivation for JSF2 guys to implement this way or even better how to solve my problem?
EDIT:
Version of JSF2: 2.0.3-SNAPSHOT
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>JSF2Testing</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
</web-app>
EDIT2 Attempt to follow BalusC' suggestion
Changes on page:
<h:inputText id="someValueId" value="#{testPageBean.someValue}">
<f:validator validatorId="myLengthValidator"/>
<f:attribute name="disableMyLengthValidator" value="#{testPageBean.disableValidateLength}"/>
<f:attribute name="minimum" value="2" />
<f:attribute name="maximum" value="4" />
</h:inputText>
Own validator used instead of standard :
import java.io.Serializable;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.LengthValidator;
import javax.faces.validator.ValidatorException;
#FacesValidator("myLengthValidator")
public class MyLengthValidator extends LengthValidator implements Serializable {
public MyLengthValidator() {
System.out.println("MyLengthValidator constructor");
}
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if((Boolean)component.getAttributes().get("disableMyLengthValidator")) {
return;
}
setMinimum(Integer.valueOf((String)component.getAttributes().get("minimum")));
setMaximum(Integer.valueOf((String)component.getAttributes().get("maximum")));
super.validate(context, component, value);
}
}
My notes about this solution:
requires own implementation even if for standard validators
is dependent on attributes on component (inputText) level
validator is triggered even if it should not be
I am pretty sure it will not behave as we expect when client side validation is provided for validator
I consider is as very ugly and not following JSF2 :-(
You've become another victim of the chicken-egg issue with partial state saving and view scoped beans as described in issue 1492 which is to be fixed in the upcoming Mojarra 2.2.
You should also immediately have realized that something's not entirely right when you saw the constructor of a view scoped bean being invoked on every request instead of only once at the first request of a view.
One of the ways to fix it is to disable the partial state saving altogether:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
See also:
Communication in JSF 2 - #ViewScoped fails in tag handlers
Why does f:validateDoubleRange only work for #SessionScoped?

Resources