Spring Framework. Parte 03 Spring MVC

Documentos relacionados
Spring Framework. Parte 05 Spring Security

Spring Framework. Parte 04 transações

Spring Framework. Parte 02 acesso a dados e testes de integração

Spring Framework. Parte 01 introdução e primeiros passos

PROJETO ECLIPSE: Estrutura do projeto: (Dynamic Web Project) LIBS: Java WebDeveloper. Prof. Edson Belém

SPRING - VALIDAÇÃO. Altere o arquivo formulario.jsp como segue:

PROJETO WEB: Java. Prof Fernando Gomes

Lista de exercícios I - RESPOSTAS Servlets e banco de dados

Desenvolvimento Web com Java. Sérgio Lopes Caelum -

HTML BÁSICO E TEMPLATE VIEW. Gabrielle Amorim Porto

O que faz um servidor/navegador web? 14/03/2016 Rômulo da Silva Lima Slid e 2

2 Criar uma Enterprise Application que num módulo EJB irá conter um ou vários Beans.

TUTORIAL INTEGRAÇÃO SPRING, HIBERNATE E MYSQL

Tutorial Jogo da Velha WEB

COM222 DESENVOLVIMENTO DE SISTEMAS WEB. Aula 01: HTML e CSS

Java para WEB com Struts 2 e Hibernate

Primeiros Passos com Spring MVC por Normandes Junior

Table of Contents

Programação para Internet II

PLATAFORMA SIGA RIO DAS VELHAS MANUAL DO CÓDIGO FONTE

JSP Standard Tag Library (JSTL)

JSP (JAVASERVER PAGES)

EXERCÍCIOS DE REVISÃO DE CONTEÚDO QUESTÕES DISSERTATIVAS

Desenvolvimento para Web em Java. Profa Andréa Schwertner Charão DLSC/CT/UFSM Lamarck Heinsch Mestrando PPGI/CT/UFSM

JSP Standard Tag Library (JSTL)

AJAX. Prof. Marcos Alexandruk

Construindo um sistema simples de cadastro de fornecedores em PHP e MySQL.

Programação para web HTML: Formulários

REST. Representational State Transfer. É um estilo arquitetural usado por muitas aplicações Web para estender as suas funcionalidades.

Mapeando Relacionamentos Entre Classes com Anotações Hibernate Por: Raphaela Galhardo Fernandes Gleydson de Azevedo F. Lima

PROJETOS EXEMPLO DE ASP.NET MVC

Desenvolvimento de Aplicações para Internet

Uploadde arquivos com o método POST

Desenvolvimento de Aplicações Web. Prof. José Eduardo A. de O. Teixeira / j.edu@vqv.com.br

JSP e Servlet Princípio de MVC

Trabalhando com Servlet

Tutorial 1 Configuração Apache Tomcat no NetBeans 8.0 (passo a passo)

A composição de uma Java Server Pages (Diretivas, Elementos de Script e Objetos Implícitos)

Java Server Pages (JSP)

Aplicação MVC com Class Library

Desenvolvimento de Aplicações para Internet Aula 5

Java Server Pages (Diretivas, Elementos de Script e Objetos Implícitos)

Vamos falar de Hibernate?

Sessão e inclusão de arquivos no PHP

Introdução ao Javascript

Tutorial Cold Fusion Módulo 2 Cold Fusion Brasil -

Desenvolvimento Web TCC Turma A-1

Web Services REST JAX-RS

Introdução à linguagem HTML. Volnys Borges Bernal

O que fazer ao receber o Caso de Uso NOMEDAENTIDADE CRUD?

API - Lista de Compras

TUTORIAL DE INTRODUÇÃO AO CEWOLF

Desenvolvimento de Aplicações para Internet Aula 11

Enums em Java: utilização e persistência

Java: Linguagem de programação (OOP) JavaScipt: Linguagem de scripts (OOP)

A figura acima mostra o script de criação do banco de dados que chamaremos de minicurso.

Programação para Internet

Recursos Complementares (Tabelas e Formulários)

Construção de Sites 2. Prof. Christiano Lima Santos

Bem vindos ao Curso de ASP.NET MVC 3 Razor e C#

Managed Beans e Tags JSF

DESENVOLVIMENTO DE SISTEMAS WEB. Lista de Exercícios AV2-01. Luiz Leão

Linguagem de Programação II Implementação

TAGS. O HTML trabalha com o sistema de tags (etiquetas). Esse sistema funciona da seguinte maneira. <tag>conteúdo da tag</tag>

22/05/2012 CRIANDO UM PROJETO COM TELAS ESTRUTURA DA APLICAÇÃO LOGIN BANCO DE DADOS TAREFAS PHP MYSQL PARTE 2

1. Fazer aplicação exemplo

Retrofit. Criar um novo projeto. Selecionar a API. Retrofit para consumir Web Service Luiz Eduardo Guarino de Vasconcelos

Utilizando Swing com Hibernate

Programação para Dispositivos Móveis

Desenvolvimento Web XHTML Formulários. Prof. Bruno E. G. Gomes

Volnys Bernal. Introdução à linguagem HTML. Introdução à linguagem HTML. Visão geral. Visão geral. Visão geral. Visão geral.

