Problemas de Upload de arquivos com Primefaces?

Problemas de Upload de arquivos com Primefaces?

Verifique se adicionou em seu web.xml:

    <!-- Muito importante -->
	<context-param>
		<param-name>primefaces.UPLOADER</param-name>
		<param-value>commons</param-value>
	</context-param>	
	
	<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>
	
	<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>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <context-param>
        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <context-param>
        <param-name>primefaces.UPLOADER</param-name>
        <param-value>auto</param-value>
    </context-param>
    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>	
  

A dependencias para upload de arquivos são:

		
		<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <!-- Faces Implementation -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.2.4</version>
        </dependency>
        <!-- Faces Library -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.2.4</version>
        </dependency>
        <!-- Primefaces Version 5 -->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>5.0</version>
        </dependency>
		<!-- File uploads -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.2.1</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.4</version>
		</dependency>  
		
        <!-- JSP Library -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <!-- JSTL Library -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.1.2</version>
        </dependency>		
	

index.xhtml:

<html 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">
    <h:head>
        <title>Journaldev Tutorial</title>
    </h:head>
    <h:body>
        <h:form enctype="multipart/form-data">
                <p:fileUpload value="#{fileUploadManagedBean.file}"  mode="simple"></p:fileUpload>
                <p:separator/>
                <h:commandButton value="Dummy Action" action="#{fileUploadManagedBean.dummyAction}"></h:commandButton>
        </h:form>
    </h:body>
</html>		

FileUploadManagedBean.java:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
import org.primefaces.model.UploadedFile;
 
@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
    UploadedFile file;
 
    public UploadedFile getFile() {
        return file;
    }
 
    public void setFile(UploadedFile file) {
        this.file = file;
    }
 
    public String dummyAction(){
        System.out.println("O nome do arquivo é "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
        return "";
    }
}

Conclusão
Este artigo tem intenção de prover uma explicação da utilização do FileUpload do Primefaces. Caso não esteja conseguindo realizar upload, tente verificar se todos os passos estão realizados e não falta nenhum detalhe. O componente FileUpload tem muitas funcionalidades e permite que o programador mantenha o foco do trabalho nas regras de negócio ao invés de ficar reinventando a roda.

Anúncios

Java 8 e StringJoiner

Na ultima versão do Java 8 foi adicionado o StringJoiner no pacote java.util.
É uma implementação juntar as pedaços em comparação, um facilitador da antiga abordagem usando StringBuffer / StringBuilder.
Vamos ver o uso do StringJoiner e como funciona a implementação.

Por exemplo, tenho duas cadeias como “Andre” e “Rezende” e eu quero juntar essas cadeias como [Andre, Rezende]. Neste caso, eu tenho o prefixo como “[“, o sufixo como “]” e o delimitador como “,”. StringJoiner tem dois construtores como dado abaixo.
StringJoiner (CharSequence delimitador)
StringJoiner (CharSequence delimitador, CharSequence prefixo, sufixo CharSequence)
Queremos ter prefixo e sufixo, portanto, vamos usar o segundo construtor para o nosso exemplo.

StringJoiner sjr = new StringJoiner(",", "[", "]");
sjr.add("Andre").add("Rezende");
System.out.println("A string final é " + sjr);

Resultado será a saída no console: A string final é [Andre,Rezende]

Se não quiser adicionar o prefixo e sufixo, então:

StringJoiner sjr1 = new StringJoiner(",");
sjr1.add("Andre").add("Rezende");
System.out.println("A string final é " + sjr1);

Resultado será a saída no console: A string final é [Andre,Rezende]

Conclusão, não é uma baita implementação, ainda pode-se utilizar a StringBuilder ou StringBuffer, mas ele facilita um pouco a vida do desenvolvedor.

Exemplo JDBI

Como já comentado no artigo anterior, JDBI é uma forma de implementar seu DAO com mais produtividade, uma biblioteca para se trabalhar SQL e banco de dados relacionais.
Então vamos criar um simples DAO para realizar operações CRUD(Create, Read, Update e Delete).
Para esse exemplo é necessário possuir o MySQL em execução na sua máquina com o esquema teste criado.

No maven (pom.xml) de seu projeto Java, adicione as dependências do JDBI versão 2.73 , do MYSQL 5.1.38 e Junit versão 4.12 para nossos testes unitários.

                <!-- JDBI-->
		<dependency>
			<groupId>org.jdbi</groupId>
			<artifactId>jdbi</artifactId>
			<version>${jdbi.version}</version>
		</dependency>

                <!-- MySQL -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>

                <!-- JUNIT -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>

Criaremos uma interface de nome MyDAO:

public interface MyDAO {}

Agora que temos nossa classe criada, podemos então criar nossos métodos CRUD, vamos implementar uma INSERT, SELECT, UDPATE e DELETE para tabela do MySQL TBLEXEMPLO conforme métodos abaixo:

public interface MyDAO
{
	//Cria tabela TBLEXEMPLO no banco
	@SqlUpdate("CREATE TABLE IF NOT EXISTS TBLEXEMPLO (ID int NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, PRIMARY KEY (ID))")
	void createTable();

