segunda-feira, 28 de novembro de 2011

Imprimir JTable Print

Para casos onde seja apenas necessário imprimir os dados de uma Jtable, sem cabecalhos nem imagens etc, pode-se utilizar o método print das jTable, definindo apenas o título para imprimir.

sexta-feira, 25 de novembro de 2011

A melhor dica de todos os tempos e um pouco de código fonte

A dica que segue é triste, mas considero uma boa dica.

NUNCA UTILIZE LETRAS MAIÚSCULAS AO DESENVOLVER COM JAVA.

Eu já perdi a conta de quantos problemas e horas passei pesquisando e pedindo ao Pai Google como resolver erros no Java, e muitos deles foi por eu ter usado uma letra maiúscula. Por exemplo, usar letra maiúscula em nome de tabela ou campo no banco de dados, volta e meia dá problema com o Hibernate.

E hoje, tentando passar os dados de uma abstractTableModel diretamente para um relatório no iReport Jasper, recebi várias erros como:

java.lang.NoSuchMethodException: Unknown property 'Data' on class


Depois de várias alteracões uma coisa me chamou a atencão, erro no campo Data, o D maiúsculo... refatorei o nome para data tanto na classe como no relatório e o erro passou pro campo seguinte... CustoMO. Eureka, descobri o problema, mais uma vez as maiúsculas. Olha outro que sofreu...

Se não ajustar no iReport  dá um erro tipo este:

net.sf.jasperreport.engine.JRException:Error retrieving field value bean: Campo



Bem, aproveitando o post, vou postar o código da AbstractTableModel que montei pra vocês darem risadas das minhas gambiarras e poderem copia-las depois quando quiserem jogar os dados da tablemodel pra um relatório jasper :)



Vejam que acabei criando uma classe interna com os mesmos campos/colunas da table model que uso nas jTable... campos em MINÚSCULO! Ai fiz uma funcão carregaDadosPrint() que busca os dados e joga pra ArrayList que vai pro relatório a ser impresso.

Tenho certeza que o código pode ser bastante melhorado visto que Java não é o meu forte, mas acredito que quem está iniciando pode aprender muitas coisas estudando ele.

Aproveita pra colocar alguns links que me ajudaram nos últimos dias:
Java sem café.!: JavaSE: CRUD em Swing
Implementando AbstractTableModel - Java Free.org
A Simple Interactive JTable Tutorial
Java Swing | extend AbstractTableModel and use it with JTable | several questions - Stack Overflow
Creating a Set | Example Depot
Não consigo buscar dado do AbstractTableModel.. pq?
Morte definitiva ao default table model
Máscara monetária - Java Free.org 
Cómo crear interfaces gráficas con Look And Feel en Java
Cotidiano em Wonderland: Look and Feel
Testando vários Look And Feels - Java Free.org 
Printing simple tabular reports with JTable - Alan's Ramblings
Marc Nuri's Happy Coding Blog » Updated: Displaying a jTable inside another jTable // JTable cellRenderer
Marc Nuri's Happy Coding Blog » Getting started with JasperReports // Printing reports from your java app (Part III)
sagara's Blog: JTable to Dynamic PDF Report using JasperReport
Getting Started | DynamicJasper
Preencher Relatórios JasperReport com Hibernate
JasperReports 4.0.1 - Hibernate Sample
Usando o JRBeanCollectionDataSource » Roberto Furutani

quarta-feira, 9 de novembro de 2011

AbstractTableModel x DefaultTableModel

Olá, estou com pouco tempo pra escrever um bom post, mas não posso deixar de recomendar a todos que parem de usar DefaultTableModel e comecem com AbstractTableModel. Seguem 3 links interessantes que vão lhe levar para muitos outros links e exemplos :), é isso ai, bom estudo.

http://www.guj.com.br/java/138916-duvida-pegar-objeto-da-jtable-resolvido

http://www.guj.com.br/java/199067-redimensionar-jtable---pra-variar--resolvido-/2#1001295

http://stackoverflow.com/questions/4303680/java-swing-extend-abstracttablemodel-and-use-it-with-jtable-several-question

quinta-feira, 13 de outubro de 2011

Engenharia Reversa no Hibernate com Netbeans

Olá!

Se você vai usar o Hibernate para desenvolver aplicativos Java, recomendo fortemente que leia este tutorial http://netbeans.org/kb/docs/java/hibernate-java-se.html, você vai aprender a utilizar alguns recursos bem legais como o HQL Query editor e gerar POJOs e arquivos de mapeamento das tabelas (models, classes) no banco através de um recurso de engenharia reversa do Hibernate.

No tutorial é para Swing apps, mas este conhecimento você vai usar em qualquer projeto que utilize Java e Hibernate.

___
Bolívar Butzke
bolivarbutzke.blogspot.com

segunda-feira, 4 de julho de 2011

Trabalhando com Web Service SOP com JAVA, Netbeans

Se você quer criar um web service, ou consumir um, e a sua IDE é o NetBeans, dê
uma olhada no link abaixo. Tem um material bom.

http://netbeans.org/kb/docs/websvc/jax-ws.html