Tutorial Hibernate + Vraptor para projetos Restful.

Transcrição:

Spring Framework Parte 03 Spring MVC

Spring MVC Módulo do Spring Framework que permite o desenvolvimento de aplicações web baseadas em ações (action based) bem como o desenvolvimento de serviços REST. Integra-se à API de Servlets. Suporta: Diversas tecnologias de visão tais como JSP/JSTL, Velocity, FreeMarker, Thymeleaf, Tiles, XSLT e Groovy Markup Templates. Processamento assíncrono. Internacionalização. Oferece funcionalidades de segurança e de testes. 2

Padrão front controller 2: HTTP request Handler mapping 3: Web controller 1: HTTP request 10: HTTP Response Dispatcher Servlet 4: HTTP request 5: model and view name Web controller 9: HTTP Response View 8: model 7: view 6: view name View resolver 3

Controlador web Objeto responsável por responder um conjunto de requisições HTTP. As requisições atendíveis podem ser especificadas através de padrões de URL, por cabeçalhos HTTP e por métodos HTTP. 4

Anotações e classes @Controller: define um controlador web. @RequestMapping: definições das requisições HTTP a serem atendidas. @RequestParam: define um parâmetro query string. @PathVariable: referencia parâmetros em URLs estilo REST. org.springframework.ui.model: para armazenar objetos acessados pela view. org.springframework.web.servlet.modelandview: para armazenar o nome da view e objetos acessados pela view. 5

Atualizando as configurações Adicionar JSTL como dependência no pom.xml: <dependency> <groupid>javax.servlet</groupid> <artifactid>jstl</artifactid> </dependency> 6

Atualizando as configurações Disponibilizando o contexto do Spring para o contexto da aplicação web: public class SpringMVCServlet extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getrootconfigclasses() { return new Class[]{AppConfig.class; 7

CRUD Fabricante: listagem Controlador web (1): package cursospring.revenda_veiculos.web; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.controller; import org.springframework.ui.model; import org.springframework.web.bind.annotation.requestmapping; import cursospring.revenda_veiculos.dominio.fabricanterepository; @Controller @RequestMapping("/fabricantes") public class CRUDFabricante { @Autowired private FabricanteRepository repositorio; 8

CRUD Fabricante: listagem Controlador web (2): @RequestMapping public String inicio(model model){ model.addattribute("fabricantes", repositorio.todos()); return "fabricantes/inicio"; 9

CRUD Fabricante: listagem Controlador web (2): @RequestMapping public String inicio(model model){ model.addattribute("fabricantes", repositorio.todos()); return "fabricantes/inicio"; Visão (página) a ser renderizada com os dados inseridos em model. 10

CRUD Fabricante: listagem Página src/main/webapp/web- INF/views/fabricantes/inicio.jsp (1): <%@ page language="java" contenttype="text/html; charset=iso-8859-1" pageencoding="iso-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <title>fabricantes</title> </head> <body> <h2>fabricantes</h2> <table> <tr> <th>fabricante</th> <th colspan="2">opções</th> </tr> 11

CRUD Fabricante: listagem Página src/main/webapp/web- INF/views/fabricantes/inicio.jsp (2): <c:foreach var="fabricante" items="${fabricantes"> <tr> <td>${fabricante.descricao</td> <td> EXCLUIR </td> <td> ALTERAR </td> </tr> </c:foreach> </table> </body> </html> 12

CRUD Fabricante: exclusão Controlador web (1): import org.springframework.web.bind.annotation.requestparam; @Controller @RequestMapping("/fabricantes") public class CRUDFabricante { 13

CRUD Fabricante: exclusão Controlador web (2): @RequestMapping("/excluir") public String excluir(@requestparam("id") Integer idfabricante, Model model){ try{ repositorio.excluir(idfabricante); model.addattribute("mensagem", "Fabricante excluído com sucesso."); catch(exception ex){ ex.printstacktrace(); model.addattribute("mensagem", "Ocorreu um erro durante a operação."); return "forward:/fabricantes"; 14

CRUD Fabricante: exclusão Controlador web (2): @RequestMapping("/excluir") public String excluir(@requestparam("id") Integer idfabricante, Model model){ try{ repositorio.excluir(idfabricante); model.addattribute("mensagem", "Fabricante excluído com sucesso."); catch(exception ex){ ex.printstacktrace(); model.addattribute("mensagem", return "forward:/fabricantes"; Como queremos voltar à listagem "Ocorreu um erro durante de fabricantes a operação."); após a exclusão, aproveitamos o método inicio realizando um forward para a URL /fabricantes. 15

CRUD Fabricante: exclusão fabricante/inicio.jsp: <h2>fabricantes</h2> <c:url var="actionurl" value="/fabricantes" /> <c:if test="${not empty mensagem"> <p style="border: 1px solid black;">${mensagem</p> </c:if> <table> <td>${fabricante.descricao</td> <td> <a href="${actionurl/excluir?id=${fabricante.id"> EXCLUIR </a> </td> 16

Forward e Redirect É comum que após processar uma requisição o controlador web direcione o fluxo da aplicação para uma página diferente da utilizada na submissão. Temos duas formas disponíveis: forward e redirect. Diferença básica: No forward o processamento é realizado no servidor. No redirect a mudança de página é feita pelo browser. 17

Forward As mudanças de URL são todas processadas no servidor antes da resposta ser enviada ao cliente. Por haver apenas uma requisição, o mesmo contexto de requisição é utilizado pelas páginas e métodos envolvidos no processamento. O mesmo model fica disponível a todos os métodos Java. Ao final do processamento da requisição, a URL na barra de endereços do navegador não muda. Assim, o reload da página resultante irá executar a requisição original. 18

Forward 19

Redirect É um mecanismo especificado pelo HTTP. Dois passos. Ao receber uma requisição, a aplicação pede ao browser para acessar uma segunda URL. Por isso a URL na barra de endereços muda. O pedido é um recurso do HTTP: código 301 ou 302 e cabeçalho Location. O reload de página não repetirá a requisição original, mas sim a segunda URL. Como acontecem duas requisições, os dados da primeira requisição, não estarão disponíveis no contexto da segunda requisição. Um model diferente por método Java. 20

Redirect 21

Flash scope Utilizado para manter dados que devem estar disponíveis após um redirect. Para utilizar o flash scope basta declarar um parâmetro do tipo RedirectAttributes. 22

CRUD Fabricante: exclusão com redirect Controlador web (1): import org.springframework.web.servlet.mvc.support.redirectattributes; public class CRUDFabricante { 23

CRUD Fabricante: exclusão com redirect Controlador web (2): @RequestMapping("/excluir") public String excluir(@requestparam("id") Integer idfabricante, RedirectAttributes redattr){ try{ repositorio.excluir(idfabricante); redattr.addflashattribute("mensagem", "Fabricante excluído com sucesso."); catch(exception ex){ ex.printstacktrace(); redattr.addflashattribute("mensagem", "Ocorreu um erro durante a operação."); return "redirect:/fabricantes"; 24

CRUD Fabricante: novo registro Atualizando pom.xml com bean validation: <dependency> <groupid>javax.validation</groupid> <artifactid>validation-api</artifactid> </dependency> <dependency> <groupid>org.hibernate</groupid> <artifactid>hibernate-validator</artifactid> </dependency> 25

CRUD Fabricante: novo registro Decorando Fabricante com anotações da bean validation: import javax.validation.constraints.notnull; import javax.validation.constraints.size; @Entity @Table(name="FABRICANTES") public class Fabricante extends Entidade{ @NotNull @Size(min=2) private String descricao; 26

CRUD Fabricante: novo registro inicio.jsp link para um novo registro: <h2>fabricantes</h2> <c:url var="actionurl" value="/fabricantes" /> <c:if test="${not empty mensagem"> <p style="border: 1px solid black;">${mensagem</p> </c:if> <a href="${actionurl/novo">novo fabricante</a> <table> 27

CRUD Fabricante: novo registro Controlador web método novo: import org.springframework.web.servlet.modelandview; import cursospring.revenda_veiculos.dominio.fabricante; @RequestMapping("/novo") public ModelAndView novo(){ ModelAndView modelandview = new ModelAndView("fabricantes/edicao"); modelandview.addobject("fabricante", new Fabricante()); modelandview.addobject("titulo", "Novo Fabricante"); return modelandview; 28

CRUD Fabricante: novo registro Controlador web método novo: import org.springframework.web.servlet.modelandview; import cursospring.revenda_veiculos.dominio.fabricante; @RequestMapping("/novo") public ModelAndView novo(){ ModelAndView modelandview = new ModelAndView("fabricantes/edicao"); modelandview.addobject("fabricante", new Fabricante()); modelandview.addobject("titulo", "Novo Fabricante"); return modelandview; O objeto fabricante será utilizado para receber os valores do campos do formulário. 29

CRUD Fabricante: novo registro Controlador web método novo: import org.springframework.web.servlet.modelandview; import cursospring.revenda_veiculos.dominio.fabricante; @RequestMapping("/novo") public ModelAndView novo(){ ModelAndView modelandview = new ModelAndView("fabricantes/edicao"); modelandview.addobject("fabricante", new Fabricante()); modelandview.addobject("titulo", "Novo Fabricante"); return modelandview; É informado o título da página pois a mesma página será utilizada nas operações de novo fabricante e edição de fabricante. 30

CRUD Fabricante: novo registro Página edicao.jsp (1): <%@ page language="java" contenttype="text/html; charset=iso-8859-1" pageencoding="iso-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <!DOCTYPE html> <html> <head> <title>${titulo</title> </head> <body> <h2>${titulo</h2> <c:url var="actionurl" value="/fabricantes/salvar" /> 31

CRUD Fabricante: novo registro Página edicao.jsp (1): <%@ page language="java" contenttype="text/html; charset=iso-8859-1" pageencoding="iso-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <!DOCTYPE html> <html> <head> <title>${titulo</title> Biblioteca de tags Spring para </head> manipulação de formulários. <body> <h2>${titulo</h2> <c:url var="actionurl" value="/fabricantes/salvar" /> 32

CRUD Fabricante: novo registro Página edicao.jsp (2): <form:form action="${actionurl" method="post" modelattribute="fabricante"> <label for="descricao">descrição</label> <form:input path="descricao"/> <form:errors path="descricao" cssstyle="color: red"/> <form:hidden path="id"/> <input type="hidden" name="titulo" value="${titulo"> <br> <button type="submit">salvar</button> </form:form> </body> </html> 33

CRUD Fabricante: novo registro Página edicao.jsp (2): <form:form action="${actionurl" method="post" modelattribute="fabricante"> <label for="descricao">descrição</label> <form:input path="descricao"/> <form:errors path="descricao" cssstyle="color: red"/> <form:hidden path="id"/> <input type="hidden" name="titulo" value="${titulo"> <br> <button type="submit">salvar</button> </form:form> </body> </html> Define o identificador do objeto que será utilizado (binding) para receber/preencher os campos do formulário. O objeto será inserido no contexto do model. Note que este é o identificador a ser utilizado no controlador para acessar os campos do formulário. 34

CRUD Fabricante: novo registro Controlador web método salvar (1): import javax.validation.valid; import org.springframework.validation.bindingresult; import org.springframework.web.bind.annotation.modelattribute; import org.springframework.web.bind.annotation.requestmethod; @RequestMapping(value="/salvar", method=requestmethod.post) public String salvar( @Valid @ModelAttribute("fabricante") Fabricante fabricante, BindingResult br, @RequestParam("titulo") String titulo, Model model, RedirectAttributes rattrs){ if(br.haserrors()){ model.addattribute("titulo", titulo); return "fabricantes/edicao"; 35

CRUD Fabricante: novo registro Indica Controlador que os atributos web do método salvar (1): Indica que o spring deve injetar um objeto import objeto org.springframework.validation.bindingresult; devem ser validados presente no contexto do model e que é import segundo org.springframework.web.bind.annotation.modelattribute; as anotações da identificado pela string fabricante. Na import Bean org.springframework.web.bind.annotation.requestmethod; Validation. página, usamos o mesmo identificador. @RequestMapping(value="/salvar", method=requestmethod.post) public String salvar( @Valid @ModelAttribute("fabricante") Fabricante fabricante, BindingResult br, @RequestParam("titulo") String titulo, Model model, RedirectAttributes rattrs){ if(br.haserrors()){ model.addattribute("titulo", titulo); return "fabricantes/edicao"; Armazena o resultado da validação. 36

CRUD Fabricante: novo registro Controlador web método salvar (2): try{ if(fabricante.getid() == null) repositorio.inserir(fabricante); else repositorio.atualizar(fabricante); rattrs.addflashattribute("mensagem", "Fabricante salvo com sucesso."); catch(exception ex){ ex.printstacktrace(); rattrs.addflashattribute("mensagem", "Ocorreu um erro durante a operação."); return "redirect:/fabricantes"; 37

CRUD Fabricante: alterar registro inicio.jsp link de edição: <td> <a href="${actionurl/editar/${fabricante.id"> ALTERAR </a> </td> 38

CRUD Fabricante: alterar registro Controlador web: import org.springframework.web.bind.annotation.pathvariable; @RequestMapping("/editar/{id") public String editar(@pathvariable Integer id, Model model){ Fabricante f = repositorio.getporid(id); if(f == null) return "forward:/fabricantes"; model.addattribute("fabricante", f); model.addattribute("titulo", "Alterar Fabricante"); return "fabricantes/edicao"; 39

Outras tags Spring para formulários checkbox: produz um campo input do tipo checkbox. Pode ser associada a atributos com um ou muitos valores (coleções e arrays). Quando seu valor não é indicado, é assumido o tipo boolean. checkboxes: gera vários campos do tipo checkbox a partir de uma coleção. radiobutton: produz uma tag input do tipo radio. radiobuttons: gera um conjunto relacionado de radio buttons a partir de uma coleção. password: gera uma tag input do tipo password. option: gera uma tag option para um campo select. options: opções de um campo select gerados a partir de uma coleção. textarea: produz uma tag textarea. 40

CRUD Veículo Classe Foto: package cursospring.revenda_veiculos.dominio; import javax.persistence.embeddable; @Embeddable public class Foto { @Basic(fetch=FetchType.LAZY) private byte[] bytes; private String mimetype; public Foto() { public Foto(byte[] bytes, String mimetype) { this.bytes = bytes; this.mimetype = mimetype; //getters e setters 41

CRUD Veículo Classe Veiculo (1): package cursospring.revenda_veiculos.dominio; import javax.persistence.basic; import javax.persistence.embedded; import javax.persistence.entity; import javax.persistence.fetchtype; import javax.persistence.joincolumn; import javax.persistence.manytoone; import javax.persistence.table; import javax.validation.constraints.min; import javax.validation.constraints.notnull; import javax.validation.constraints.pattern; @Entity @Table(name="VEICULOS") public class Veiculo extends Entidade { 42

CRUD Veículo Classe Veiculo (2): @Min(1900) @NotNull private Integer anofabricacao; @Pattern(regexp="[A-Z]{3\\d{4") @NotNull private String placa; private String chassi; @Embedded private Foto foto; @Min(50) private Integer cilindradas; 43

CRUD Veículo Classe Veiculo (3): @NotNull @ManyToOne @JoinColumn(name="ID_MODELO") private Modelo modelo; public Veiculo() { public Veiculo(Integer id, String placa){ super(id); this.placa = placa; 44

CRUD Veículo Classe Veiculo (4): public String getmimetypefoto() { if(foto!= null) return foto.getmimetype(); return null; //getters e setters 45

CRUD Veículo create-schema.sql: create table VEICULOS (ID int auto_increment, ANOFABRICACAO int not null, PLACA varchar(10) not null, CHASSI varchar(50), CILINDRADAS int, BYTES blob, MIMETYPE varchar(50), ID_MODELO int not null, primary key(id), foreign key(id_modelo) references MODELOS); drop-schema.sql: drop table VEICULOS; 46

CRUD Veículo Interface VeiculoRepositorio: package cursospring.revenda_veiculos.dominio; import java.util.list; public interface VeiculoRepositorio { public Integer inserir(veiculo v); public void excluir(integer id); public List<Veiculo> todos(); public Veiculo getporid(integer id); public Foto getfoto(integer idveiculo); 47

CRUD Veículo Classe VeiculoDAO (1): package cursospring.revenda_veiculos.dao; import java.util.list; import org.hibernate.query; import org.hibernate.session; import org.hibernate.sessionfactory; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.repository; import org.springframework.transaction.annotation.transactional; import cursospring.revenda_veiculos.dominio.foto; import cursospring.revenda_veiculos.dominio.veiculo; import cursospring.revenda_veiculos.dominio.veiculorepositorio; @Repository @Transactional public class VeiculoDAO implements VeiculoRepositorio { 48

CRUD Veículo Classe VeiculoDAO (2): @Autowired private SessionFactory sessionfactory; @Override public Integer inserir(veiculo v) { sessionfactory.getcurrentsession().save(v); return v.getid(); @Override public void excluir(integer id) { String hql = "delete Veiculo where id = :idveiculo"; Session session = sessionfactory.getcurrentsession(); Query q = session.createquery(hql). setparameter("idveiculo", id); q.executeupdate(); 49

CRUD Veículo Classe VeiculoDAO (3): @Override public List<Veiculo> todos() { Session session = sessionfactory.getcurrentsession(); return session.createquery("from Veiculo").list(); @Override public Veiculo getporid(integer id) { Session session = sessionfactory.getcurrentsession(); return (Veiculo)session.get(Veiculo.class, id); 50

CRUD Veículo Classe VeiculoDAO (4): @Override public Foto getfoto(integer idveiculo) { String hql = "select v.foto from Veiculo v where v.id = :id "; Session session = sessionfactory.getcurrentsession(); Query q = session.createquery(hql). setparameter("id", idveiculo); return (Foto)q.uniqueResult(); 51

CRUD Veículo Página veiculos/inicio.jsp (1): <%@ page language="java" contenttype="text/html; charset=iso-8859-1" pageencoding="iso-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <title>veículos</title> </head> <body> <h2>veículos</h2> <c:url var="actionurl" value="/veiculos" /> <c:if test="${not empty mensagem"> <p style="border: 1px solid black;">${mensagem</p> </c:if> <a href="${actionurl/novo">novo veículo</a> 52

CRUD Veículo Página veiculos/inicio.jsp (2): <table> <tr> <th>placa</th> <th>fabricante</th> <th>modelo</th> <th>ano</th> <th>cilindradas</th> <th colspan="2">opções</th> </tr> <c:foreach var="veiculo" items="${veiculos"> <tr> <td>${veiculo.placa</td> <td>${veiculo.modelo.fabricante.descricao</td> <td>${veiculo.modelo.descricao</td> <td>${veiculo.anofabricacao</td> <td>${veiculo.cilindradas</td> 53

CRUD Veículo Página veiculos/inicio.jsp (3): <td> <a href="${actionurl/excluir/${veiculo.id"> EXCLUIR </a> </td> </tr> </c:foreach> </table> </body> </html> 54

CRUD Veículo Página veiculos/edicao.jsp (1): <%@ page language="java" contenttype="text/html; charset=iso-8859-1" pageencoding="iso-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <!DOCTYPE html> <html> <head> <title>novo veículo</title> </head> <body> <h2>novo veículo</h2> <c:url var="actionurl" value="/veiculos/salvar" /> <form:form action="${actionurl" method="post" modelattribute="veiculo" > 55

CRUD Veículo Página veiculos/edicao.jsp (2): <label for="placa">placa</label> <form:input path="placa"/>* <form:errors path="placa" cssstyle="color: red"/><br> <label for="anofabricacao">ano</label> <form:input path="anofabricacao"/>* <form:errors path="anofabricacao" cssstyle="color: red"/><br> <label for="cilindradas">cilindradas</label> <form:input path="cilindradas"/> <form:errors path="cilindradas" cssstyle="color: red"/><br> <label for="chassi">chassi</label> <form:input path="chassi"/> <form:errors path="chassi" cssstyle="color: red"/><br> 56

CRUD Veículo Página veiculos/edicao.jsp (3): <label for="selectmodelo">modelo</label> <form:select path="modelo.id" id="selectmodelo" > <form:options items="${modelos" itemvalue="id" itemlabel="descricao" /> </form:select> <form:errors path="modelo" cssstyle="color: red"/><br> <button type="submit">salvar</button> </form:form> </body> </html> 57

CRUD Veículo Classe CRUDVeiculo (1): package cursospring.revenda_veiculos.web; import java.util.list; import javax.validation.valid; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.controller; import org.springframework.ui.model; import org.springframework.validation.bindingresult; import org.springframework.web.bind.annotation.modelattribute; import org.springframework.web.bind.annotation.pathvariable; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.requestmethod; import org.springframework.web.servlet.modelandview; import org.springframework.web.servlet.mvc.support.redirectattributes; import cursospring.revenda_veiculos.dominio.modelo; import cursospring.revenda_veiculos.dominio.modelorepository; 58

CRUD Veículo Classe CRUDVeiculo (2): import cursospring.revenda_veiculos.dominio.veiculo; import cursospring.revenda_veiculos.dominio.veiculorepositorio; @Controller @RequestMapping("/veiculos") public class CRUDVeiculo { @Autowired private VeiculoRepositorio veiculorepositorio; @Autowired private ModeloRepository modelorepositorio; @ModelAttribute("modelos") public List<Modelo> listademodelos(){ return modelorepositorio.todos(); 59

CRUD Veículo Classe CRUDVeiculo (2): import cursospring.revenda_veiculos.dominio.veiculo; import cursospring.revenda_veiculos.dominio.veiculorepositorio; @Controller @RequestMapping("/veiculos") public class CRUDVeiculo { @ModelAttribute insere o @Autowired retorno do método no private VeiculoRepositorio veiculorepositorio; contexto model. Assim, a lista @Autowired de modelos ficará disponível private ModeloRepository modelorepositorio; para as páginas acessadas através deste controlador. @ModelAttribute("modelos") public List<Modelo> listademodelos(){ return modelorepositorio.todos(); 60

CRUD Veículo Classe CRUDVeiculo (3): @RequestMapping public ModelAndView inicio(){ ModelAndView modelandview = new ModelAndView("veiculos/inicio"); modelandview.addobject("veiculos", veiculorepositorio.todos()); return modelandview; @RequestMapping("/novo") public ModelAndView novo(){ ModelAndView modelandview = new ModelAndView("veiculos/edicao"); modelandview.addobject("veiculo", new Veiculo()); return modelandview; 61

CRUD Veículo Classe CRUDVeiculo (4): @RequestMapping(value="/salvar", method=requestmethod.post) public String salvar(@valid @ModelAttribute("veiculo") Veiculo veiculo, BindingResult br, Model model, RedirectAttributes rattrs){ if(br.haserrors()){ return "veiculos/edicao"; try{ veiculorepositorio.inserir(veiculo); rattrs.addflashattribute("mensagem", "Veículo salvo com sucesso."); catch(exception ex){ ex.printstacktrace(); rattrs.addflashattribute("mensagem", "Ocorreu um erro durante a operação."); return "redirect:/veiculos"; 62

CRUD Veículo Classe CRUDVeiculo (5): @RequestMapping("/excluir/{id") public String excluir(@pathvariable Integer id, RedirectAttributes redattr){ try{ veiculorepositorio.excluir(id); redattr.addflashattribute("mensagem", "Veículo excluído com sucesso."); catch(exception ex){ ex.printstacktrace(); redattr.addflashattribute("mensagem", "Ocorreu um erro durante a operação."); return "redirect:/veiculos"; 63

CRUD Veículo Classe ModeloDAO: import org.springframework.transaction.annotation.transactional; @Repository @Transactional public class ModeloDAO implements ModeloRepository { 64

CRUD Veículo: upload da foto Dependência para upload de arquivos: <dependency> <groupid>commons-fileupload</groupid> <artifactid>commons-fileupload</artifactid> </dependency> 65

CRUD Veículo: upload da foto Classe AppConfig adição do bean gerenciador de uploads: import org.springframework.web.multipart.commons.commonsmultipartresolver; @Bean public CommonsMultipartResolver multipartresolver(){ CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setmaxuploadsize(1024 * 1024 * 5); resolver.setmaxinmemorysize(1024 * 1024 * 5); return resolver; 66

CRUD Veículo: upload da foto Página veiculos/edicao.jsp: <form:form action="${actionurl" method="post" modelattribute="veiculo" enctype="multipart/form-data"> <label for="arquivofoto">foto</label> <input type="file" name="arquivofoto" accept="image/*"/> <button type="submit">salvar</button> </form:form> 67

CRUD Veículo: upload da foto CRUDVeiculo atualização do método salvar (1): @RequestMapping(value="/salvar", method=requestmethod.post) public String salvar(@valid @ModelAttribute("veiculo") Veiculo veiculo, BindingResult br, Model model, RedirectAttributes rattrs, @RequestParam("arquivoFoto") MultipartFile file){ if(br.haserrors()){ return "veiculos/edicao"; try{ if(file!= null){ Foto foto = new Foto(file.getBytes(), file.getcontenttype()); veiculo.setfoto(foto); 68

CRUD Veículo: upload da foto CRUDVeiculo atualização do método salvar (1): @RequestMapping(value="/salvar", method=requestmethod.post) public String salvar(@valid @ModelAttribute("veiculo") Veiculo veiculo, BindingResult br, Model model, RedirectAttributes rattrs, @RequestParam("arquivoFoto") MultipartFile file){ if(br.haserrors()){ return "veiculos/edicao"; try{ Será preenchido com o arquivo if(file!= null){ submetido. Note que a string Foto foto = new Foto(file.getBytes(), arquivofoto corresponde ao nome file.getcontenttype()); dado ao campo presente no veiculo.setfoto(foto); formulário de submissão. 69

CRUD Veículo: upload da foto CRUDVeiculo atualização do método salvar (2): veiculorepositorio.inserir(veiculo); rattrs.addflashattribute("mensagem", "Veículo salvo com sucesso."); catch(exception ex){ ex.printstacktrace(); rattrs.addflashattribute("mensagem", "Ocorreu um erro durante a operação."); return "redirect:/veiculos"; 70

CRUD Veículo: acessando a foto com Ajax veiculos/inicio.jsp (1): <head> <c:url var="actionurl" value="/veiculos" /> <title>veículos</title> <script src="http://code.jquery.com/jquery-1.11.3.min.js"> </script> <script src="http://code.jquery.com/ui/1.11.4/jquery-ui.min.js"> </script> <script> $(function() { $("#dialogfoto").dialog({ autoopen: false ); ); 71

CRUD Veículo: acessando a foto com Ajax veiculos/inicio.jsp (1): <head> <c:url var="actionurl" value="/veiculos" /> <title>veículos</title> <script src="http://code.jquery.com/jquery-1.11.3.min.js"> </script> <script src="http://code.jquery.com/ui/1.11.4/jquery-ui.min.js"> </script> <script> $(function() { $("#dialogfoto").dialog({ autoopen: false ); ); Esta instrução foi movida para o início da tag head para que a URL já esteja disponível aos scripts em JS. 72

CRUD Veículo: acessando a foto com Ajax veiculos/inicio.jsp (2): function verfoto(idveiculo){ var imgurl = '${actionurl/foto/'+idveiculo; $('#imgfoto').attr('src', imgurl); $('#dialogfoto').dialog("open"); </script> </head> 73

CRUD Veículo: acessando a foto com Ajax veiculos/inicio.jsp (3): <td>${veiculo.cilindradas</td> <td> <c:choose> <c:when test="${not empty veiculo.foto"> <a href="#" onclick="verfoto(${veiculo.id)"> VER FOTO </a> </c:when> <c:otherwise> -- </c:otherwise> </c:choose> </td> 74

CRUD Veículo: acessando a foto com Ajax veiculos/inicio.jsp (4): </table> <div id="dialogfoto" title="foto" style="border: 1px black solid;"> <img id="imgfoto"> </div> </body> 75

CRUD Veículo: acessando a foto com Ajax CRUDVeiculo método foto: @RequestMapping("/foto/{id") public ResponseEntity<byte[]> foto(@pathvariable Integer id){ Foto foto = veiculorepositorio.getfoto(id); HttpHeaders headers = new HttpHeaders(); String[] tokens = foto.getmimetype().split("/"); MediaType mimetype = new MediaType(tokens[0], tokens[1]); headers.setcontenttype(mimetype); return new ResponseEntity<>(foto.getBytes(), headers, HttpStatus.OK); 76

CRUD Veículo: acessando a foto com Ajax CRUDVeiculo método foto: @RequestMapping("/foto/{id") public ResponseEntity<byte[]> foto(@pathvariable Integer id){ Foto foto = veiculorepositorio.getfoto(id); HttpHeaders headers = new HttpHeaders(); String[] tokens = foto.getmimetype().split("/"); MediaType mimetype = new MediaType(tokens[0], tokens[1]); headers.setcontenttype(mimetype); return new ResponseEntity<>(foto.getBytes(), headers, HttpStatus.OK); Um ResponseEntity representa dados a serem inseridos na resposta HTTP. Pelo tipo de retorno deste método, SringMVC entende que não deve renderizar uma visão. 77

Pesquisa de veículo: Ajax + JSON Adicionar biblioteca Jackson ao pom.xml: <dependency> <groupid>com.fasterxml.jackson.core</groupid> <artifactid>jackson-databind</artifactid> </dependency> 78

Pesquisa de veículo: Ajax + JSON VeiculoRepositorio: método getpormodelo import java.util.list; public interface VeiculoRepositorio { public List<Veiculo> getpormodelo(integer idmodelo); 79

Pesquisa de veículo: Ajax + JSON VeiculoDAO: método getpormodelo @Repository @Transactional public class VeiculoDAO implements VeiculoRepositorio { @Override public List<Veiculo> getpormodelo(integer idmodelo) { String hql = "from Veiculo v where v.modelo.id = :id "; Session session = sessionfactory.getcurrentsession(); Query q = session.createquery(hql).setparameter("id", idmodelo); return q.list(); 80

Pesquisa de veículo: Ajax + JSON CRUDVeiculo: package cursospring.revenda_veiculos.web; import java.util.list; import org.springframework.web.bind.annotation.responsebody; public class CRUDVeiculo { @RequestMapping("/busca") public String paginadebusca(){ return "veiculos/busca"; @RequestMapping("/pesquisar") @ResponseBody public List<Veiculo> pesquisar(@requestparam Integer idmodelo){ return veiculorepositorio.getpormodelo(idmodelo); 81

Pesquisa de veículo: Ajax + JSON CRUDVeiculo: package cursospring.revenda_veiculos.web; import java.util.list; import org.springframework.web.bind.annotation.responsebody; public class CRUDVeiculo { @RequestMapping("/busca") public String paginadebusca(){ return "veiculos/busca"; Indica que a resposta do método deve ser colocada no payload da resposta HTTP. Por padrão, Spring MVC converterá os objetos Java retornados pelo método em uma string JSON. @RequestMapping("/pesquisar") @ResponseBody public List<Veiculo> pesquisar(@requestparam Integer idmodelo){ return veiculorepositorio.getpormodelo(idmodelo); 82

Pesquisa de veículo: Ajax + JSON Página veiculos/busca.jsp (1): <%@ page language="java" contenttype="text/html; charset=iso-8859-1" pageencoding="iso-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <c:url var="actionurl" value="/veiculos" /> <title>veículos</title> <script src="http://code.jquery.com/jquery-1.11.3.min.js"> </script> <script> $(document).ready(function($){ $('#formpesquisa').submit(function(event){ event.preventdefault(); buscar(); ); ) 83

Pesquisa de veículo: Ajax + JSON Página veiculos/busca.jsp (2): function buscar(){ $.getjson('${actionurl/pesquisar', $('#formpesquisa').serialize(), function(data){ var linhas = ''; for(var i=0; i<data.length; i++){ linhas += '<tr><td>'+data[i].placa+'</td>'+ '<td>'+data[i].modelo.descricao+'</td>'+ '<td>'+data[i].anofabricacao+'</td></tr>'; console.log(">>"+linhas); var $tbody = $('#tabelaveiculos').children('tbody'); $tbody.empty(); $tbody.append(linhas); ); </script> 84

Pesquisa de veículo: Ajax + JSON Página veiculos/busca.jsp (3): </head> <body> <h2>busca de Veículos</h2> <form id="formpesquisa"> <select name="idmodelo"> <c:foreach var="modelo" items="${modelos"> <option value="${modelo.id">${modelo.descricao</option> </c:foreach> </select> <input type="submit" value="pesquisar"> </form> <table id="tabelaveiculos"> <thead> <tr> <th>placa</th> <th>modelo</th> <th>ano</th> 85

Pesquisa de veículo: Ajax + JSON Página veiculos/busca.jsp (4): </tr> </thead> <tbody> </tbody> </table> </body> </html> 86

Servindo conteúdo estático É preciso registrar um gerenciador de recursos. import org.springframework.web.servlet.config.annotation.resourcehandlerreg istry; @EnableWebMvc @ComponentScan(basePackageClasses={OlaMundoController.class) public class AppWebConfig extends WebMvcConfigurerAdapter{ @Override public void addresourcehandlers(resourcehandlerregistry registry){ registry.addresourcehandler("/resources/**").addresourcelocations("/resources/"); 87

Servindo conteúdo estático É preciso registrar um gerenciador de recursos. import org.springframework.web.servlet.config.annotation.resourcehandlerreg istry; @EnableWebMvc @ComponentScan(basePackageClasses={OlaMundoController.class) URL de acesso aos arquivos. public class AppWebConfig extends WebMvcConfigurerAdapter{ @Override public void addresourcehandlers(resourcehandlerregistry registry){ registry.addresourcehandler("/resources/**").addresourcelocations("/resources/"); Diretório em que se encontram os arquivos (JS, CSS, imagens, etc). 88

Servindo conteúdo estático index.jsp: <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <html> <body> <h2>hello World!</h2> <img src="resources/logo.jpg" > </body> </html> 89

Servindo conteúdo estático index.jsp: <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> Repare que não é necessário o uso da <html> tag c:url para obter o endereço <body> completo da URL resources. <h2>hello World!</h2> <img src="resources/logo.jpg" > </body> </html> 90

Referências Johnson, Rod et al. Spring Framework Reference Documentation, 4.2.1 release. Disponível em <http://docs.spring.io/spring/docs/current/spring-frameworkreference/html/> Márcio d Ávila. Informações úteis sobre cabeçalhos HTTP e tipos MIME. Disponível em <http://www.mhavila.com.br/topicos/web/http_mime.html> Paraschiv, Eugen. Serve static resources with Spring. Disponível em <http://www.baeldung.com/spring-mvc-static-resources>. Souza, Alberto. Spring MVC: domine o principal framework web Java. São Paulo: Casa do Código, 2015. Stack Overflow. JSTL tag wiki. Disponível em <http://stackoverflow.com/tags/jstl/info> 91

Instituto Federal de Educação, Ciência e Tecnologia do Rio Grande do Norte Campus Natal Central Diretoria Acadêmica de Gestão e Tecnologia da Informação Curso de formação em Spring Framework 4 Parte 03 Spring MVC Autor: Alexandre Gomes de Lima Natal, outubro de 2015. 92