Escolar Documentos
Profissional Documentos
Cultura Documentos
CA PTULO 11
Spring MVC
"Um homem pinta com seu crebro e no com suas mos." Michelangelo Nesse captulo, voc aprender: Porque utilizar frameworks; Como funciona o framework Spring MVC; As diferentes formas de se trabalhar com o Spring MVC.
09/10/13
objeto do tipo C o n t a t oj devidamente populado com os dados que vieram na requisio e nosso trabalho seria apenas, por exemplo invocar o C o n t a t o D a o passando o C o n t a t opara ser adicionado. O grande problema que estamos atrelados a API de S e r v l e t sque ainda exige muito trabalho braal para desenvolvermos nossa lgica. E, justamente para resolver esse problema, comearam a surgir os frameworks MVC, com o objetivo de diminuir o impacto da API de S e r v l e t sem nosso trabalho e fazer com que passemos a nos preocupar exclusivamente com a lgica de negcios, que o cdigo que possui valor para a aplicao.
09/10/13
Um dos frameworks mais famosos na mercado o Spring MVC. Spring um framework que inicialmente no foi criado para o desenvolvimento web. Na essncia o Spring um container leve que visa fornecer servios para sua aplicao como por exemplo o gerenciamento de objetos ou transao. Mas com o tempo a comunidade Spring entendeu que o Struts era ultrapassado e comeou criar um framework MVC prprio. O Spring MVC um framework moderno que usa os recursos atuais da linguagem alm de usar todo poder do container Spring. Nesse cpitulo veremos as funcionalidades desse framework poderoso.
Struts 1 Embora bastante antigo, o Struts 1 ainda usado em muitas empresas. Os conceitos e fundamentos so muito parecidos entre as verses, mas a verso antiga mais trabalhosa e possui formas particulares de uso.
Struts 2 Apesar do nome famoso, o Struts 2 nunca foi to utilizado quanto o Struts 1. Enquanto o Struts 1 era pioneiro na poca e se tornou o padro no desenvolvimento web Java, o Struts 2 era uma escolha entre vrios frameworks MVC que ofereciam as mesmas facilidades.
Agora a melhor hora de aprender algo novo Se voc gosta de estudar essa apostila aberta da Caelum, certamente vai gostar dos novos cursos online que lanamos na plataforma Alura. Voc estuda a qualquer momento com a qualidade Caelum. Conhea a assinatura semestral.
09/10/13
adicionarmos em nossa aplicao. Spring MVC vem junto com as bibliotecas do framework Spring que podemos encontrar no site http://springsource.org. L, possvel encontrar diversas documentaes e tutoriais, alm dos JARs do projeto. Uma vez que adicionamos os JARs do Spring MVC em nosso projeto dentro do diretrio W E B I N F / l i b , precisamos declarar um Servlet, que far o papel de Front Controller da nossa aplicao, recebendo as requisies e as enviando s lgicas corretas. Para declararmos o Filtro do Spring MVC, basta adicionarmos no w e b . x m l da nossa aplicao:
< s e r v l e t > < s e r v l e t n a m e > S p r i n gM V CD i s p a t c h e rS e r v l e t < / s e r v l e t n a m e > < s e r v l e t c l a s s > o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . D i s p a t c h e r S e r v l e t < / s e r v l e t c l a s s > < i n i t p a r a m > < p a r a m n a m e > c o n t e x t C o n f i g L o c a t i o n < / p a r a m n a m e > < p a r a m v a l u e > / W E B I N F / s p r i n g c o n t e x t . x m l < / p a r a m v a l u e > < / i n i t p a r a m > < l o a d o n s t a r t u p > 1 < / l o a d o n s t a r t u p > < / s e r v l e t > < s e r v l e t m a p p i n g > < s e r v l e t n a m e > S p r i n gM V CD i s p a t c h e rS e r v l e t < / s e r v l e t n a m e > < u r l p a t t e r n > / < / u r l p a t t e r n > < / s e r v l e t m a p p i n g >
Repare que uma configurao normal de Servlet, com s e r v l e t c l a s se u r l p a t t e r n , como as que fizemos antes. Tem apenas um elemento novo, o i n i t p a r a m . Este parmetro uma configurao que pode ser passada para o servlet pelo w e b . x m l . Aqui definimos o nome do arquivo de configurao do framework Spring, o s p r i n g c o n t e x t . x m l . Quando o Servlet carregado, ele vai procurar esse s p r i n g c o n t e x t . x m ldentro da pasta W E B I N F .
09/10/13
nossas classes:
< m v c : a n n o t a t i o n d r i v e n/ > < c o n t e x t : c o m p o n e n t s c a nb a s e p a c k a g e = " b r . c o m . c a e l u m . t a r e f a s "/ >
Alm disso, preciso informar ao Spring o local onde colocaremos os arquivos JSP. Para isso Spring MVC oferece uma classe especial que recebe o nome da pasta dos JSPs e a extenso dos arquivos. Vamos criar todos os JSPs na pasta / W E B I N F / v i e w s / :
< b e a n c l a s s = " o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . v i e w . I n t e r n a l R e s o u r c e V i e w R e s o l v e r " > < p r o p e r t yn a m e = " p r e f i x "v a l u e = " / W E B I N F / v i e w s / " / > < p r o p e r t yn a m e = " s u f f i x "v a l u e = " . j s p " / > < / b e a n >
Isso j suficiente para comear com o Spring MVC. O arquivo completo, com todos os cabealhos, fica ento como:
< ? x m lv e r s i o n = " 1 . 0 "e n c o d i n g = " U T F 8 " ? > < b e a n sx m l n s = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / b e a n s " x m l n s : x s i = " h t t p : / / w w w . w 3 . o r g / 2 0 0 1 / X M L S c h e m a i n s t a n c e " x m l n s : c o n t e x t = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / c o n t e x t " x m l n s : m v c = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / m v c " x s i : s c h e m a L o c a t i o n = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / m v c h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / m v c / s p r i n g m v c 3 . 0 . x s d h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / b e a n s h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / b e a n s / s p r i n g b e a n s 3 . 0 . x s d h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / c o n t e x t h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / s c h e m a / c o n t e x t / s p r i n g c o n t e x t 3 . 0 . x s d " > < c o n t e x t : c o m p o n e n t s c a nb a s e p a c k a g e = " b r . c o m . c a e l u m . t a r e f a s "/ > < m v c : a n n o t a t i o n d r i v e n/ > < b e a n c l a s s = " o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . v i e w . I n t e r n a l R e s o u r c e V i e w R e s o l v e r " > < p r o p e r t yn a m e = " p r e f i x "v a l u e = " / W E B I N F / v i e w s / " / > < p r o p e r t yn a m e = " s u f f i x "v a l u e = " . j s p " / > < / b e a n > < / b e a n s >
09/10/13
do framework e, a partir do Java 5, surgiram as anotaes, que so uma forma de introduzir metadados dentro de nossas classes. O Spring MVC permite criar as lgicas de formas diferentes, usando convenes ou declarar tudo no XML, porm na verso 3 a maneira indicada utilizando anotaes.
09/10/13
Um ponto importante a se notar que podemos criar outros mtodos que respondam por outras URL's, ou seja, vrios aes dentro dessa classe (dentro do mesmo @ C o n t r o l l e r ). Bastaria que ns utilizssemos novamente a anotao @ R e q u e s t M a p p i n gesses mtodos. Por fim, s precisamos criar o JSP que mostrar a mensagem "Ol mundo!". Basta criar o arquivo o k . j s pdentro da pasta W E B I N F / v i e w s / , que mapeamos anteriormente no XML do Spring. O JSP ter o seguinte contedo:
< h t m l > < b o d y > < h 2 > O l m u n d oc o mS p r i n gM V C ! < / h 2 > < / b o d y > < / h t m l >
Podemos acessar nosso mtodo pela URL http://localhost:8080/fj21tarefas/olaMundoSpring. O que acontece que aps a execuo do mtodo o Spring MVC verifica qual foi o resultado retornado pelo seu mtodo e procura despachar a requisio para a pgina indicada.
Voc pode tambm fazer o curso FJ-21 dessa apostila na Caelum Querendo aprender ainda mais sobre Java na Web e Hibernate? Esclarecer dvidas dos exerccios? Ouvir explicaes detalhadas com um instrutor? A Caelum oferece o curso FJ-21 presencial nas cidades de So Paulo, Rio de Janeiro e Braslia, alm de turmas incompany. Consulte as vantagens do curso Java para Desenvolvimento Web.
09/10/13
commons-logging-1.x.x.jar log4j-1.2.x.jar mysql-connector-java-5.x.x.jar slf4j-api-1.6.x.jar slf4j-log4j12-1.6.x.jar spring-aspects-3.x.x.RELEASE.jar spring-aop-3.x.x.RELEASE.jar spring-beans-3.x.x.RELEASE.jar spring-context-3.x.x.RELEASE.jar spring-core-3.x.x.RELEASE.jar spring-expression-3.x.x.RELEASE.jar spring-jdbc-3.x.x.RELEASE spring-web-3.x.x.jar spring-webmvc-3.x.x.RELEASE.jar
1. Vamos configurar o Spring MVC em um novo projeto. a. Crie um novo projeto web: File -> New -> Project... -> Dynamic Web Project chamado f j 2 1 t a r e f a s . Caso a verso do Dynamic web module esteja com 3.0 selecione 2.5. b. Na aba Servers, clique com o boto direito no Tomcat e v em Add and Remove...: c. Basta selecionar o nosso projeto f j 2 1 t a r e f a se clicar em Add: d. Vamos comear importando as classes que sero necessrias ao nosso projeto, como o modelo de T a r e f a se o D A O . Clique com o boto direito no projeto f j 2 1 t a r e f a se escolha a opo I m p o r t .
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 8/41
09/10/13
Selecione General -> Archive File Escolha o arquivo p r o j e t o t a r e f a s . z i pque est em D e s k t o p / C a e l u m / 2 1e confirme a importao. e. Abra o arquivo w e b . x m lpara fazermos a declarao do servlet do Spring MVC:
< s e r v l e t > < s e r v l e t n a m e > s p r i n g m v c < / s e r v l e t n a m e > < s e r v l e t c l a s s > o r g . s p r i n g f r a m e w o r k . w e b . s e r v l e t . D i s p a t c h e r S e r v l e t < / s e r v l e t c l a s s > < i n i t p a r a m > < p a r a m n a m e > c o n t e x t C o n f i g L o c a t i o n < / p a r a m n a m e > < p a r a m v a l u e > / W E B I N F / s p r i n g c o n t e x t . x m l < / p a r a m v a l u e > < / i n i t p a r a m > < l o a d o n s t a r t u p > 1 < / l o a d o n s t a r t u p > < / s e r v l e t > < s e r v l e t m a p p i n g > < s e r v l e t n a m e > s p r i n g m v c < / s e r v l e t n a m e > < u r l p a t t e r n > / < / u r l p a t t e r n > < / s e r v l e t m a p p i n g >
2. Vamos fazer um simples Ol Mundo, para testarmos nossa configurao: a. Crie uma nova classe chamada O l a M u n d o C o n t r o l l e rno pacote
b r . c o m . c a e l u m . t a r e f a s . c o n t r o l l e r
Dica: Use C t r l + S h i f t + Opara importar as classes. c. Precisamos preparar a camada de visualizao. Crie uma pasta views para nossos JSPs que deve ficar dentro da pasta W e b C o n t e n t / W E B I N F . d. Falta o JSP que ser exibido aps a execuo da nossa lgica. Crie o JSP o k . j s p no diretrio W e b C o n t e n t / W E B I N F / v i e w sdo projeto com o contedo:
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
9/41
09/10/13
< h t m l > < b o d y > < h 2 > O l m u n d oc o mS p r i n gM V C ! < / h 2 > < / b o d y > < / h t m l >
parecido com:
Vamos criar a funcionalidade de adio de novas tarefas. Para isso, teremos uma tela contendo um formulrio com campos para serem preenchidos. Queremos que, ao criarmos uma nova tarefa, a mesma venha por padro como no finalizada e, consequentemente, sem a data de finalizao definida. Dessa forma, nosso formulrio ter apenas o campo d e s c r i c a o . Podemos criar um JSP chamado
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 10/41
09/10/13
O nosso form, ao ser submetido, chama uma ao, um mtodo dentro de um @ C o n t r o l l e rque responde pela URL a d i c i o n a T a r e f a . Esse mtodo precisa receber os dados da requisio e gravar a tarefa que o usurio informou na tela. Vamos chamar esse mtodo a d i c i o n ae colocar dentro da classe T a r e f a s C o n t r o l l e r :
@ C o n t r o l l e r p u b l i cc l a s sT a r e f a s C o n t r o l l e r{ @ R e q u e s t M a p p i n g ( " a d i c i o n a T a r e f a " ) p u b l i cS t r i n ga d i c i o n a ( ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . a d i c i o n a ( t a r e f a ) ; r e t u r n" t a r e f a a d i c i o n a d a " ; } }
Mas, como montaremos o objeto t a r e f apara passarmos ao nosso D A O ? Dentro dessa nossa classe T a r e f a s C o n t r o l l e rem nenhum momento temos um H t t p S e r v l e t R e q u e s tpara pegarmos os parmetros enviados na requisio e montarmos o objeto t a r e f a . Uma das grandes vantagens de frameworks modernos que eles conseguem popular os objetos para ns. Basta que de alguma forma, ns faamos uma ligao entre o campo que est na tela com o objeto que queremos popular. E com o Spring MVC no diferente. Essa ligao feita atravs da criao de um parmetro do mtodo a d i c i o n a . Esse parmetro o objeto que dever ser populado pelo Spring MVC com os dados que vieram da requisio. Portanto, vamos criar no nosso mtodo um novo parmetro chamado t a r e f a :
@ C o n t r o l l e r p u b l i cc l a s sT a r e f a s C o n t r o l l e r{
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 11/41
09/10/13
Queremos que o campo de texto que criamos no nosso formulrio preencha a descrio dessa tarefa. Para fazermos isso, basta darmos o nome com o caminho da propriedade que queremos definir. Portanto, se dentro do objeto t a r e f a queremos definir a propriedade d e s c r i c a o , basta nomearmos o i n p u tcom d e s c r i c a o . O Spring MVC cria o objeto t a r e f apara ns e preenche esse objeto com os dados da requisio, nesse caso com o parmetro d e s c r i c a oda requisio. Como a classe T a r e f a um JavaBean e possui construtor sem argumentos e getters/setters isso no ser problema. Por fim, basta exibirmos a mensagem de confirmao de que a criao da tarefa foi feita com sucesso. Criamos o arquivo t a r e f a a d i c i o n a d a . j s pcom o seguinte contedo HTML:
< h t m l > < b o d y > N o v at a r e f aa d i c i o n a d ac o ms u c e s s o ! < / b o d y > < / h t m l >
09/10/13
Na pasta W E B I N F / v i e w s / t a r e f atambm deve ficar o formulrio para adicionar uma tarefa. Como discutimos antes, todos os JSPs da tarefa na mesma sub-pasta. Porm aqui surge um novo problema: preciso carregar o JSP no navegador, mas o acesso direto ao pasta W E B I N F proibido pelo servlet-container e consequentemente no possvel acessar o formulrio. Para resolver isso vamos criar uma nova ao (um novo mtodo) dentro da classe T a r e f a s C o n t r o l l e rque tem a finalidade de chamar o formulrio apenas. O mtodo usa tambm a anotoo @ R e q u e s t M a p p p i n ge retorna um S t r i n gpara chamar o formulrio. Abaixo o cdigo completo do T a r e f a s C o n t r o l l e rcom os dois mtodos:
@ C o n t r o l l e r p u b l i cc l a s sT a r e f a s C o n t r o l l e r{ @ R e q u e s t M a p p i n g ( " n o v a T a r e f a " ) p u b l i cS t r i n gf o r m ( ){ r e t u r n" t a r e f a / f o r m u l a r i o " ; }
Tire suas dvidas no novo GUJ Respostas O GUJ um dos principais fruns brasileiros de computao e o maior em
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 13/41
09/10/13
portugus sobre Java. A nova verso do GUJ baseada em uma ferramenta de perguntas e respostas (QA) e tem uma comunidade muito forte. So mais de 150 mil usurios pra ajudar voc a esclarecer suas dvidas. Faa sua pergunta.
2. Agora precisamos um mtodo (action) dentro de um @ C o n t r o l l e rpara acessar o JSP. Crie uma nova classe no pacote b r . c o m . c a e l u m . t a r e f a s . c o n t r o l l e r chamada T a r e f a s C o n t r o l l e r . Nossa classe precisa ter um mtodo para acessar o JSP. Vamos chamar o mtodo form() e usar a anotao @RequestMapping:
@ C o n t r o l l e r p u b l i cc l a s sT a r e f a s C o n t r o l l e r{ @ R e q u e s t M a p p i n g ( " n o v a T a r e f a " ) p u b l i cS t r i n gf o r m ( ){ r e t u r n" t a r e f a / f o r m u l a r i o " ; } }
Use C t r l + S h i f t + Opara importar as classes. 3. Ainda falta o mtodo que realmente adiciona a tarefa no banco de dados. Esse
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 14/41
09/10/13
mtodo chamado pelo nosso formulrio e recebe uma tarefa como parmetro. Ele novamente usa a anotao @ R e q u e s t M a p p i n gpara definir a URL. Dentro da classe T a r e f a s C o n t r o l l e rcrie o mtodo a d i c i o n aque recebe uma tarefa. No mtodo usamos a J d b c T a r e f a D a opara persistir os dados. O retorno do mtodo define o local e nome do JSP. O cdigo deve ficar:
@ R e q u e s t M a p p i n g ( " a d i c i o n a T a r e f a " ) p u b l i cS t r i n ga d i c i o n a ( T a r e f at a r e f a ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . a d i c i o n a ( t a r e f a ) ; r e t u r n" t a r e f a / a d i c i o n a d a " ; }
4. E, por fim, criamos o arquivo adicionada.jsp na pasta tarefa que mostrar uma mensagem de confirmao de que a tarefa foi efetivamente adicionada.
< h t m l > < b o d y > N o v at a r e f aa d i c i o n a d ac o ms u c e s s o ! < / b o d y > < / h t m l >
5. Reinicie o Tomcat. Acesse no seu navegador o endereo h t t p : / / l o c a l h o s t : 8 0 8 0 / f j 2 1 t a r e f a s / n o v a T a r e f ae adicione uma nova tarefa.
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
15/41
09/10/13
Caso acontea uma exceo informando que a tabela no est criada, crie-a com o script abaixo e tente inserir novamente a tarefa. Abra o terminal e digite:
m y s q lur o o t u s ef j 2 1 ; c r e a t et a b l et a r e f a s( i dB I G I N TN O TN U L LA U T O _ I N C R E M E N T , d e s c r i c a oV A R C H A R ( 2 5 5 ) , f i n a l i z a d oB O O L E A N , d a t a F i n a l i z a c a oD A T E , p r i m a r yk e y( i d ) ) ;
Validando programaticamente
A maneira mais fcil de validar a tarefa usar vrios i f s no mtodo a d i c i o n ada classe T a r e f a s C o n t r o l l e rantes de chamar d a o . a d i c i o n a ( t a r e f a ) , executando a validao programaticamente. O cdigo seguinte mostra a ideia:
@ R e q u e s t M a p p i n g ( " a d i c i o n a T a r e f a " ) p u b l i cS t r i n ga d i c i o n a ( T a r e f at a r e f a ){ i f ( t a r e f a . g e t D e s c r i c a o ( )= =n u l l| |t a r e f a . g e t D e s c r i c a o ( ) . e q u a l s ( " " ) ){ r e t u r n" t a r e f a / f o r m u l a r i o " ; }
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 16/41
09/10/13
O problema aqui quanto mais atributos na tarefa mais i f s teremos. provvel tambm que vamos repetir um i fou outro quando validarmos a tarefa em mtodos diferentes, por exemplo, para adicionar ou alterar a tarefa. Sabemos que copiar e colar cdigo no uma boa maneira de reaproveitar cdigo. O que precisamos de algum artifcio que seja igual para qualquer mtodo, algo que ajude na validao dos dados.
Pronto! Com essas anotaes, qualquer objeto do tipo T a r e f apode ser validado na camada de controller. S falta avisar o Spring MVC que realmente queremos executar a validao. Isso feito pela anotao V a l i dque devemos usar na antes do parmetro da ao:
@ R e q u e s t M a p p i n g ( " a d i c i o n a T a r e f a " ) p u b l i cS t r i n ga d i c i o n a ( @ V a l i dT a r e f at a r e f a ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . a d i c i o n a ( t a r e f a ) ; r e t u r n" t a r e f a / a d i c i o n a d a " ; }
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 17/41
09/10/13
Como estamos falando de Spring MVC, antes da chamada do mtodo executada a validao, ou seja ser verificado se a descrio da tarefa no est vazia. Se estiver, ser lanada uma exceo do tipo C o n s t r a i n t V i o l a t i o n E x c e p t i o nque possui a descrio do erro. No queremos mostrar uma exceo para o usurio e sim apenas voltar para o formulrio para mostrar uma mensagem que a validao falhou. O Spring MVC pode guardar o resultado (os erros de validao) em um objeto do tipo B i n d i n g R e s u l t . Assim no ser lanado um exceo. Este objeto B i n d i n g R e s u l t se torna um parmetro da ao. Ento s preciso perguntar para ele se existe um erro de validao e se existir, voltar para o formulrio. Veja o cdigo:
@ R e q u e s t M a p p i n g ( " a d i c i o n a T a r e f a " ) p u b l i cS t r i n ga d i c i o n a ( @ V a l i dT a r e f at a r e f a ,B i n d i n g R e s u l tr e s u l t ){ i f ( r e s u l t . h a s F i e l d E r r o r s ( " d e s c r i c a o " ) ){ r e t u r n" t a r e f a / f o r m u l a r i o " ; } J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . a d i c i o n a ( t a r e f a ) ; r e t u r n" t a r e f a / a d i c i o n a d a " ; }
No cdigo acima verificamos se existe um de erro validao relacionado com o atributo d e s c r i c a oda tarefa. Tambm podemos conferir se existe algum erro de validao, mais genrico:
@ R e q u e s t M a p p i n g ( " a d i c i o n a T a r e f a " ) p u b l i cS t r i n ga d i c i o n a ( @ V a l i dT a r e f at a r e f a ,B i n d i n g R e s u l tr e s u l t ){ i f ( r e s u l t . h a s E r r o r s ( ) ){ r e t u r n" t a r e f a / f o r m u l a r i o " ; }
O atributo path indica com que atributo essa mensagem est relacionada. Abaixo est o cdigo completo do formulrio formulario.jsp da pasta t a r e f a . Repare que preciso importar o taglib do Spring MVC:
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
18/41
09/10/13
< % @ t a g l i bu r i = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / t a g s / f o r m "p r e f i x = " f o r m "% > < h t m l > < b o d y > < h 3 > A d i c i o n a rt a r e f a s < / h 3 > < f o r ma c t i o n = " a d i c i o n a T a r e f a "m e t h o d = " p o s t " > D e s c r i o : < b r / > < t e x t a r e ar o w s = " 5 "c o l s = " 1 0 0 "n a m e = " d e s c r i c a o " > < / t e x t a r e a > < b r / > < f o r m : e r r o r sp a t h = " t a r e f a . d e s c r i c a o "c s s S t y l e = " c o l o r : r e d " / > < b r / > < i n p u tt y p e = " s u b m i t "v a l u e = " A d i c i o n a r " / > < / f o r m > < / b o d y > < / h t m l >
Mensagens internacionalizadas
Para deixar as mensagens de nossa aplicao mais fceis de alterar, comum criar um arquivo separado do HTML que possui apenas mensagens. Este arquivo normalmente chamado mensagens.properties ou messages.properties. Na pasta WEB-INF do projeto podemos ento criar este arquivo com o seguinte contedo:
t a r e f a . a d i c i o n a d a . c o m . s u c e s s o = T a r e f aa d i c i o n a d ac o ms u c e s s o ! . . .
Repare que definimos as mensagens em um estilo de: <chave>=<valor>. O Spring MVC pode carregar automaticamente este arquivo, desde que a linha abaixo seja includa no arquivo spring-context.xml:
< b e a ni d = " m e s s a g e S o u r c e "c l a s s = " o r g . s p r i n g f r a m e w o r k . c o n t e x t . s u p p o r t . R e l o a d a b l e R e s o u r c e B u n d l e M e s s a g e S o u r c e " > < p r o p e r t yn a m e = " b a s e n a m e "v a l u e = " / W E B I N F / m e n s a g e n s "/ > < / b e a n >
Basta ento usar a taglib f m tpara mostra mensagens do arquivo m e n s a g e n s . p r o p e r t i e sna pgina HTML:
< f m t : m e s s a g ek e y = " t a r e f a . a d i c i o n a d a . c o m . s u c e s s o " / >
09/10/13
p u b l i cc l a s sT a r e f a{ p r i v a t eL o n gi d ; @ N o t N u l l ( m e s s a g e = " Ad e s c r i od e v es e rp r e e n c h i d a " ) p r i v a t eS t r i n gd e s c r i c a o ; . . .
Para no deixar as mensagens de validao espalhadas em nossas classes, podemos isolar estas mensagens no arquivo padro de mensagens do Bean Validation, chamado V a l i d a t i o n M e s s a g e s . p r o p e r t i e s :
t a r e f a . d e s c r i c a o . v a z i a = D e s c r i od e v es e rp r e e n c h i d a ! t a r e f a . d e s c r i c a o . p e q u e n a = D e s c r i od e v ec o n t e r p e l om e n o s{ m i n }c a r a c t e r e s . . .
E referenciar as chaves das mensagens dentro das anotaes tambm pelo atributo m e s s a g e :
p u b l i cc l a s sT a r e f a{ p r i v a t eL o n gi d ; @ N o t N u l l ( m e s s a g e = " { t a r e f a . d e s c r i c a o . v a z i a } " ) @ S i z e ( m i n = 5 ,m e s s a g e = " { t a r e f a . d e s c r i c a o . p e q u e n a } " ) p r i v a t eS t r i n gd e s c r i c a o ;
Nova editora Casa do Cdigo com livros de uma forma diferente Editoras tradicionais pouco ligam para ebooks e novas tecnologias. No conhecem programao para revisar os livros tecnicamente a fundo. No tm anos de experincia em didticas com cursos. Conhea a Casa do Cdigo, uma editora diferente, com curadoria da Caelum e obsesso por livros de qualidade a preos justos. Casa do Cdigo, ebook com preo de ebook.
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
20/41
09/10/13
Haver dois JARs: validation-api-1.x.x.GA.jar e hibernate-validator4.x.x.Final.jar . Copie-os (CTRL+C) e cole-os (CTRL+V) dentro de w o r k s p a c e / f j 2 1 t a r e f a s / W e b C o n t e n t / W E B I N F / l i b
2. Abra a classe T a r e f a . Nela preciso definir as regras de validao atravs das anotaes do framework Bean validation. A atributo descricao deve ter pelo menos 5 caracteres:
p u b l i cc l a s sT a r e f a{ p r i v a t eL o n gi d ; @ N o t N u l l@ S i z e ( m i n = 5 ) p r i v a t eS t r i n gd e s c r i c a o ;
3. Abra a classe T a r e f a s C o n t r o l l e re procure o mtodo adiciona. Coloque a anotao @Valid na frente do parmetro T a r e f at a r e f ae adicione o parmetro B i n d i n g R e s u l tna assinatura do mtodo. Alm disso, no mesmo mtodo, adicione a verificao se h erros de validao. O mtodo completo fica:
@ R e q u e s t M a p p i n g ( " a d i c i o n a T a r e f a " ) p u b l i cS t r i n ga d i c i o n a ( @ V a l i dT a r e f at a r e f a ,B i n d i n g R e s u l tr e s u l t ){ i f ( r e s u l t . h a s F i e l d E r r o r s ( " d e s c r i c a o " ) ){ r e t u r n" t a r e f a / f o r m u l a r i o " ; } J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . a d i c i o n a ( t a r e f a ) ; r e t u r n" t a r e f a / a d i c i o n a d a " ; }
4. Abra o JSP formulario.jsp (da pasta W E B I N F / v i e w s / t a r e f a ). Adicione no incio da pgina a declarao da taglib do Spring MVC:
< % @ t a g l i bu r i = " h t t p : / / w w w . s p r i n g f r a m e w o r k . o r g / t a g s / f o r m "p r e f i x = " f o r m "% >
Dentro do HTML adicione a tag form:errors acima do tag form. Adicione apenas o tag form:errors:
< f o r m : e r r o r sp a t h = " t a r e f a . d e s c r i c a o " / > < f o r ma c t i o n = " a d i c i o n a T a r e f a "m e t h o d = " p o s t " >
5. Reinicie o Tomcat e acesse no seu navegador o endereo h t t p : / / l o c a l h o s t : 8 0 8 0 / f j 2 1 t a r e f a s / n o v a T a r e f aEnvie uma requisico SEM
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 21/41
09/10/13
Como j conseguimos adicionar tarefas em nossa aplicao, precisamos saber o que foi adicionado. Para isso precisamos criar uma nova funcionalidade que lista as tarefas. A funo dessa ao ser invocar o J d b c T a r e f a D a opara conseguir a lista das tarefas que esto no banco de dados. Podemos adicionar um novo mtodo dentro da classe T a r e f a s C o n t r o l l e r :
@ R e q u e s t M a p p i n g ( " l i s t a T a r e f a s " ) p u b l i cS t r i n gl i s t a ( ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; L i s t < T a r e f a >t a r e f a s=d a o . l i s t a ( ) ; r e t u r n" t a r e f a / l i s t a " ; }
Essa lista de tarefas dever ser disponibilizada para o JSP fazer sua exibio. Para que possamos disponibilizar um objeto para o JSP, temos que alterar o retorno do mtodo l i s t a . A ideia que o Spring MVC no s recebe o nome da pgina JSP (t a r e f a / l i s t a ) quando chama o mtodo l i s t a , o Spring MVC tambm recebe os dados para o JSP. Os dados para a exibio na tela e o nome da pgina JSP foram encapsulados pelo Spring MVC em uma classe especial que se chama M o d e l A n d V i e w . Vamos criar um objeto do tipo M o d e l A n d V i e we preencher esse modelo com nossa lista de tarefas e definir o nome da pgina JSP. O mtodo l i s t a deve retornar esse objeto, no mais apenas um S t r i n g . Veja como fica o cdigo:
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 22/41
09/10/13
@ R e q u e s t M a p p i n g ( " l i s t a T a r e f a s " ) p u b l i cM o d e l A n d V i e wl i s t a ( ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; L i s t < T a r e f a >t a r e f a s=d a o . l i s t a ( ) ; M o d e l A n d V i e wm v=n e wM o d e l A n d V i e w ( " t a r e f a / l i s t a " ) ; m v . a d d O b j e c t ( " t a r e f a s " ,t a r e f a s ) ; r e t u r nm v ; }
Dessa forma, ser disponibilizado para o JSP um objeto chamado t a r e f a sque pode ser acessado via Expression Language como $ { t a r e f a s } . Poderamos em seguida iterar sobre essa lista utilizando a Tag f o r E a c hda JSTL core. Vendo o cdigo da ao l i s t apode aparecer estranho instanciar uma classe do framework Spring (M o d e l A n d V i e w ) dentro do nosso controlador. Isso at influencia negativamente a testabilidade do mtodo. Por isso, O Spring MVC d uma outra opo, oferece uma alternativa ao uso da classe M o d e l A n d V i e w . Na nossa ao podemos receber um objeto que representa o modelo para o nosso JSP. Spring MVC pode passar um parmetro para o mtodo do controlador que tem a funo do modelo. Esse modelo podemos preencher com a lista de tarefas. Assim tambm continuaremos devolver uma String como retorno do mtodo que indica o caminho para o JSP:
@ R e q u e s t M a p p i n g ( " l i s t a T a r e f a s " ) p u b l i cS t r i n gl i s t a ( M o d e lm o d e l ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; L i s t < T a r e f a >t a r e f a s=d a o . l i s t a ( ) ; m o d e l . a d d A t t r i b u t e ( " t a r e f a s " ,t a r e f a s ) ; r e t u r n" t a r e f a / l i s t a " ; }
09/10/13
b. Para fazer a listagem, vamos precisar da JSTL (iremos fazer um f o r E a c h ), portanto precisamos import-la. Primeiro, v ao Desktop, e entre no diretrio
C a e l u m / 2 1 / j s t l .
c. Haver dois JARs, jstl-impl-xx.jar e jstl-api-xx.jar. d. Copie-os (CTRL+C) e cole-os (CTRL+V) dentro de w o r k s p a c e / f j 2 1 t a r e f a s / W e b C o n t e n t / W E B I N F / l i b
e. No Eclipse, d um F5 no seu projeto. Pronto, a JSTL j est em nosso projeto. f. Crie o JSP que far a exibio das tarefas dentro da pasta W e b C o n t e n t / W E B I N F / v i e w s / t a r e f a .
< % @ t a g l i bu r i = " h t t p : / / j a v a . s u n . c o m / j s p / j s t l / c o r e "p r e f i x = " c "% > < % @ t a g l i bu r i = " h t t p : / / j a v a . s u n . c o m / j s p / j s t l / f m t "p r e f i x = " f m t "% > < h t m l > < b o d y > < ah r e f = " n o v a T a r e f a " > C r i a rn o v at a r e f a < / a > < b r/ >< b r/ > < t a b l e > < t r > < t h > I d < / t h > < t h > D e s c r i o < / t h > < t h > F i n a l i z a d o ? < / t h > < t h > D a t ad ef i n a l i z a o < / t h > < / t r > < c : f o r E a c hi t e m s = " $ { t a r e f a s } "v a r = " t a r e f a " > < t r > < t d > $ { t a r e f a . i d } < / t d > < t d > $ { t a r e f a . d e s c r i c a o } < / t d > < c : i ft e s t = " $ { t a r e f a . f i n a l i z a d oe qf a l s e } " > < t d > N of i n a l i z a d o < / t d > < / c : i f > < c : i ft e s t = " $ { t a r e f a . f i n a l i z a d oe qt r u e } " > < t d > F i n a l i z a d o < / t d > < / c : i f > < t d > < f m t : f o r m a t D a t e v a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } " p a t t e r n = " d d / M M / y y y y " / > < / t d > < / t r > < / c : f o r E a c h > < / t a b l e >
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 24/41
09/10/13
J conhece os cursos online Alura? A Alura oferece dezenas de cursos online em sua plataforma exclusiva de ensino que favorece o aprendizado com a qualidade reconhecida da Caelum. Voc pode escolher um curso nas reas de Java, Ruby, Web, Mobile, .NET e outros, ou fazer a assinatura semestral que d acesso a todos os cursos. Conhea os cursos online da Caelum.
Podemos desenvolver um mtodo para fazer a remoo. A lgica no possui nenhuma novidade, basta recuperarmos o parmetro como aprendemos nesse captulo e invocarmos o D A Opara fazer a remoo:
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
25/41
09/10/13
A questo : Para qual lugar redirecionar o usurio aps a excluso? Poderamos criar um novo JSP com uma mensagem de confirmao da remoo, mas usualmente isso no costuma ser bom, porque precisaramos navegar at a lista das tarefas novamente caso tenhamos que remover outra tarefa. Seria muito mais agradvel para o usurio que ele fosse redirecionado direto para a lista das tarefas. Uma das formas que poderamos fazer esse redirecionamento enviar o usurio diretamente para a pgina que lista as tarefas (t a r e f a / l i s t a . j s p ). Mas, essa no uma boa abordagem, porque precisaramos, outra vez, disponibilizar a lista das tarefas para o JSP, algo que j fazemos na ao de listar as tarefas, o mtodo l i s t a na classe T a r e f a s C o n t r o l l e r . J que o mtodo l i s t afaz esse trabalho, poderamos vs de redirecionar a execuo para o JSP, envi-la para essa ao. Para isso, o retorno do mtodo deve ser um pouco modificado. Vamos continuar devolvendo uma S t r i n gmas essa S t r i n gdeve indicar que queremos chamar uma outra ao. Podemos fazer um redirecionamento na lado do servidor (forward) ou pelo navegador, no lado do cliente (redirect). Para fazer um redirecionamento no lado do servidor basta usar o prefixo forward no retorno:
@ R e q u e s t M a p p i n g ( " r e m o v e T a r e f a " ) p u b l i cS t r i n gr e m o v e ( T a r e f at a r e f a ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . r e m o v e ( t a r e f a ) ; r e t u r n" f o r w a r d : l i s t a T a r e f a s " ; }
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
26/41
09/10/13
c. Acesse a lista de tarefas em http://localhost:8080/fj21-tarefas/listaTarefas e remova algumas tarefas. 2. Criaremos a tela para fazer a alterao das tarefas, como por exemplo, marc-la como finalizada e definirmos a data de finalizao. a. Primeiro vamos criar um novo link na nossa listagem que enviar o usurio para a tela contendo os dados da tarefa selecionada:
< t d > < ah r e f = " m o s t r a T a r e f a ? i d = $ { t a r e f a . i d } " > A l t e r a r < / a > < / t d >
b. Vamos criar uma nova ao que dado um i d , devolver a T a r e f acorrespondente para um JSP, que mostrar os dados para que a alterao possa ser feita.Crie um novo mtodo m o s t r ana classe T a r e f a s C o n t r o l l e r :
@ R e q u e s t M a p p i n g ( " m o s t r a T a r e f a " ) p u b l i cS t r i n gm o s t r a ( L o n gi d ,M o d e lm o d e l ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; m o d e l . a d d A t t r i b u t e ( " t a r e f a " ,d a o . b u s c a P o r I d ( i d ) ) ; r e t u r n" t a r e f a / m o s t r a " ; }
09/10/13
< i n p u tt y p e = " h i d d e n "n a m e = " i d "v a l u e = " $ { t a r e f a . i d } "/ > D e s c r i o : < b r/ > < t e x t a r e an a m e = " d e s c r i c a o "c o l s = " 1 0 0 "r o w s = " 5 " > $ { t a r e f a . d e s c r i c a o } < / t e x t a r e a > < b r/ > F i n a l i z a d o ?< i n p u tt y p e = " c h e c k b o x "n a m e = " f i n a l i z a d o " v a l u e = " t r u e "$ { t a r e f a . f i n a l i z a d o ?' c h e c k e d ':' '} / >< b r/ > D a t ad ef i n a l i z a o :< b r/ > < i n p u tt y p e = " t e x t "n a m e = " d a t a F i n a l i z a c a o " v a l u e = " < f m t : f o r m a t D a t e v a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } " p a t t e r n = " d d / M M / y y y y "/ > " / > < b r/ > < i n p u tt y p e = " s u b m i t "v a l u e = " A l t e r a r " / > < / f o r m > < / b o d y > < / h t m l >
d. Para o Spring MVC saber converter automaticamente a data no formato brasileiro para um C a l e n d a r preciso usar a anotao @ D a t e T i m e F o r m a t . Abra a classe
T a r e f ae
@ D a t e T i m e F o r m a t ( p a t t e r n = " d d / M M / y y y y " ) p r i v a t eC a l e n d a rd a t a F i n a l i z a c a o ;
esse mtodo:
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
28/41
09/10/13
Voc no est nessa pgina a toa Voc chegou aqui porque a Caelum referncia nacional em cursos de Java, Ruby, Agile, Mobile, Web e .NET. Faa curso com quem escreveu essa apostila. Consulte as vantagens do curso Java para Desenvolvimento Web.
09/10/13
GET). O JQuery nos fornece duas funes: $ . p o s te $ . g e t , cada uma para cada mtodo. Para as funes basta passarmos o endereo que queremos invocar, como por exemplo:
$ . g e t ( " m i n h a P a g i n a . j s p " )
Nesse caso, estamos enviando uma requisio via GET para o endereo m i n h a P a g i n a . j s p . Sabendo isso, vamos criar um link que invocar uma funo Javascript e far requisio AJAX para uma ao que finalizar a tarefa:
< t d > < ah r e f = " # "o n c l i c k = " f i n a l i z a A g o r a ( $ { t a r e f a . i d } ) " > F i n a l i z a ra g o r a < / a > < / t d >
Vamos criar a funo f i n a l i z a A g o r aque recebe o id da tarefa que ser finalizada e a passar como parmetro para a ao:
< s c r i p tt y p e = " t e x t / j a v a s c r i p t " > f u n c t i o nf i n a l i z a A g o r a ( i d ){ $ . g e t ( " f i n a l i z a T a r e f a ? i d = "+i d ) ; } < / s c r i p t >
Por fim, basta criarmos a nossa ao que receber o parmetro e invocar um mtodo do J d b c T a r e f a D a opara fazer a finalizao da tarefa. No entanto, a requisio que estamos fazendo no gerar resposta nenhuma e ns sempre retornamos uma String o resultado que determina qual JSP ser exibido. Dessa vez, no exibiremos nem um JSP e nem invocaremos outra A c t i o n . O protocolo HTTP sempre retorna um cdigo indicando qual o estado dessa resposta, ou seja, se foi executado com sucesso, se a pgina no foi encontrada, se algum erro aconteceu e assim por diante. O protocolo HTTP define que o cdigo 200 indica que a execuo ocorreu com sucesso, portanto, vamos apenas indicar na nossa resposta o cdigo, sem devolver nada no corpo da nossa resposta. Para setar o cdigo da resposta programaticamente precisamos do objeto H t t p S e r v l e t R e s p o n s e . Podemos receber a resposta HTTP como parmetro de qualquer mtodo que uma ao. Com a resposta na mo podemos chamar o mtodo s e t S t a t u s ( 2 0 0 ) . Dessa forma, poderamos ter um mtodo na classe T a r e f a s C o n t r o l l e rpara fazer a finalizao da tarefa com o seguinte cdigo:
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 30/41
09/10/13
O primeiro parmetro a id da tarefa que vem atravs da requisio, o segundo a resposta para setar o cdigo HTTP.
Repare que $ . g e trecebe mais uma funo como parmetro (tambm chamado callback de sucesso). Nela, definimos apenas um simples alert para mostrar uma mensagem ao usurio. Tambm possvel manipular o HTML da pgina dinamicamente. O JQuery oferece recursos poderosos para alterar qualquer elemento HTML dentro do navegador. Por exemplo, podemos selecionar um elemento da pgina pela i de mudar o contedo desse elemento:
$ ( " # i d D o E l e m e n t o H T M L " ) . h t m l ( " N o v oc o n t e d oH T M Ld e s s ee l e m e n t o " ) ;
Para o nosso exemplo, ento interessante atualizar a coluna da tarefa para indicar que ela foi finalizada:
$ ( " # t a r e f a _ " + i d ) . h t m l ( " T a r e f af i n a l i z a d a " ) ;
09/10/13
Seus livros de tecnologia parecem do sculo passado? Conhea a Casa do Cdigo, uma nova editora, com autores de destaque no mercado, foco em ebooks (PDF, epub, mobi), preos imbatveis e assuntos atuais. Com a curadoria da Caelum e excelentes autores, uma abordagem diferente para livros de tecnologia no Brasil. Conhea os ttulos e a nova proposta, voc vai gostar. Casa do Cdigo, livros para o programador.
Na pasta W e b C o n t e n tcrie uma nova pasta r e s o u r c e s , vamos colocar nela tudo relativo a contedo esttico do nosso sistema. 2. Vamos adicionar AJAX na nossa aplicao. Para isso, utilizaremos o JQuery que precisamos importar para nosso projeto e em nossas pginas. a. V ao Desktop, e entre em C a e l u m / 2 1 ; b. Copie os diretrio j se cole-os dentro de W e b C o n t e n t / r e s o u r c e sno seu projeto fj21-tarefas; Caso voc esteja em casa, faa o download em http://jquery.com/download
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 32/41
09/10/13
c. Precisamos importar o JQuery em nossa pgina de listagem. Para isso, adicione logo aps a Tag < h t m l >o seguinte cdigo no arquivo l i s t a . j s p :
< h e a d > < s c r i p tt y p e = " t e x t / j a v a s c r i p t "s r c = " r e s o u r c e s / j s / j q u e r y . j s " > < / s c r i p t > < / h e a d >
d. Pronto, importamos o JQuery para nossa aplicao. 3. Caso a tarefa no esteja finalizada, queremos que ela possua uma nova coluna que se chamar "Finalizar agora". Ao clicar, chamaremos via AJAX uma A c t i o n que marcar a tarefa como finalizada e a data de hoje ser marcada como a data de finalizao da mesma. a. Altere a coluna que mostra a tarefa como no finalizada no arquivo l i s t a . j s p . Adicione um link que ao ser clicada, chamar uma funo Javascript passando o
i dda
tarefa para finalizar. Tambm adicione uma id para cada elemento < t d > .No
arquivo procure o c:if para tarefas no finalizadas, altere o elemento t ddentro c:if:
< c : i ft e s t = " $ { t a r e f a . f i n a l i z a d oe qf a l s e } " > < t di d = " t a r e f a _ $ { t a r e f a . i d } " > < ah r e f = " # "o n C l i c k = " f i n a l i z a A g o r a ( $ { t a r e f a . i d } ) " > F i n a l i z aa g o r a ! < / a > < / t d > < / c : i f >
b. Crie a funo Javascript f i n a l i z a A g o r apara chamar a ao que criaremos a seguir via uma requisio POST:
< ! -C o m e od ap g i n ac o moi m p o r td oJ a v a s c r i p t> < b o d y > < s c r i p tt y p e = " t e x t / j a v a s c r i p t " > f u n c t i o nf i n a l i z a A g o r a ( i d ){ $ . p o s t ( " f i n a l i z a T a r e f a " ,{ ' i d ':i d } ,f u n c t i o n ( ){ / /s e l e c i o n a n d ooe l e m e n t oh t m la t r a v sd a / /I Dea l t e r a n d ooH T M Ld e l e $ ( " # t a r e f a _ " + i d ) . h t m l ( " F i n a l i z a d o " ) ; } ) ; } < / s c r i p t > < ah r e f = " n o v a T a r e f a " > C r i a rn o v at a r e f a < / a > < b r/ >< b r/ > < t a b l e > < ! -R e s t od ap g i n ac o mat a b e l a>
4. Vamos criar o mtodo para finalizar a tarefa. Aps o mesmo ser executado, ele
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 33/41
09/10/13
no dever nos redirecionar para lugar nenhum, apenas indicar que a execuo ocorreu com sucesso. a. Abra a classe T a r e f a s C o n t r o l l e rAdicione o mtodo f i n a l i z acom o contedo:
@ R e q u e s t M a p p i n g ( " f i n a l i z a T a r e f a " ) p u b l i cv o i df i n a l i z a ( L o n gi d ,H t t p S e r v l e t R e s p o n s er e s p o n s e ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . f i n a l i z a ( i d ) ; r e s p o n s e . s e t S t a t u s ( 2 0 0 ) ; }
b. Acesse a listagem http://localhost:8080/fj21-tarefas/listaTarefas e clique no novo link para finalizar tarefa. A tela muda sem precisar uma atualizao inteira da pgina.
5. (Opcional, Avanado) No mesmo estilo do exerccio anterior, use o JQuery para acionar o mtodo r e m o v e T a r e f aquando clicado em um boto de "excluir". Para isso, crie uma nova coluna na tabela com um link que o onClick vai chamar o endereo associado a r e m o v e T a r e f a , e via AJAX devemos remover a linha da tabela. Pra isso voc pode usar um recurso poderoso do JQuery e pedir que seja escondida a linha de onde veio o clique:
$ ( e l e m e n t o H t m l ) . c l o s e s t ( " t r " ) . h i d e ( ) ;
11.22 - PARA SABER MAIS: ALT ERANDO VALOR DA DAT A COM AJAX
Agora ao finalizar nossa tarefa via AJAX o usurio tem um feedback na alterao do HTML de No Finalizado para Finalizado. Porm todas as tarefas finalizadas possuem a coluna de data de finalizao preenchidas, menos as que acabamos de finalizar.
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
34/41
09/10/13
Para resolver esse problema, de alguma forma o nosso Controller deveria passar uma data para nosso JQuery. Mas como? Uma soluo possvel seria escrev-la direto no response. Algo parecido com isso:
@ R e q u e s t M a p p i n g ( " f i n a l i z a T a r e f a " ) p u b l i cv o i df i n a l i z a ( L o n gi d ,H t t p S e r v l e t R e s p o n s er e s p o n s e )t h r o w s I O E x c e p t i o n{ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . f i n a l i z a ( i d ) ; D a t ed a t a D e F i n a l i z a c a o= d a o . b u s c a P o r I d ( i d ) . g e t D a t a F i n a l i z a c a o ( ) . g e t T i m e ( ) ; S t r i n gd a t a=n e w S i m p l e D a t e F o r m a t ( " d d / M M / y y y y " ) . f o r m a t ( d a t a D e F i n a l i z a c a o ) ; r e s p o n s e . g e t W r i t e r ( ) . w r i t e ( d a t a ) ; r e s p o n s e . s e t S t a t u s ( 2 0 0 ) ; }
Resolve nosso problema mas ainda assim teramos que ficar trabalhando direto em um camada mais baixa que so as classes de H T T P S e r v l e t R e q u e s te H T T P S e r v l e t R e s p o n s e . Agora alm de finalizar uma tarefa nossa action tem as responsabilidades de buscar pela data finalizada, formatar a data, escrever no response e mudar o status para 2 0 0 . Responsabilidade de mais, no mesmo? Retornar uma JSP j nos traz o benefcio do status 2 0 0 , necessrio para nossa funo de callback no JQuery. Sabendo disso usaremos uma JSP para renderizar a data formatada. Mas antes preciso passar essa data a nossa JSP, ou simplesmente passar uma T a r e f apara ela e depois fazer com que a Action retorne a S t r i n g referente a JSP.
@ R e q u e s t M a p p i n g ( " f i n a l i z a T a r e f a " ) p u b l i cv o i df i n a l i z a ( L o n gi d ,M o d e lm o d e l ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . f i n a l i z a ( i d ) ; m o d e l . a d d A t t r i b u t e ( " t a r e f a " ,d a o . b u s c a P o r I d ( i d ) ) ; r e t u r n" t a r e f a / d a t a F i n a l i z a d a " ; }
Agora s falta realmente criarmos o arquivo d a t a F i n a l i z a d ana pasta / W E B I N F / v i e w s / t a r e f ae formatar a data usandoa tag <fmt>.
< % @ t a g l i bu r i = " h t t p : / / j a v a . s u n . c o m / j s p / j s t l / f m t "p r e f i x = " f m t "% > < f m t : f o r m a t D a t ev a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } "p a t t e r n = " d d / M M / y y y y " / >
Legal, j renderizamos uma data formatada e por consequncia o status 2 0 0 enviado para o JQuery. S que at agora no fizemos nada com essa data que o JSP renderizou. Para que se pegue algo enviado pelo nosso servidor, a funo de
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 35/41
09/10/13
callback deve receber um parmetro com esse contedo. Vamos executar um a l e r t com esta varivel.
< s c r i p tt y p e = " t e x t / j a v a s c r i p t " > f u n c t i o nf i n a l i z a A g o r a ( i d ){ $ . p o s t ( " f i n a l i z a T a r e f a " ,{ ' i d ':i d } ,f u n c t i o n ( r e s p o s t a ){ $ ( " # t a r e f a _ " + i d ) . h t m l ( " F i n a l i z a d o " ) ; a l e r t ( r e s p o s t a ) ; } ) ; } < / s c r i p t >
A execuo desse a l e r tnos mostra a data, falta apenas inseri-la em lugar apropriado. Vamos usar a mesma estratgia que usamos para mudar de No Finalizado para Finalizado, atrelando um id a nossa < t d >referente ao campo de de data.
< t di d = " t a r e f a _ d a t a _ $ { t a r e f a . i d } " > < f m t : f o r m a t D a t ev a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } " p a t t e r n = " d d / M M / y y y y "/ > < / t d >
O nosso desafio foi cumprido de forma elegante, mas ainda assim poderamos melhorar o nosso cdigo. A funo de callback do AJAX tem que modificar dois < t d > 's e isso tornaria repetitivo para modelos com mais alteraes que a nossa T a r e f a . Sabendo que a funo recebe apenas um parmetro de resposta, teramos mais problemas ao ter que passar mais de um parmetro a ela. Como resolver esta questo? Uma soluo vivel passar a prpria < t r > , completa, com as alterao necessrias. Para isso uma alterao na JSP se faz necessria.
< % @ t a g l i bu r i = " h t t p : / / j a v a . s u n . c o m / j s p / j s t l / f m t "p r e f i x = " f m t "% >
< t d > $ { t a r e f a . i d } < / t d > < t d > $ { t a r e f a . d e s c r i c a o } < / t d > < t d > F i n a l i z a d a < / t d > < t d > < f m t : f o r m a t D a t ev a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } " p a t t e r n = " d d / M M / y y y y "/ >
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 36/41
09/10/13
< / t d > < t d > < ah r e f = " r e m o v e T a r e f a ? i d = $ { t a r e f a . i d } " > R e m o v e r < / a > < / t d > < t d > < ah r e f = " m o s t r a T a r e f a ? i d = $ { t a r e f a . i d } " > A l t e r a r < / a > < / t d >
Uma alterao no nome do aquivo d a t a F i n a l i z a d a . j s pseria mais do que recomendado, j que agora no possui apenas uma data e sim todas as alteraes de uma < t r > . Vamos renome-lo para f i n a l i z a d a . j s p . Sem esquecer de modificar o retorno da action de tarefa/dataFinalizada para tarefa/finalizada:
@ R e q u e s t M a p p i n g ( " f i n a l i z a T a r e f a " ) p u b l i cS t r i n gf i n a l i z a ( L o n gi d ,M o d e lm o d e l ){ . . . r e t u r n" t a r e f a / d a t a F i n a l i z a d a " ; }
Agora que retornamos uma < t r >com todas as alteraes vamos modificar a funo de callback, para que ela apenas modifique o contedo da < t r > correspondente a tarefa finalizada. Para isso preciso diferenciar um < t r >do outro. Vamos utilizar agora um id na prpria < t r >e removeremos os ids desnecessrios dos < t d > 's.
< t a b l e > . . . < c : f o r E a c hi t e m s = " $ { t a r e f a s } "v a r = " t a r e f a " > < t ri d = " t a r e f a _ $ { t a r e f a . i d } " > < t d > $ { t a r e f a . i d } < / t d > < t d > $ { t a r e f a . d e s c r i c a o } < / t d > < c : i ft e s t = " $ { t a r e f a . f i n a l i z a d oe qt r u e } " > < t d > F i n a l i z a d o < / t d > < / c : i f > < c : i ft e s t = " $ { t a r e f a . f i n a l i z a d oe qf a l s e } " > < t d > < ah r e f = " # "o n C l i c k = " f i n a l i z a A g o r a ( $ { t a r e f a . i d } ) " > F i n a l i z a r < / a > < / t d > < / c : i f > < t d > $ { t a r e f a . p r i o r i d a d e } < / t d > < t d > < f m t : f o r m a t D a t e v a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } " p a t t e r n = " d d / M M / y y y y "/ > < / t d > < t d > < ah r e f = " r e m o v e T a r e f a ? i d = $ { t a r e f a . i d } " > R e m o v e r < / a > < / t d > < t d > < ah r e f = " m o s t r a T a r e f a ? i d = $ { t a r e f a . i d } " > A l t e r a r < / a > < / t d >
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
37/41
09/10/13
E por ltimo, falta mudar a funo de callback para que esta modifique o contedo do < t r > .
. . . $ . p o s t ( " f i n a l i z a T a r e f a " ,{ ' i d ':i d } ,f u n c t i o n ( r e s p o s t a ){ $ ( " # t a r e f a _ " + i d ) . h t m l ( r e s p o s t a ) ; } ) ; . . .
Agora sim, temos um cdigo simples e fcil de manter. Tudo o que um bom programador gostaria de encontrar. [section Exerccios Opcionais: Melhorando nosso AJAX] 1. Vamos buscar uma tarefa e pass-la para nossa JSP atravs do Model. Abra o T a r e f a s C o n t r o l l e r . j a v ae modifique a action que finaliza uma tarefa para o que segue:
@ R e q u e s t M a p p i n g ( " f i n a l i z a T a r e f a " ) p u b l i cS t r i n gf i n a l i z a ( L o n gi d ,M o d e lm o d e l ){ J d b c T a r e f a D a od a o=n e wJ d b c T a r e f a D a o ( ) ; d a o . f i n a l i z a ( i d ) ; m o d e l . a d d A t t r i b u t e ( " t a r e f a " ,d a o . b u s c a P o r I d ( i d ) ) ; r e t u r n" t a r e f a / f i n a l i z a d a " ; }
2. Agora falta criarmos o arquivo f i n a l i z a d a . j s pdentro do diretrio: / W E B I N F / v i e w s / t a r e f a / . Que dever ter o seguinte contedo da <tr> realacionada a tarefa finalizada.
< % @ t a g l i bu r i = " h t t p : / / j a v a . s u n . c o m / j s p / j s t l / f m t "p r e f i x = " f m t " % >
< t d > $ { t a r e f a . i d } < / t d > < t d > $ { t a r e f a . d e s c r i c a o } < / t d > < t d > F i n a l i z a d a < / t d > < t d > < f m t : f o r m a t D a t ev a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } " p a t t e r n = " d d / M M / y y y y "/ > < / t d > < t d > < ah r e f = " r e m o v e T a r e f a ? i d = $ { t a r e f a . i d } " > R e m o v e r < / a > < / t d > < t d > < ah r e f = " m o s t r a T a r e f a ? i d = $ { t a r e f a . i d } " > A l t e r a r < / a > < / t d >
3. Por ltimo devemos modificar o arquivo t a r e f a / l i s t a . j s ppara que ele tenha um identificador de cada linha, ou seja, elemento <tr> da tabela. De maneira anloga ao que foi feito no exerccio anterior vamos concatenar com o i dda tarefa
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 38/41
09/10/13
um valor de t a r e f a _ . Lembre-se de remover os ids dos outros <td>'s j que eles no sero necessrios e podem estar com o mesmo nome do identificador da <tr>.
. . . . < c : f o r E a c hi t e m s = " $ { t a r e f a s } "v a r = " t a r e f a " > < t ri d = " t a r e f a _ $ { t a r e f a . i d } " > < t d > $ { t a r e f a . i d } < / t d > < t d > $ { t a r e f a . d e s c r i c a o } < / t d > < c : i ft e s t = " $ { t a r e f a . f i n a l i z a d oe qt r u e } " > < t d > F i n a l i z a d o < / t d > < / c : i f > < c : i ft e s t = " $ { t a r e f a . f i n a l i z a d oe qf a l s e } " > < t d> < ah r e f = " # "o n C l i c k = " f i n a l i z a A g o r a ( $ { t a r e f a . i d } ) " > F i n a l i z a r < / a > < / t d > < / c : i f > < t d > $ { t a r e f a . p r i o r i d a d e } < / t d > < t d > < f m t : f o r m a t D a t e v a l u e = " $ { t a r e f a . d a t a F i n a l i z a c a o . t i m e } " p a t t e r n = " d d / M M / y y y y "/ > < / t d > . . . . < / t r > . . . . .
4. E agora para fazer uso do contedo renderizado pela JSP, necessrio que a funo de callback do AJAX receba como parmetro esse contedo. Vamos alterar a funo do f i n a l i z a A g o r ano mesmo arquivo l i s t a . j s p , para o que segue:
< s c r i p tt y p e = " t e x t / j a v a s c r i p t " > f u n c t i o nf i n a l i z a A g o r a ( i d ){ $ . p o s t ( " f i n a l i z a T a r e f a " ,{ ' i d ':i d } ,f u n c t i o n ( r e s p o s t a ){ $ ( " # t a r e f a _ " + i d ) . h t m l ( r e s p o s t a ) ; } ) ; } < / s c r i p t >
5. Reinicie o servidor e verifique que agora ao clicar no link F i n a l i z a ro usurio tem a alterao tanto de No Finalizada para Finalizada quando uma mudana na data de finalizao.
CAPTULO ANTERIOR:
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc 39/41
09/10/13
Blog Caelum
Cursos Online
Newsletter
Casa do Cdigo
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
40/41
09/10/13
www.caelum.com.br/apostila-java-web/spring-mvc/#11-1-porque-precisamos-de-frameworks-mvc
41/41