Só não funciona com TomCat, tem que ser GlassFish o servidor. Se souber como fazer com TomCat, comente aí.

terça-feira, 14 de junho de 2011

Obter dados de um parametro do web.xml

Estive com uma dificuldade, precisava fazer upload de um arquivo mas não queria informar o caminho absoluto no servidor, infelizmente ainda não consegui fazer funcionar isso... mas, na busca por uma solucão, acabei aprendendo outra coisa legal, pra quem já programou em .NET conhece bem a tal da web.config, um arquivo XML com milhoes de configuracoes, ta um pouco menos, mas voce pode adicionar varias coisas la e obter na aplicacao, seria um lugar bom pra guardar qualquer parametro do sistema que possa se alterar em uma eventual nova instalacao ou mudanca de servidor... chega do rolo, vamos ao codigo Java com Struts, aqui o arquivo se chama web.xml e costuma estar dentro do WEB-INF, podemos adicionar variaveis (parametros de contexto) com informacoes úteis, como no meu caso queria manter o caminho absoluto até o diretório da minha aplicacao. Olha a imagem abaixo, após a configuracao do tiles  tem um context-param (linhas 32->35), ali dentro fica os dados desse parametro (nome e valor) que eu adicionei.


Minha dificuldade foi conseguir obter esse valor na app, após várias tentativas e erros deu certo, muito simples por sinal:

ServletActionContext.getServletContext().getInitParameter("caminhoFisicoImgProdutos");


Bom, na imagem acima tem além da parte que obtém caminhoAbsoluto o upload do arquivo igual tutorial do helton, e tem tbm a atualizacao dos dados no banco, onde eh alterado o caminho (nome arquivo) da imagem...

Isso ai galera, até +.

segunda-feira, 6 de junho de 2011

Struts2 - Upload de arquivos, gravando no sistema de arquivos

Para fazer upload usando Struts2, em Java para o sistema de arquivos (do servidor) é relativamente simples. Segue exemplo básico abaixo com uma pequena explicação.

No NetBeans, crie um novo projeto (Java Web) , chameio- de “UploadFS”. Usaremos Tomcat como de costume, mas esse aplicativo não tem banco de dados, portanto, na tela dos frameworks, marque apenas o Struts2, e não o Hibernate, também não precisa criar a página de exemplo.

Bom, projeto criado, vamos modificar o index.jsp e incluir o formulário de upload. Código fonte abaixo.



Perceba que informamos no enctype o valor “multipart/form-data”. Se não, não faria o upload. O action do form, está para ação “doUpload”, então vamos implementar esse método. Criamos o arquivo “Upload.java”.


Bom, como vemos no código acima, apenas implementamos os gettes e os setters de um atributo do tipo File, para fazer upload, o Struts pede que se façam os outros dois atributos, conforme o nome do filefield que colocamos no jsp, no caso "arquivo"

Abaixo a implementação do upload em sí, carregando o arquivo para /dados/temp/upload.



Bom, próximo passo é configurar o struts, apontando a ação "doUpload" para a classe Upload no respectivo método.






Rodando a aplicação (diretório de upload está vazio)...


Escolhemos uma... e vua-la!



Download do código fonte do exemplo.

O Próximo, upando e cadastrando no BD.

quarta-feira, 4 de maio de 2011

StrutsTool: Desenvolvendo Aplicações em Struts sem Sofrimento

Quem acompanhou os posts anteriores pôde ter uma idéia de como desenvolver aplicações em Java com a framework Struts 2. Um dos aspectos que mais chama a atenção é a quantidade de passos necessários para criar aplicações relativamente simples. Quem já usou Struts sabe como é custoso criar um simples CRUD.

Isso trás grande frustração para quem desenvolve aplicações web, inclusive eu. Isso se dá principalmente pois o Struts necessita de extensa configuração. Cada action que você cria precisa ser mapeada em um arquivo xml, se você usar Tiles o negócio é pior ainda, é xml para todo lado.

O pior é que isso acontece em outras frameworks Java, como o Spring. Porém esta adotou o uso de anotações ao invés de xml, mas não deixa de ser configuração. Fato é que com as anotações você não precisa criar tantos arquivos, mas ainda assim precisa escrever muitas linhas para fazer a coisa funcionar.

Com uma rápida busca na internet é possível encontrar diversas discussões sobre quando utilizar Java para web ou qual é a melhor dentre as frameworks para Java (a Wikipedia lista 35 frameworks para Java). Kelby Zorgdrager faz em um artigo uma comparação entre frameworks Java, com tabelas de pontuação para os pontos mais relevantes de uma framework. Para encurtar a história, de modo geral (não conclusivo) Struts e JSF tem as melhores notas. Entretanto, frameworks como Stripes e Tapestry tem melhores notas quando falamos em RAD, isso porque ambas se utilizam de convenção ao invés de configuração.

Nessas horas muitos diriam para trocar de linguagem, mas isso depende muito das necessidades e recursos disponíveis para o projeto. Não vou entrar nesta discussão, a internet já está cheia delas, tendo destaque as com títulos como: “linguagem A vs linguagem B”.

Porque Struts?

Não vou dizer que adoro esta framework, pois estaria mentindo. Digamos que a escolha desta framework foi mais uma questão de necessidade (obrigação), do contrário teria escolhido outra framework, ou outra linguagem, como Ruby (comparação interessante entre as linguagens aqui).

Bom, se eu tenho que utilizar Struts para desenvolver uma aplicação, ao menos posso usar meus meios para reduzir o sofrimento durante a jornada. E é exatamente o que estou fazendo, construindo uma aplicação de linha de comando inspirada em Rails para Struts 2.

StrutsTool

Pois bem, esta aplicação se chama StrutsTool (não estava muito inspirado, então me baseei no Zend_Tool mesmo) e está hospedada no Google Code, no seguinte endereço: http://code.google.com/p/strutstool/.

A idéia de fazer tal ferramenta surgiu, obviamente, de uma necessidade, que era não me arrebentar para programar funcionalidades simples. E por simples, me refiro ao CRUD. Além disso, muitos arquivos precisam ser criados e modificados para se obter uma aplicação funcional em Struts.

Quer uma amostra prática disto? Justin Gehtland reescreveu uma aplicação Java em Ruby on Rails e obteve os seguintes resultados (fonte):

Linhas de Código:
Rails: 1164
Java: 3293

Número de Classes:
Rails: 55
Java: 62

Número de Métodos:
Rails: 126
Java: 549

Linhas de Configuração:
Rails: 113
Java: 1161

Não é para menos. Quer outro exemplo, então dê uma olhada neste projeto que hospedei há algum tempo no Github, é apenas um exemplo simples de CRUD utilizando Struts 2, Tiles, Hibernate e Hibernate Validator. Em poucas palavras : muito código para pouca funcionalidade.

Para deixar claro o quanto de trabalho um CRUD pode dar, você precisa:

  1. criar os arquivos .jsp

  2. criar um controlador

  3. mapeá-lo no arquivo struts.xml indicando os arquivos .jsp que irão ser exibidos

  4. se usar tiles, definir os arquivos .jsp no tiles.xml e referenciá-los no struts.xml

  5. criar a classe POJO

  6. adicionar validadores de dados ao POJO

  7. mapear a classe POJO para o Hibernate, podendo ser com anotações ou xml

  8. criar classe de acesso a dados

  9. criar classe de serviço

  10. você pode ainda querer criar um arquivo properties para armazenar as mensagens que serão usadas pelo controlador

Foi baseado nesta aplicação de exemplo que eu comecei a criar o que viria a ser uma aplicação de base para o desenvolvimento de minhas aplicações em Struts. Se trata de um projeto com as configurações básicas para funcionar e em cima dele eu poderia adicionar as funcionalidades específicas de minhas aplicações.

De forma simples, esta aplicação (StrutsTool) cria um projeto base e conforme você for criando novas funcionalidades (models, controladores, views, …) a ferramenta irá adicioná-las a este projeto e executar toda a configuração necessária. Ou seja, é um gerador para Struts.

Funcionalidades

Esta ferramenta provê, por enquanto, poucas funcionalidades, porém extremamente úteis. Mas antes de falar destas funcionalidades gostaria de listar as frameworks/APIs suportadas pelos projetos criados com esta ferramenta. São elas:

  • Struts 2.2.1.1

  • Struts2 jQuery Plugin 2.5.3

  • Hibernate 3.6.3

  • Hibernate Validator 4.1.0

  • Hibernate Search 3.4.0

  • Tiles 2.2.2

  • HTML Compressor 1.1

  • Closure Compiler

  • wro4j 1.3.6

  • YUICompressor 2.4.2

  • Spring Framework 3.1.0

  • displaytag 1.2

Agora sim vamos as funcionalidades, basicamente elas são quatro: criação de projeto, scaffolding, criação de controlador e criação de modelo. Nos próximos itens estarei fazendo uma descrição mais detalhada de cada uma destas funções.

Criação de Projeto

A criação de um projeto consiste apenas em descomprimir o arquivo que contém o projeto de base para aplicações. Neste projeto não existem controladores, views ou modelos. Apenas a estrutura básica de um projeto para a IDE NetBeans, além de uma série de classes utilizadas como base para a geração de aplicações e alguns arquivos de configuração para as frameworks/APIs.

Scaffolding

Talvez uma das funcionalidades mais interessantes da ferramenta, apesar de ser pouco flexível. Assim como em Rails, é necessário apenas informar o nome da classe e os seus atributos e tipos correspondentes. Adicionalmente, a ferramenta permite adicionar o tamanho das variáveis e em caso de relacionamentos com outras classes, indicá-los.

Criação de Controlador e Criação de Modelo

A criação de controlador e model é o que o nome diz, não existe mistério. Exceto que a criação de controladores com suas actions inclui a criação das views. Em uma versão futura adicionarei a opção de não criar uma view, o que algumas vezes pode ser conveniente. Quanto a criação de modelo, ele gera a entidade com validações, mapeamento, classe de acesso a dados e de serviços.

Instalação do StrutsTool

O StrutsTool foi desenvolvido em Java, para fazer o download dele basta ir na seção de downloads do projeto e fazer o download dos arquivos StrutsTool-x.x.tar.gz (baixe sempre a última versão) e o arquivo lib.zip.

Descompacte o primeiro arquivo na pasta que achar mais conveniente. Dentro desta pasta haverá outra pasta chamada resources, coloque o arquivo lib.zip dentro dela. Para executar a ferramenta utilize o arquivo strutstool (Linux) ou strutstool.bat (Windows). Antes de executá-lo, abra-o e edite as variáveis nele declaradas, sendo elas: INSTALL_PATH (caminho da instalação do StrutsTool) e JAVA_BIN (caminho da pasta bin do Java (JRE ou JDK) ).

Para executar o comando sem precisar estar na pasta da ferramenta você precisa, no Linux, editar o arquivo .bashrc e adicionar as seguintes linhas:

PATH=$PATH:/caminho/completo/para/strutstool

export PATH

No windows basta adicionar a pasta do StrutsTool na variável de ambiente path. Feito isto você pode poderá acessar o aplicativo executando: strutstool

Criando um Aplicativo

Feita a instalação, é hora de começar a utilizar a ferramenta para criar um aplicativo de exemplo, para demonstrar o que a ferramenta é capaz de fazer. Nosso aplicativo vai ser algo simples, com duas tabelas, uma de produtos e outra de marcas.

Neste exemplo estarei utilizando o banco de dados PostgreSQL, mas qualquer outro banco suportado pelo Hibernate irá funcionar (contanto que sejam feitas as modificações no mapeamento, se necessário). O SQL para criar as tabelas é este:

CREATE TABLE produto(

id Serial NOT NULL,

nome Character varying(100) NOT NULL,

marca Integer NOT NULL

) WITH (OIDS=FALSE);

ALTER TABLE produto ADD CONSTRAINT pk_produto PRIMARY KEY (id);

CREATE TABLE marca(

id Serial NOT NULL,

nome Character varying(100) NOT NULL

) WITH (OIDS=FALSE);

ALTER TABLE marca ADD CONSTRAINT pk_marca PRIMARY KEY (id);

ALTER TABLE produto ADD CONSTRAINT fk_marca_produto FOREIGN KEY (marca) REFERENCES marca (id) ON DELETE NO ACTION ON UPDATE NO ACTION;

Criado o banco de dados, iremos agora criar um novo projeto com o StrutsTool. O comando para realizar esta operação é simples:

strutstool new project loja com.app.web

Este comando cria o projeto base dentro da pasta loja/. Agora vamos criar o que realmente interessa nesta aplicação através do scaffolding. Primeiro vamos criar os providers (view, modelo e controlador) para a classe Produto, assim:

strutstool scaffold Produto nome:string:100 marca:Marca

Após executar o comando deverá aparecer na tela todos os arquivos e pastas criados e/ou modificados. Vale ressaltar que o método scaffold parte da premissa de que o identificador da tabela é chamado id, sendo este um valor inteiro e auto-incremento (ou que use uma sequence, como neste caso (consulte a documentação do Hibernate)).

Outro aspecto importante é o das convenções adotadas pela ferramenta. No caso do Produto, é assumido (por padrão, você pode alterar) que o nome da tabela é produto e ela tem, além da chave primária id, um campo chamado nome de tamanho 100. Além disso, é criado um controlador chamado ProdutoController com as actions: index, edit, add e delete.

E nas views (pasta web/WEB-INF/) é criada a pasta produto com as páginas: index.jsp, edit.jsp e add.jsp (delete utiliza jQuery). A url para acesso a action index, por exemplo, ficaria assim: http://localhost:8084/loja/produto/index.action.

Estas são convenções básicas adotadas em várias frameworks conhecidas, exceto o Struts (além de outros frameworks Java), mas que através desta ferramenta poupam o desenvolvedor de configurar mais do que o necessário.

Agora vamos gerar os providers da classe Marca. Para tanto:

strutstool scaffold Marca nome:string:100 produtos:set:Produto

Aqui adicionamos mais um atributo a classe, produtos:set:Produto, que corresponde ao relacionamento um para muitos (one-to-many) com a classe de Produto (uma marca tem vários produtos). O set do atributo corresponde ao tipo de Collection do Java java.util.Set. Este é o único tipo de coleção suportado pela ferramenta (não consegui fazer List funcionar com o Hibernate).

Por padrão, a ferramenta gera relacionamentos em duas direções, portanto a classe Produto poderá acessar a marca a qual pertence, bem como uma marca poderá acessar todos os seus produtos. Para quem notou, a ferramenta não checa os tipos de dados utilizados nos parâmetros. A bem da verdade, ela possui uma lista com os tipos básicos suportados e quando um tipo é desconhecido ela trata-o como um novo tipo, portanto cuidado ao informar os tipos de dados.

Outra funcionalidade que preferi desativar era a checagem das classes existentes. Neste exemplo a classe Produto referencia a classe Marca, sendo que esta última nem sequer existe ainda. Porém, me pareceu mais prático deixar a cargo do programador cuidar destes detalhes.

