Search code examples
javajsffile-uploadjsf-2myfaces

not invoking the setter method in jsf


i m working on javas server faces. i have used the User.java class as model ,UserController as controller and index.xhtml,ViewProfile,xhtml as view . i traced the following code and i observed that the setter method set setUploadedFile(UploadedFile file){} not invoking .whereas other two setters are invoking.and it is giving NullPointerException. what is the reason ? i m not getting . Here is the code

UserController.java

@Named("controller")
@RequestScoped

public class UserController implements Serializable
{
    private User user=new User();   

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String submit() throws IOException ,SQLException ,ClassNotFoundException, InstantiationException, IllegalAccessException
    {
        String fileName = FilenameUtils.getName(user.getUploadedFile().getName());
        byte[] bytes = user.getUploadedFile().getBytes();
        int index=fileName.indexOf('.');
        String extension=fileName.substring(index);
        File file;
        String path;
        path = "C:/Users/";
        if(extension.equalsIgnoreCase(".jpg")||extension.equalsIgnoreCase(".jpeg")||extension.equalsIgnoreCase(".png")||extension.equalsIgnoreCase(".gif")||extension.equalsIgnoreCase(".tif"))
        {
            file=new File(path);      
            if(!file.exists())
            {
                file.mkdir();                
            }
            path=file+"/"+fileName;
            FileOutputStream outfile=new FileOutputStream(path);           
            outfile.write(bytes);
            outfile.close();  
            PreparedStatement stmt;            
            Connection connection;
            String url="jdbc:mysql://localhost:3306/userprofile";
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            connection = DriverManager.getConnection(url, "root", "mysql"); 
            stmt = connection.prepareStatement("insert into table_profile values('"+user.getUserName()+"','"+user.getUserId()+"','"+path+"')");                                 
            stmt.executeUpdate();
            connection.close(); 
            return "SUCCESS";
        }
        else
        {
            return "fail";
        }              
    }
}

User.java

import org.apache.myfaces.custom.fileupload.UploadedFile;


public class User implements java.io.Serializable
{    
    private String userName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        System.out.println("in setter of username");
        this.userName = userName;
    }

    private String userId;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
        System.out.println("in setter of userid");
    }

    private UploadedFile uploadedFile;

    public UploadedFile getUploadedFile()
    {
        return uploadedFile;
    }

    public void setUploadedFile(UploadedFile uploadedFile) 
    {
        this.uploadedFile = uploadedFile;
        System.out.println("in setter of upload");
    }
}

index.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 lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:t="http://myfaces.apache.org/tomahawk">

    <h:head>
        <title>Profile Demo</title>        
    </h:head>
    <h:body>

        <h:form>
            <h:panelGrid columns="2">

                <h:outputLabel for="userId">User Id</h:outputLabel>
                <h:inputText id="userId" value="#{controller.user.userName}" required="true"></h:inputText>

                <h:outputLabel for="username">Username</h:outputLabel>
                <h:inputText id="username" value="#{controller.user.userId}" required="true"></h:inputText>

               <h:outputLabel for="photo">Profile Picture</h:outputLabel>
               <t:inputFileUpload value="#{controller.user.uploadedFile}"  required="true"></t:inputFileUpload>

               <h:commandButton value="Register" action="#{controller.submit()}"></h:commandButton>            
          </h:panelGrid> 
        </h:form>

    </h:body> 

</html>

Solution

  • <h:form>
    

    Here, you forgot to set the proper form encoding type.

    The default is application/x-www-form-urlencoded which thus means that all request parameter names and values are sent in the query string format (which is essentially a String!). For the uploaded file, only the file name would be sent, not the file content. That's why you end up getting no concrete File.

    You need to set the proper form encoding type.

    <h:form enctype="multipart/form-data">
    

    This way the request parameter names and values are sent in a different and more flexible format which allows enclosing binary data such as file content. However, standard JSF does not support this format and that's why you need to register a servlet filter which can parse it and convert it to usual request parameters, so that JSF can continue doing its job.

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

    See also: