Exportando relatório criado com Ireport em java + jsf

Olá a todos!

Bom este é um post destinado a quem já trabalha com Ireport, pois será somente exibido como exportar esses relatórios para pdf com java e jsf.

Posteriormente será criando post com um passo a passo de como se construir um relatório completo usando Ireport.

O código abaixo é usado para realizar a exportação:


import javax.faces.context.FacesContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

	public void executeReport() {
		FacesContext facesContext = FacesContext.getCurrentInstance();

		HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();

		InputStream reportStream = facesContext.getExternalContext().getResourceAsStream("caminho_arquivo.jasper");

		response.setContentType("application/pdf");

		response.setHeader("Content-disposition", "inline;filename=relatorio.pdf");

		try {
			ServletOutputStream servletOutputStream = response.getOutputStream();

			JRBeanCollectionDataSource datasource = new JRBeanCollectionDataSource(arrayList);

			JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parameters, datasource);

			servletOutputStream.flush();
			servletOutputStream.close();
		} catch (JRException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			facesContext.responseComplete();
		}
	}

É bom lembrar que na sua pagina.xhtml é preciso usar um link, pois se usado botões para chamar este método o resultado não será o esperado.

Abaixo segue um exemplo de como esse método deve ser chamado:


<h:commandLink id="exportReport" immediate="true" action="#{bean.executeReport()}" value="#{messages['report.export']}"/>

Espero que ajude.

Até mais…

Trabalhando com datas utilizando a API JodaTime – Parte 1

Olá a todos!

Trabalhar com datas parece ser um pouco complicado, realizar cálculos de diferenças, trabalhar com minutos, segundos e até milissegundos.

Para isso temos as classes java.util.Date e java.util.Calendar, mas agora existem um nova API JodaTime.

Bom, neste primeiro será mostrado que com o uso desta API é possível deixar seu código mais limpo efetuando cálculos com datas.

Abaixo segue um exemplo:


import java.util.Calendar;
import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Duration;
import org.joda.time.Hours;
import org.joda.time.Months;
import org.joda.time.Years;

public class JodaTimeExample {

	public static void main(String[] args) {
		
		Calendar calendarInitial = Calendar.getInstance();
		calendarInitial.set(Calendar.HOUR_OF_DAY, 1);
		calendarInitial.set(Calendar.MINUTE, 0);
		calendarInitial.set(Calendar.SECOND, 0);
		calendarInitial.set(Calendar.MILLISECOND, 0);
		
		Calendar calendarFinish = Calendar.getInstance();
		calendarFinish.add(Calendar.DAY_OF_MONTH, 37);
		calendarFinish.set(Calendar.HOUR_OF_DAY, 15);
		calendarFinish.set(Calendar.MINUTE, 0);
		calendarFinish.set(Calendar.SECOND, 0);
		calendarFinish.set(Calendar.MILLISECOND, 0);
		
		Date dateInitial = calendarInitial.getTime();
		Date dateFinish = calendarFinish.getTime();
		
		//--Exemplos que podem ajudar a deixar o código mais orgainzado
		
		System.out.println("\n");
		
		System.out.println(Duration.standardDays(1).getMillis() + " milliseconds.");
		System.out.println(Duration.standardDays(1).getStandardHours() + " hours.");
		System.out.println(Duration.standardDays(1).getStandardMinutes() + " minutes.");
		System.out.println(Duration.standardDays(1).getStandardSeconds() + " seconds.");

		System.out.println("\n");
		
		System.out.println(Duration.standardHours(48).getMillis() + " milliseconds.");
		System.out.println(Duration.standardHours(48).getStandardDays() + " days.");
		System.out.println(Duration.standardHours(48).getStandardMinutes() + " minutes.");
		System.out.println(Duration.standardHours(48).getStandardSeconds() + " seconds.");

		System.out.println("\n");
		
		System.out.println(Duration.standardMinutes(2880).getMillis() + " milliseconds.");
		System.out.println(Duration.standardMinutes(2880).getStandardDays() + " days.");
		System.out.println(Duration.standardMinutes(2880).getStandardHours() + " hours.");
		System.out.println(Duration.standardMinutes(2880).getStandardSeconds() + " seconds.");
		
		System.out.println("\n");

		System.out.println(Duration.standardSeconds(360000).getMillis() + " milliseconds.");
		System.out.println(Duration.standardSeconds(360000).getStandardDays() +" days.");
		System.out.println(Duration.standardSeconds(360000).getStandardHours() + " hours.");
		System.out.println(Duration.standardSeconds(360000).getStandardMinutes() + " minutes.");

		System.out.println("\n");

		//--Exemplos que podem ajudar a calcular diferenças entre datas
		
		System.out.println(Hours.hoursBetween(new DateTime(dateInitial), new DateTime(dateFinish)).getHours() + " hours.");
		System.out.println(Days.daysBetween(new DateTime(dateInitial), new DateTime(dateFinish)).getDays() + " days."); 
		System.out.println(Months.monthsBetween(new DateTime(dateInitial), new DateTime(dateFinish)).getMonths() + " months.");
		System.out.println(Years.yearsBetween(new DateTime(dateInitial), new DateTime(dateFinish)).getYears() + " years.");
		
		System.out.println("\n");
		
	}
	
}