Por equanto esta ferramenta suporta apenas relacionamentos um para muitos (1:n) e muitos para um (n:1). Relacionamentos muitos para muitos (n:m) podem ser feitos com dois relacionamentos um para muitos.

Agora que a aplicação foi gerada, é hora de abrí-la com o NetBeans e fazer algumas modificações. Basta ir em “Abrir Projeto...” e selecionar a pasta loja. É provável que o NetBeans exiba um erro sobre o arquivo build-impl.xml, isto ocorre devido a uma modificação que é feita durante a criação do projeto. Basta clicar em Regenerar e prosseguir normalmente.

Com o projeto aberto precisamos fazer algumas coisas. Primeiro, adicionar o driver do banco de dados utilizado às bibliotecas do projeto. Depois disso, é preciso abrir o arquivo hibernate.cfg.xml e modificar as configurações do banco de dados com o qual o Hibernate irá se comunicar.

Ainda no arquivo de configurações do Hibernate, é preciso modificar o valor da propriedade com nome hibernate.search.default.indexBase. O valor desta propriedade é o caminho absoluto para a pasta onde o Lucene irá criar os índices para as buscas. Você deve criar a pasta (dar as permissões para escrita na pasta) e informar na propriedade o caminho completo para ela, no meu arquivo a propriedade ficou assim:

/home/maycon/lucene/indexes

Seguindo todos estes passos e com o banco de dados tal qual o deste exemplo, basta executar a aplicação e você terá criado um pequeno aplicativo web com Struts sem muito sofrimento e com pouca configuração.

Alguns Ajustes

Para aparar um pouco as arestas deste exemplo vou sugerir algumas modificações no código, especificamente na parte visual. A primeira diz respeito ao campo autocomplete que é criado no formulário de Produto e referencia Marca. Abra o arquivo form.jsp na pasta web/WEB-INF/produto/ e na tag troque o valor do atributo listValue de id para nome. Se você adicionou alguma marca poderá ver a lista de marcas, e a medida que for digitando as marcas irão sendo filtradas.

Talvez vocês tenham notado que na listagem de produtos, na coluna marca, ao invés de imprimir o nome da Marca está imprimindo algo como: com.app.web.model.entity.Marca@... Para resolver isto basta abrir a entidade Marca e sobreescrever o método toString, assim:

@Override

public String toString() {

return nome;

}

A segunda modificação é apenas para dar um exemplo de como se criam links para actions. Vou colocar os links na página inicial. Para fazer isso abra o arquivo redirect.jsp na pasta web/WEB-INF/. Substitua o conteúdo do arquivo por isto:


Acho que não há necessidade de maiores explicações sobre o código acima, para maiores detalhes existe a documentação do Struts 2, mais especificamente a referência das tags dele. Ainda sobre o arquivo redirect.jsp, se você precisar exibir como página inicial uma action, usê-o da seguinte forma:

Assim você estará redirecionando o usuário para, neste exemplo, a action index do controlador de login.

Lucene Search

O Lucene é uma engine de busca para textos muito poderosa, escrita em Java. Como foi colocado ateriormente, é preciso informar uma pasta onde o Lucene irá criar os índices para as buscas. Estes índices são criados automaticamente quando dados são inseridos, modificados ou removidos. Entretanto, caso você já possua dados no seu banco, terá de executar um comando uma vez na aplicação para criar o índice inicial. Para fazer isso com a tabela de marcas, por exemplo, você precisaria executar o seguinte código:

new MarcaRepositoryHibernate().createInitialLuceneIndex();

Pronto, índice criado, já é possível remover o código da aplicação. Espero futuramente inserir esta funcionalidade no StrutsTool.

Para finalizar

Acredito que até o fim deste semestre estarei empenhado no desenvolvimento desta ferramenta, adicionando novas funcionalidades (testes unitários com JUnit e JMock, por exemplo) e, é claro, corrigindo eventuais (provavéis) bugs. Não sei se esta ferramenta terá grande utilidade para outras pessoas, estou desenvolvendo ela de acordo com minhas necessidades.

Espero que a ferramenta tenha alguma utilidade para quem esteja lendo isto. E para quem vai utilizá-la no desenvolvimento de aplicações recomendo logo abaixo alguns sites de referência para consulta, até porque a existência de um gerador não significa que você não deva saber como as coisas funcionam por baixo.

Links Recomendados

terça-feira, 3 de maio de 2011

Deleção/Delete/Exclusão de dados com Struts2 e Hibernate em Netbeans

Continuando o projeto, agora vamos implementar o delete. Basicamente vamos colocar um link de delete na view da listagem, quando clicar, chama uma action que apaga e volta para a lista.


Modificando a view
Na view (arquivo jsp), vamos adicionar um link, chamando a action, com um parâmetro. Adicionamos mais uma coluna na tabela. (clique na figura para ampliar)

Estamos passando o parâmetro id, por isso, depois lá na action teremos que criar um atributo id e implementar os getters e os setters.


Modificando a DAO
Na DAO, temos que implementar o método delete. Para isso precisamos importar a org.hibernate.Transaction, já que o hibernate por baixo vai rodar um delete from ...