	//Insere registro no banco na tabela TBLEXEMPLO
	@SqlUpdate("insert into TBLEXEMPLO (name) values (:name)")
	void insert(@Bind("name") String name);

	//filtra no banco da tabela TBLEXEMPLO
	@SqlQuery("select ID from TBLEXEMPLO where name = :name")
	int findIdByName(@Bind("name") String name);

	//filtra no banco da tabela TBLEXEMPLO
	@SqlQuery("select name from TBLEXEMPLO where id = :id")
	String findNameById(@Bind("id") int id);

	//Altera registro no banco na tabela TBLEXEMPLO
	@SqlUpdate("update TBLEXEMPLO set name = :name where id = :id")
	int updateNameById(@Bind("id") int id, @Bind("name") String name);

	//Apaga registro no banco na tabela TBLEXEMPLO
	@SqlUpdate("delete from TBLEXEMPLO where id = :id")
	int deleteById(@Bind("id") int id);

	//Apaga tabela após conclusão de testes
	@SqlUpdate("drop table TBLEXEMPLO")
	void dropTable();

	//Finaliza conexão
	void close();
}

As anotações @SqlUpdate servem para realizar operações de escrita no branco de dados, em quanto as anotações @SqlQuery para leitura, como SELECT.

Abaixo o código que realiza os testes unitários.

public class MyDAOTest {

	@Test
	public void testJdbi() {
		MyDAO dao = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			//Realiza conexão com o mysql
			DBI dbi = new DBI("jdbc:mysql://localhost/test", "usuario", "senha");
			//Abra conexão com o MySQL
			dao = dbi.open(MyDAO.class);
			//Cria tabela
			dao.createTable();
			//Insere Registro com nome Rezebde
			dao.insert("Rezende");
			int id = dao.findIdByName("Rezende");
			//Nome retornado da consulta deve ser Rezende
			assertEquals(1, id);
			//Altera nome de Rezende para Rezende2
			dao.updateNameById(id, "Rezende2");
			String name2 = dao.findNameById(id);
			//Nome retornado deve ser Rezende2
			assertEquals("Rezende2", name2);

			//Apaga registro criado
			dao.deleteById(id);
			String name3 = dao.findNameById(id);
			//Valor retornado deve ser nulo, pois registro foi apagado acima
			assertNull(name3);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			fail("Error");
		} finally {
			if (dao != null) {
				// Apaga tabela
				dao.dropTable();
				dao.close();
			}
		}
	}
}

Executando os testes acima, não deverá retornar erro.

O download do projeto pode ser feito em meu github: https://github.com/andremrezende/jdbi-example.git

Como visto no post, é muito rápido implementar a camada de persistência utilizando o JDBI e chamadas nativas no banco de dados desejado.

Qual a diferença entre JDBC e JDBI?

Recentemente um colega meu me indicou o usou de JDBI para substituir um ORM. ORM é bom para quem trabalha com múltiplos banco de dados e necessita colocar a mesma aplicação para consumir diferentes bancos de dados. Essa facilidade tem um custo, o custo de performance, pois as ferramentas de ORM precisam converter as chamadas SQL do framework para chamadas que o banco compreende, ou semelhante a nativa.

Então, porque ao invés de não se realizar direto a chamada de JDBC e não tivesse um framework que agilize meu desenvolvimento, mas não comprometa a performance?

Pensando nisso, a galera criou o JDBI, não é nova, tem desde 2004, mas eu só vim descobrir recentemente.

jDBI é uma biblioteca construída em cima de JDBC. JDBC funciona muito bem, mas geralmente parece otimizar para os fornecedores de banco de dados (escritores drivers). jDBI tenta expor a mesma funcionalidade, mas em uma API otimizada para os desenvolvedores.

É nível muito mais baixo do que um ORM como Hibernate ou JPA. A biblioteca é semelhante ao MyBatis (sucessora bifurcada para iBATIS).

jDBI suporta duas APIs estilo, um estilo velho, que se parece com:

List<AlgumaClasse> r = h.createQuery("select * from algo where id = :id and nome = :nome")
.bind("nome", "andre")
.bind("id", 1)
.map(AlgumaClasse.class)
.list();

E o estilo novo da API SQL objeto, que trabalha de uma forma reflexiva  e realmente abstraindo o JDBC:

interface NovoAPISQL
{
@SqlUpdate("insert into algo (id, nome) values (:id, :nome)")
int insert(@Bind("id") int id, @Bind("nome") String nome);

@SqlQuery("select id, nome from algo where id = :id")
AlgumaClasse findById(@Bind("id") long id);
}

A biblioteca tem uma boa referência (javadoc) e documentação estilo tutorial em http://jdbi.org/.

Concluindo

Outro lado interessante é que a comunidade trabalha bastante em melhorias e correções nela, por ser open source.
Vale a pena pensar se seu time ou seu projeto não merece ganhar uma produtividade no trabalho com tarefas de DAO.

Meu github: https://github.com/andremrezende