No próximo post será mostrado mais sobre essa API e sobre a persistências dessas datas na sua base de dados.

Até mais…

Criptografando senhas usando MD5 em Java

Olá a todos!

Quando se trabalha com sistemas com múltiplos usuários é interessante criptografar as senhas do usuários para uma maior confiabilidade e descrição dessas senhas, para isso uma boa opção é o MD5.

Uma senha criptografada com MD5 não pode ser novamente transformada no texto de origem, portanto a comparação deve ser feita por duas strings criptografadas.

Abaixo segue uma classe que vai ajudar na criação de MD5.


import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class ConvertPasswordToMD5 {

	public static String convertPasswordToMD5(String password) throws NoSuchAlgorithmException {
		MessageDigest md = MessageDigest.getInstance("MD5");

		BigInteger hash = new BigInteger(1, md.digest(password.getBytes()));

		return String.format("%32x";, hash);
	}

}

Bom, abaixo segue o código de teste desta classe que criptografa as senhas em MD5.


import java.security.NoSuchAlgorithmException;

public class Test {

	public static void main(String[] args) {
		String password1 = "Senha1";
		String password2 = "Senha2";

		try {
			String password1MD5 = ConvertPasswordToMD5.convertPasswordToMD5(password1);
			String password2MD5 = ConvertPasswordToMD5.convertPasswordToMD5(password2);

			String passwordCompareMD5 = ConvertPasswordToMD5.convertPasswordToMD5(password1);

			System.out.println("Password1: " + password1MD5);
			System.out.println("Password2: " + password2MD5);

			System.out.println("passwordCompareMD5: " + passwordCompareMD5);

			if (password1MD5.equals(passwordCompareMD5)) {
				System.out.println("Compare OK");
			} else {
				System.out.println("Compare NOK");
			}

			if (password2MD5.equals(passwordCompareMD5)) {
				System.out.println("Compare OK");
			} else {
				System.out.println("Compare NOK");
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
}

As saídas deste teste são:

Password1: be6b9084a5dcdb09af8f433557a2119c
Password2: 14621de3463eb7e1b3606d5514bbf800
passwordCompareMD5: be6b9084a5dcdb09af8f433557a2119c
Compare OK
Compare NOK

Em outro post será abordada a criptografia feita com RSA, onde é possível criptografar e descriptografar.

Até mais.

Aumentando o tempo de transação do JBoss

Olá a todos!

Para quem trabalha com JBoss AS 5.1.GA já deve ter se deparado com a seguinte exception “com.arjuna.ats.jbossatx.jta.TransactionManagerService”, ela acontece pois o tempo padrão de uma transação no JBoss é de 5 minutos.

Bom, mas sempre teremos métodos que levaram mais do que 5 minutos para responder, então vamos aumentar este tempo fazendo as configurações necessárias.

Para realizar esta configuração vá ate o arquivo jboss/server/default/deploy/transaction-jboss-beans.xml e edite a seguinte linha:


<property name="transactionTimeout">300</property>

O valor 300 é o padrão, pois é configurado em segundos, onde 300 segundos são iguais a 5 minutos, mude este valor para um que atenda as suas necessidades e reinicie o servidor.

Mas lembrando que se seus métodos estão demorando muito tempo e o sistema estiver apresentado algum problema de performance, está não é a solução, e sim, usar uma ferramenta de profile como por exemplo a Visual VM para encontrar o gargalo da aplicação.

Se quiser saber mais saber a Visual VM, deixe um comentário ou aguarde o próximo post.

Até mais…

Liberando acesso do Servidor JBoss AS 7 pela rede.

Olá a todos!

Para quem já trabalhou com JBoss 5.1GA que é a versão mais estável e está migrando para a versão 7.1 deve ter se deparado com o problema em disponibilizar o acesso do sistema pela rede, bem, na versão 5.1 se usava o comando -b 0.0.0.0 tanto no eclipse como nos arquivos.conf do JBoss.

Para a versão 7.1 isso muda um pouco, se você esta desenvolvendo e realizando os testes realizando o start do servidor pelo eclipse é possível continuar configurando o host como 0.0.0.0, mas para fazer um deploy manual, vá ate o arquivo /jboss//standalone/configuration/standalone.xml e econtre as seguinte linhas:


<interfaces>
    <interface name="management">
        <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
    </interface>
    <interface name="public">
        <inet-address value="${jboss.bind.address:127.0.0.1}"/>
    </interface>
    <interface name="unsecure">
        <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>
    </interface>
</interfaces>

Para liberar o sistema pela rede, troque o endereço 17.0.0.1 por 0.0.0.0, pronto, assim o sistema estará disponível na rede.

O mesmo vale para quado você estiver usando o tipo domain, vá até /domain/configuration/domain.xml e edite as mesmas linhas.

Até mais…

Criando aplicação Java com Hibernate e PostgreSQL – Parte 3

Ola a todos!

Para iniciar está parte, primeiro é preciso ter feitos todos os passos descritos neste post.

Está é a 3ª parte do tutorial, onde vamos criar os arquivos de configuração do Hibernate e gerar as entidades usando a engenharia reversa com as tabelas já existentes no banco, essa é uma das melhores práticas, pois suas entidades vão representar fielmente seu banco de dados, tanto em colunas como nos relacionamentos.

3 – Criando projeto

O primeiro arquivo que precisamos é o persistence.xml, esse arquivo é responsável por realizar a conexão com o banco de dados, para mais informação sobre este arquivo deixe um comentário. Abaixe segue o arquivo que será usado para se conectar com o banco de dados que criamos neste post.


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
	version="1.0">
	<persistence-unit name="maindatabase" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<properties>
			<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
			<property name="hibernate.connection.username" value="postgres" />
			<property name="hibernate.connection.password" value="database" />
			<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/delivery" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />
		</properties>
	</persistence-unit>

</persistence>

O segundo arquivo de que precisamos é o arquivo.reveng.xml, este arquivo é responsável por gerenciar as SEQUENCES geradas pelo banco de dados PostgreSQL, para mais informações sobre este arquivo deixei um comentário.  Abaixe segue o arquivo que será usado para gerenciar as SEQUENCES do banco de dados que criamos neste post.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >

<hibernate-reverse-engineering>
  <table-filter match-schema="public" match-name=".*"/>
<table schema="public" name="buy">
  	<primary-key>
  		<generator class="sequence">
  			<param name="sequence">public.seq_buy</param>
  		</generator>
  	</primary-key></table>
<table schema="public" name="provider">
  	<primary-key>
  		<generator class="sequence">
  			<param name="sequence">public.seq_provider</param>
  		</generator>
  	</primary-key></table>
<table schema="public" name="delivery">
  	<primary-key>
  		<generator class="sequence">
  			<param name="sequence">public.seq_delivery</param>
  		</generator>
  	</primary-key></table>
<table schema="public" name="client">
  	<primary-key>
  		<generator class="sequence">
  			<param name="sequence">public.seq_client</param>
  		</generator>
  	</primary-key></table>
<table schema="public" name="product">
  	<primary-key>
  		<generator class="sequence">
  			<param name="sequence">public.seq_product</param>
  		</generator>
  	</primary-key></table>
<table schema="public" name="stock">
  	<primary-key>
  		<generator class="sequence">
  			<param name="sequence">public.seq_stock</param>
  		</generator>
  	</primary-key></table>
</hibernate-reverse-engineering>

Com estes dois arquivos já em mãos podemos iniciar a criação do projeto, os passos para a criação do projeto podem ser visto no vídeo abaixo.

No próximo post será disponibilizada a classe GenericDAO.java que vai ajudar você a criar seus DAO’s para consultas ao banco, como executar suas primeiras consultas e explicar como funciona a estrutura que foi gerada neste post.

Até mais…

Criando aplicação Java com Hibernate e PostgreSQL – Parte 2

Olá a todos!

Para iniciar está parte, primeiro é preciso ter feitos todos os passos descritos neste post.

Está é a 2ª parte do tutorial, onde vamos criar o banco de dados, como exemplo iremos utilizar o banco de dados utilizado para criar a aplicação Deliveries Manager que se encontra neste post.

2 – Criando banco de dados

Abaixo segue uma imagem do banco de dados que foi retirada do framework PowerArchitect que é uma excelente opção para visualizar seus banco de dados de modo gráfico e realizar a geração de script, seu maior diferencial é o suporte a vários bancos de dados inclusive o PostgreSQL que é abordado neste tutorial, mais informações sobre este framework serão divulgadas em breve em outro post.

database

database

Abaixo segue o script do banco de dados que foi gerado pelo framework descrito acima.


CREATE SEQUENCE public.seq_provider;

CREATE TABLE public.provider (
                id BIGINT NOT NULL DEFAULT nextval('public.seq_provider'),
                name VARCHAR(30),
                celluar VARCHAR(30) NOT NULL,
                phone VARCHAR(30) NOT NULL,
                cnpj VARCHAR(30) NOT NULL,
                enabled BOOLEAN DEFAULT true,
                CONSTRAINT pk_provider PRIMARY KEY (id)
);

ALTER SEQUENCE public.seq_provider OWNED BY public.provider.id;

CREATE SEQUENCE public.seq_product;

CREATE TABLE public.product (
                id BIGINT NOT NULL DEFAULT nextval('public.seq_product'),
                name VARCHAR(30),
                value REAL,
                enabled BOOLEAN DEFAULT true,
                CONSTRAINT pk_product PRIMARY KEY (id)
);

ALTER SEQUENCE public.seq_product OWNED BY public.product.id;

CREATE UNIQUE INDEX uk_product_name
 ON public.product
 ( name );

CREATE SEQUENCE public.seq_stock;

CREATE TABLE public.stock (
                id BIGINT NOT NULL DEFAULT nextval('public.seq_stock'),
                date TIMESTAMP,
                product_id BIGINT,
                quantity INTEGER,
                enabled BOOLEAN DEFAULT true,
                CONSTRAINT pk_stock PRIMARY KEY (id)
);

ALTER SEQUENCE public.seq_stock OWNED BY public.stock.id;

CREATE SEQUENCE public.seq_client;

CREATE TABLE public.client (
                id BIGINT NOT NULL DEFAULT nextval('public.seq_client'),
                name VARCHAR(30) NOT NULL,
                celluar VARCHAR(30) NOT NULL,
                phone VARCHAR(30) NOT NULL,
                city VARCHAR(30) NOT NULL,
                district VARCHAR(30) NOT NULL,
                street VARCHAR(30) NOT NULL,
                house_number INTEGER NOT NULL,
                distance REAL NOT NULL,
                enabled BOOLEAN DEFAULT true,
                CONSTRAINT pk_client PRIMARY KEY (id)
);

ALTER SEQUENCE public.seq_client OWNED BY public.client.id;

CREATE SEQUENCE public.seq_delivery;

CREATE TABLE public.delivery (
                id BIGINT NOT NULL DEFAULT nextval('public.seq_delivery'),
                product_id BIGINT,
                client_id BIGINT,
                date TIMESTAMP,
                quantity INTEGER,
                value REAL,
                status VARCHAR(30) NOT NULL,
                enabled BOOLEAN DEFAULT true,
                CONSTRAINT pk_delivery PRIMARY KEY (id)
);

ALTER SEQUENCE public.seq_delivery OWNED BY public.delivery.id;

CREATE SEQUENCE public.seq_buy;

CREATE TABLE public.buy (
                id BIGINT NOT NULL DEFAULT nextval('public.seq_buy'),
                date TIMESTAMP,
                provider_id BIGINT,
                product_id BIGINT,
                quantity INTEGER,
                value REAL,
                enabled BOOLEAN DEFAULT true,
                CONSTRAINT pk_buy PRIMARY KEY (id)
);

ALTER SEQUENCE public.seq_buy OWNED BY public.buy.id;

ALTER TABLE public.buy ADD CONSTRAINT fk_buy_provider_id
FOREIGN KEY (provider_id)
REFERENCES public.provider (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;

ALTER TABLE public.buy ADD CONSTRAINT fk_buy_product_id
FOREIGN KEY (product_id)
REFERENCES public.product (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;

ALTER TABLE public.delivery ADD CONSTRAINT fk_delivery_product_id
FOREIGN KEY (product_id)
REFERENCES public.product (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;

ALTER TABLE public.stock ADD CONSTRAINT fk_stock_product_id
FOREIGN KEY (product_id)
REFERENCES public.product (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;

ALTER TABLE public.delivery ADD CONSTRAINT fk_delivery_client_id
FOREIGN KEY (client_id)
REFERENCES public.client (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;

Abaixo um vídeo de como executar este script no banco de dados.

Pronto já temos a ambiente configurado e o banco de dados da aplicação, no próximo post será explicado como criar o projeto e configurar o Hibernate.

Até mais.