Modificando a action
Preste atenção na linha 8, declaramos o atributo id, igual passamos no parâmetro lá na view. Implementamos os getters e os setters para o id e também o método que efetivamente responde a ação do usuário e chama a DAO no método de exclusão.

 

Ajustando os mapeamentos
No arquivo struts.xml temos que mapear que quando chamarmos na URL "ListTodolistDelete" deve chamar o método apropriado na action. Quando isso for processado deve redirecionar para "ListTodolist", é isso que faz o type="redirect" na linha 14. (clique na figura para ampliar)




Rodando a aplicação
Salve tudo, "clean and build" e depois "run". Delete funcionando.




No próximo faremos o cadastro.
Saudações!

segunda-feira, 2 de maio de 2011

Listagem de dados com Struts2 e Hibernate em Netbeans

Olá, Inicia-se hoje uma série de tutoriais (começando por esse) de como fazer o elementar (CRUD) usando Struts2 com Hibernate em uma aplicação web. Usaremos como IDE o Netbeans com o plugin do Struts2. Para acompanhar esse tutorial, é recomendado que tenha lido o post anterior introdutório ao assunto.

Criando o banco de dados
No exemplo usamos PostgreSQL. A estrutura do banco de dados é a seguinte.
Banco: todolist
CREATE TABLE todolist
(
   id serial, 
   descricao character varying(200), 
   feito character(1), 
   CONSTRAINT pk_todolist PRIMARY KEY (id)
) 
WITH (
  OIDS = FALSE
)
;

insert into todolist (descricao,feito) values ('Fazer o pos no foojava.blogspo.com','S');
insert into todolist (descricao,feito) values ('Terminar a leitura do livro the long tail','N');
insert into todolist (descricao,feito) values ('Fazer artigo da prática de e-commerce','N');
insert into todolist (descricao,feito) values ('Terminar os layouts do sistema da COTRIMAIO','N');
insert into todolist (descricao,feito) values ('Estudar para prova de adm mercadológica','N');
insert into todolist (descricao,feito) values ('Estudar para prova de Redes e sist. distribuídos','N');




Criando o projeto
Na nossa IDE, criamos um projeto web, vou chamar de todolist.

Vamos lá! file > New project.

 Chamei de todolist, salvando no meu home, diretório padrão.

Agora, escolha o Apache Tomcat (se aparecer mais algum na lista). O resto dessa tela aceite as sugestões da IDE.

Aqui, você marca o Struts2, e desmarca para ele criar o arquivo de exemplo do struts2. Nesta mesma figura tem mais um item para marcar, seguimos abaixo.

Marque o Hibernate, mas não dê finish ainda, vamos aproveitar para fazer já a conexão  com o banco de dados. No combo destacado abaixo, crie uma nova conexão.

Aqui escolhi conectar com PostgreSQL, informo usuário, senha, banco ... Quando dou ok, devo selecionar qual schema (próxima tela), se as informações dessa tela conectaram no banco.

 Escolha o schema public. Agora sim, ok.

E Finish!

A essa altura o NetBeans incluiu as bibliotecas necessárias, fez uma configuração básica já do struts, hibernate o do web.xml (que define o projeto web).

Abaixo você pode ver a web.xml, que define quem é a página inicial quando esse projeto for rodado.



Definindo a Model

Projeto criado, hora de fazer a classe que fará o mapeamento do banco de dados. Essa classe será usada pelo hibernate, portanto, depois você terá que adicionar as anotations.

Crie um novo pacote, chame-o de model.




Dentro da model, clique com o direito e crie um novo "HibernateUtil", mudei apenas  o nome do arquivo em relação ao que a IDE me sugeriu.

Na tela anterior a IDE vai gerar um arquivo (HibernateUtil.java), ele está certo, não tem que mudar nada.

Agora dentro do pacote model, você precisa fazer a classe que mapeia o seu banco. Então, dentro da model, crie uma nova classe java. O nome dela é o nome da tabela no banco que essa classe vai representar, apenas com o primeiro caracter em maiúsculo.

Na tela abaixo, criei os atributos (linhas 13, 14 e 15), cliquei com o direito em "refactory" e depois em "Encapsulate fields", marquei que ele deveria gerar os geters e os seters de todos os atributos e sem comentários. Pronto! Gerou o código que você vê abaixo.

Bom, agora nessa mesma classe, temos que identificar para o Hibernate que isso representa uma tabela.  Então adicione as anotações das linhas 18, 19, 21 e 22.

Quando fizer isso vai a IDE vai ficar te apontando warnings, ctrl+enter em cima do warning (em cima do @Id por exemplo, @table) e faça os imports, todos do pacote javax. Não pegue os do hibernate.

Veja o código final da classe model na figura seguinte.



Criando a DAO (Data Access Object)
O nosso objeto de acesso a dados, nada mais é do aque algo que usa a model, e em cima disso cria as SQL's que deverão ser rodadas no banco para a aplicação trazer os dados/ fazer as ações que precisa.

Crie um novo pacote, chame-o de dao.

 Dentro do dao, crie uma classe chamada TodolistDAO.
 

Como esse exemplo é só uma listagem, não precisamos dos métodos para inserir, deletar, update, buscar dados de só um registro (para trazer para edição), então implementamos apenas o médoto de listagem de dados.

O que temos no código abaixo. Bom primeio criamos um atributo chamado session, essa session na verdade representa a conexão com o BD (linha 19).

Então, no construtor da classe (linhas 21, 22 e 23) dizemos que a session manda abrir uma sessão (conexão) que quem define é o HibernateUtils que criamos antes.

E depois, nas linhas 24 em diante, implementamos o método que retorna uma lista de dados. Veja que a gente não escreve SQL nenhuma, o hibernate faz isso.

* Os imports dessa classe sim, são do hibernate (org.hibernate) e não do javax.

Nos próximos post's mudaremos essa classe da dao para implementar as demais operaçãos.



Implementando a Action (controller)
A action não é bem um controller, mas ela tem ligação direta (da a resposta) para uma ação do usuário (que mais tarde será mapeada no struts.xml), então dava para dizer que o struts.xml + a action é o que a gente normalmente implementa em um controller.

Crie um pacote chamado action. E dentro dele a classe seguinte:


Aqui da mesma forma, criei o atributo na linha 17, depois deu refactor > encapsulate fields, e então implementei o código das linhas 27-30.

Explicando, essa propriedade é o valor que vai ser passado para view depois, portanto lá (na view) haverá um objeto chamado "todolist", porque assim o fizemos na linha 17 deste arquivo.

Aqui precisamos dar import na classe correspondente da dao e do model.

Perceba que o que você vai pagar na view é o que é setado (assessor set), no caso na minha linha 28, onde ele recebe a execução do método que implementamos na dao antes.

Mas e o get (assessor get)? Faça-o! O struts precisa disso.

O return de "SUCESSO" será usado depois no mapeamento, quando esse método retornar "SUCESSO" deve fazer o que... mais adiante. Calma aí.

Criando o JSP (view)

O JSP é a nossa view, quanto menos processamento, código, regra de negócio rodar aqui melhor!

Lembra que antes no web.xml estava definido que o index.jsp era a página padrão da nossa aplicação. Vamos modificá-lo, fazer um link de acesso a tela/ação que traz a listagem. Segue (mudanças destacadas)


Crie uma nova página jsp, essa será usada para printar as dados retornados pelo método da action. Chamei de todolist-list. O final (-list) é porque depois vai haver um -ins, -edit ...


Logo no início, adicione o que eu tenho na linha 6.
Depois, na 18 a 33, temos uma tabela para listar os dados, as primeiras linhas são o cabeçalho, depois iteramos o objeto todolist (linha 25) e mostramos os campos (assim como está definido no model). E é isso.



Ajustando os mapeamentos

Bom, vamos ajustar algumas coisas no hibernate.xml para ajudarmos a debugar se for preciso, e temos que mapear aqui a model.

Adicione os itens indicados.


 Clique em xml (antes estava em design) e adicione o mapeamento da classe onde está a definição da tabela.


No struts.xml, temos dizer quem responde pela aquela ação que colocamos lá no href do link no index.jsp. Assim definimos que tal ação, quando invocada chama tal classe, em tal método.

Bem no fim, adicione o que eu tenho na linha 14, isso faz as mensagens de erro do java serem mais amigáveis. Coloque para false antes de publicar a aplicação.

Em cima do projeto (botão auxliliar) clique em "clean and build" e depois em "run".


Rodando a aplicação

Quando você da "run" no projeto, o NetBeans da deploy automático, exceto das coisas da camada de persistência, portanto sempre que mexer em alguma coisa do hibernate, de "clean and build" antes do "run"

Executando, teremos algo parecido com isso:

 Clicando no link, que chama a ação, a action processa, devolve os dados e passa para view. E está aí!
Achou muita tralha para pouca coisa? Eu também. Mas pior sem frameworks. Deve ser por isso que a lenda diz que pagam bem para programador java.

Nos próximos, exclusão, cadastro, e edição.

Com chave estrangeira? Com chave estrangeira? Acompanhe o blog... quem sabe sai alguma coisa.

* Daqui um tempo (um mês por aí) vai começar uma série de posts de programação para Android, usando a SDK deles, com Java!

Foo!

sexta-feira, 29 de abril de 2011

Olá Mundo com Struts2 e NetBeans

Olá galerinha!!

Vamos pra mais um Hello World, agora com o Struts2. Pra comecar crie um novo projeto no NetBeans (estou usando no Linux, aqui no Foojava tem um post que ensina instalar tudo certinho), segue -> JavaWeb -> Aplicacao Web, de o nome de HelloStruts, estou a utilizar servidor Tomcat 6.0.26 e Java EE 5, no passo 4 selecione o framework Struts2 e desmarque a opcao de Criar pagina de exemplo, caso contrário o hello world já vem pronto de exemplo, sacanagem!

Segue imagens dessa primeira parte pra ajudar vocês que ficaram com alguma dúvida nessa primeira parte.




Bom, projeto criado, vamos editar o arquivo index.jsp que foi criado junto com o projeto, este arquivo está marcado para ser sua página inicial no arquivo web.xml. Dentro do index coloque o seguinte código:

<%-- 
    Document   : index
    Created on : 28/04/2011, 20:55:03
    Author     : bolivar
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<%-- Adicione essa taglib para usar as tags do Struts --%>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <s:form action="Hello">
            <s:textfield name="nomeUsuario" label="Seu nome" />
            <s:submit />
        </s:form>
    </body>
</html>

Perceba que no início da página foi adicionado uma linha de código que inclui as tags especiais do Struts, para usar essas tags devemos adicionar o prefixo s: nas tags, é interessante dar uma olhada nessas tags, o NetBeans tem um autoComplete que msotra todas as tags possíveis de serem utilizadas. Essas tags serão substituidas por tags HTML normais quando o projeto for executado, em tempo de execução/compilaçao, não tenho bem certeza.

Crie agora mais duas páginas JSP, chame uma de sucesso.jsp e outra de erro.jsp.


 Na página de erro coloque apenas HTML normal com uma mesangem de erro e link para volar ao início.
<%-- 
    Document   : erro
    Created on : 28/04/2011, 21:08:18
    Author     : bolivar
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Primeiro Hello Struts</title>
    </head>
    <body>
        <p>
            Erro: Campo nome nao pode ser vazio, informe seu nome!<br><br>
            <a href="index.jsp">clique aqui pra voltar</a>
        </p>
    </body>
</html>

Na página de sucesso vamos utilizar novamente a taglib do Struts2, para exibir uma mensagem de Ola.
<%-- 
    Document   : sucesso
    Created on : 28/04/2011, 21:06:57
    Author     : bolivar
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Primeiro Hello Struts</title>
    </head>
    <body>
        <h1><s:property value="mensagem" /></h1>
    </body>
</html>

Bom, até agora temos duas variáveis/propriedades para trabalhar, uma está na index.jsp que é o nomeUsuario e outra na página de sucesso que é a mensagem. Para manipularmos estes campos vamos criar uma classe Java que será a nossa Action, crie uma classe java dentro de um novo pacote chamado acoes. De o nome para a nova classe de HelloAction.



Criado a classe HelloAction, dentro de um pacote acoes, coloque o seguinte código.

package acoes;

/**
 * @author bolivar
 */
public class HelloAction {

    private String Mensagem;
    private String nomeUsuario;

    public String execute() {
        if (getNomeUsuario().length() > 0)
        {
            setMensagem("Ola " + getNomeUsuario());
            return "SUCESSO";
        } else
        {
            return "ERRO";
        }
    }

    /**
     * @return the Mensagem
     */
    public String getMensagem() {
        return Mensagem;
    }

    /**
     * @param Mensagem the Mensagem to set
     */
    public void setMensagem(String Mensagem) {
        this.Mensagem = Mensagem;
    }

    /**
     * @return the nomeUsuario
     */
    public String getNomeUsuario() {
        return nomeUsuario;
    }

    /**
     * @param nomeUsuario the nomeUsuario to set
     */
    public void setNomeUsuario(String nomeUsuario) {
        this.nomeUsuario = nomeUsuario;
    }
    
}

Esta classe estamos criando duas variáveis String que correspondem aos nossos elementos nas JSP, nomeUsuario e mensagem, implementamos os métodos GET e SET para definir valores e recuperar os valores dessas propriedades e criamos uma função chamada execute(), que é o método padrão das actions dentro do Struts.

Dentro desse método execute() nós verificamos se foi preenchido o campo nomeUsuario, em caso TRUE nós setamos a propriedade mensagem com o valor 'Olá ' e concatenamos com nome informado pelo usuário que está na propriedade nomeUsuario, tudo certo, retorna 'SUCESSO', este retorno é muito importante, não é necessário ter o nome 'sucesso', mas precisa existir para mapearmos dentro do struts depois.

No caso do usuário não ter digitado o seu nome, o método vai retornar 'ERRO'.

Muito bem, vamos para nossa parte final do Hello World, é impressão minha ou fazer um hello em Struts é super complicado? hehe Seguindo, agora só nos falta relacionar tudo isso dentro do arquivo de configuração struts.xml, o código abaixo simples e comentadinho.

<struts>
    <!-- Configuration for the default package. -->
    <package name="default" extends="struts-default">
        <!-- Configura as actions, o name é o que esta sendo chamada no form da index.jsp,
 class é local da action a ser executada e adicionei também o method execute, 
isso não é necessário quando o método tem este nome, mas se tivesse outro nome como remover, listar... ai seria necessário -->
        <action name="Hello" class="acoes.HelloAction" method="execute">
            <!-- Configura os resultados da action, em caso da funçao retornar SUCESSO 
vai ir para pagina JSP sucesso, caso de ERRO vai para erro.jsp -->
            <result name="SUCESSO">/sucesso.jsp</result>
            <result name="ERRO">/erro.jsp</result>
        </action>

    </package>
</struts>

Bom pessoal, basicamente é isso ai, para ver o Hello com Struts funcionando basta executar o projeto agora e correr pro abraço. A estrutura do projeto ficou igual a imagem abaixo.


Até mais!