Está en la página 1de 92

Spring Framework

Parte 03 Spring MVC

Spring MVC
Mdulo do Spring Framework que permite o
desenvolvimento de aplicaes web baseadas em
aes (action based) bem como o desenvolvimento
de servios REST.
Integra-se API de Servlets.
Suporta:
Diversas tecnologias de viso tais como JSP/JSTL, Velocity,
FreeMarker, Thymeleaf, Tiles, XSLT e Groovy Markup
Templates.
Processamento assncrono.
Internacionalizao.

Oferece funcionalidades de segurana e de testes.


2

Padro front controller


Handler
mapping

2: HTTP request

3: Web controller
1: HTTP request
Dispatcher
Servlet

4: HTTP request
Web controller
5: model and view name

10: HTTP Response

6: view name
9: HTTP Response

View

8: model

7: view
View
resolver
3

Controlador web
Objeto responsvel por responder um conjunto
de requisies HTTP.
As requisies atendveis podem ser especificadas
atravs de padres de URL, por cabealhos HTTP
e por mtodos HTTP.

Anotaes e classes
@Controller: define um controlador web.
@RequestMapping: definies das requisies HTTP
a serem atendidas.
@RequestParam: define um parmetro query string.
@PathVariable: referencia parmetros 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 configuraes
Adicionar JSTL como dependncia no pom.xml:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>

Atualizando as configuraes
Disponibilizando o contexto do Spring para o
contexto da aplicao 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
import
import
import

org.springframework.beans.factory.annotation.Autowired;
org.springframework.stereotype.Controller;
org.springframework.ui.Model;
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";
}
}

CRUD Fabricante: listagem


Controlador web (2):
@RequestMapping
public String inicio(Model model){
model.addAttribute("fabricantes", repositorio.todos());
return "fabricantes/inicio";
}
}
Viso (pgina) a ser renderizada com
os dados inseridos em model.

10

CRUD Fabricante: listagem


Pgina src/main/webapp/WEBINF/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">Opes</th>
</tr>
11

CRUD Fabricante: listagem


Pgina src/main/webapp/WEBINF/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: excluso


Controlador web (1):
...
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/fabricantes")
public class CRUDFabricante {
...

13

CRUD Fabricante: excluso


Controlador web (2):
...
@RequestMapping("/excluir")
public String excluir(@RequestParam("id") Integer idFabricante,
Model model){
try{
repositorio.excluir(idFabricante);
model.addAttribute("mensagem",
"Fabricante excludo com sucesso.");
}catch(Exception ex){
ex.printStackTrace();
model.addAttribute("mensagem",
"Ocorreu um erro durante a operao.");
}
return "forward:/fabricantes";
}
}
14

CRUD Fabricante: excluso


Controlador web (2):

...
@RequestMapping("/excluir")
public String excluir(@RequestParam("id") Integer idFabricante,
Model model){
try{
repositorio.excluir(idFabricante);
model.addAttribute("mensagem",
"Fabricante excludo com sucesso.");
}catch(Exception ex){
ex.printStackTrace();
model.addAttribute("mensagem",
Como queremos voltar listagem
"Ocorreu um erro durante
a operao.");
de fabricantes
aps a excluso,
}
aproveitamos o mtodo inicio
return "forward:/fabricantes";
realizando um forward para a URL
}
/fabricantes.
15

CRUD Fabricante: excluso


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 aps processar uma requisio o
controlador web direcione o fluxo da aplicao
para uma pgina diferente da utilizada na
submisso.
Temos duas formas disponveis: forward e
redirect.
Diferena bsica:
No forward o processamento realizado no servidor.
No redirect a mudana de pgina feita pelo browser.
17

Forward
As mudanas de URL so todas processadas no
servidor antes da resposta ser enviada ao cliente.
Por haver apenas uma requisio, o mesmo contexto
de requisio utilizado pelas pginas e mtodos
envolvidos no processamento.
O mesmo model fica disponvel a todos os mtodos Java.

Ao final do processamento da requisio, a URL na


barra de endereos do navegador no muda. Assim,
o reload da pgina resultante ir executar a
requisio original.
18

Forward

19

Redirect
um mecanismo especificado pelo HTTP.
Dois passos. Ao receber uma requisio, a aplicao
pede ao browser para acessar uma segunda URL.
Por isso a URL na barra de endereos muda.
O pedido um recurso do HTTP: cdigo 301 ou 302 e
cabealho Location.

O reload de pgina no repetir a requisio original,


mas sim a segunda URL.
Como acontecem duas requisies, os dados da
primeira requisio, no estaro disponveis no
contexto da segunda requisio.
Um model diferente por mtodo Java.
20

Redirect

21

Flash scope
Utilizado para manter dados que devem estar
disponveis aps um redirect.
Para utilizar o flash scope basta declarar um
parmetro do tipo RedirectAttributes.

22

CRUD Fabricante: excluso com redirect


Controlador web (1):
...
import
org.springframework.web.servlet.mvc.support.RedirectAttributes;
...
public class CRUDFabricante {
...

23

CRUD Fabricante: excluso com redirect


Controlador web (2):
...
@RequestMapping("/excluir")
public String excluir(@RequestParam("id") Integer idFabricante,
RedirectAttributes redAttr){
try{
repositorio.excluir(idFabricante);
redAttr.addFlashAttribute("mensagem",
"Fabricante excludo com sucesso.");
}catch(Exception ex){
ex.printStackTrace();
redAttr.addFlashAttribute("mensagem",
"Ocorreu um erro durante a operao.");
}
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 anotaes 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 mtodo 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 mtodo 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 formulrio.

29

CRUD Fabricante: novo registro


Controlador web mtodo 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 ttulo da pgina pois a
mesma pgina ser utilizada nas operaes
de novo fabricante e edio de fabricante.
30

CRUD Fabricante: novo registro


Pgina 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


Pgina 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>
manipulao de formulrios.
<body>
<h2>${titulo}</h2>
<c:url var="actionUrl" value="/fabricantes/salvar" />

32

CRUD Fabricante: novo registro


Pgina edicao.jsp (2):
<form:form action="${actionUrl}" method="post"
modelAttribute="fabricante">
<label for="descricao">DESCRIO</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


Pgina edicao.jsp (2):
<form:form action="${actionUrl}" method="post"
modelAttribute="fabricante">
<label for="descricao">DESCRIO</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>
Define o identificador do objeto que ser
</html>
utilizado (binding) para receber/preencher os
campos do formulrio. O objeto ser inserido no
contexto do model. Note que este o
identificador a ser utilizado no controlador para
acessar os campos do formulrio.
34

CRUD Fabricante: novo registro


Controlador web mtodo salvar (1):
import
import
import
import
...

javax.validation.Valid;
org.springframework.validation.BindingResult;
org.springframework.web.bind.annotation.ModelAttribute;
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
mtodo
(1):
que os atributosweb
do
Indica quesalvar
o spring deve
injetar um objeto
objeto org.springframework.validation.BindingResult;
devem ser validados
presente no contexto do model e que
import
segundo
as anotaes da
identificado pela string fabricante. Na
import
org.springframework.web.bind.annotation.ModelAttribute;
Validation.
pgina, usamos o mesmo identificador.
import Bean
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){
Armazena o resultado
if(br.hasErrors()){
da validao.
model.addAttribute("titulo", titulo);
return "fabricantes/edicao";
}
36

CRUD Fabricante: novo registro


Controlador web mtodo 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 operao.");
}
return "redirect:/fabricantes";
}
...
37

CRUD Fabricante: alterar registro


inicio.jsp link de edio:
...
<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 formulrios


checkbox: produz um campo input do tipo checkbox. Pode ser
associada a atributos com um ou muitos valores (colees e
arrays). Quando seu valor no indicado, assumido o tipo
boolean.
checkboxes: gera vrios campos do tipo checkbox a partir de
uma coleo.
radiobutton: produz uma tag input do tipo radio.
radiobuttons: gera um conjunto relacionado de radio buttons a
partir de uma coleo.
password: gera uma tag input do tipo password.
option: gera uma tag option para um campo select.
options: opes de um campo select gerados a partir de uma
coleo.
textarea: produz uma tag textarea.
40

CRUD Veculo
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 Veculo
Classe Veiculo (1):
package cursoSpring.revenda_veiculos.dominio;
import
import
import
import
import
import
import
import
import
import

javax.persistence.Basic;
javax.persistence.Embedded;
javax.persistence.Entity;
javax.persistence.FetchType;
javax.persistence.JoinColumn;
javax.persistence.ManyToOne;
javax.persistence.Table;
javax.validation.constraints.Min;
javax.validation.constraints.NotNull;
javax.validation.constraints.Pattern;

@Entity
@Table(name="VEICULOS")
public class Veiculo extends Entidade {
42

CRUD Veculo
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 Veculo
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 Veculo
Classe Veiculo (4):
public String getMimeTypeFoto() {
if(foto != null)
return foto.getMimeType();
return null;
}
//getters e setters ...
}

45

CRUD Veculo
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 Veculo
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 Veculo
Classe VeiculoDAO (1):
package cursoSpring.revenda_veiculos.dao;
import
import
import
import
import
import
import
import
import
import

java.util.List;
org.hibernate.Query;
org.hibernate.Session;
org.hibernate.SessionFactory;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.stereotype.Repository;
org.springframework.transaction.annotation.Transactional;
cursoSpring.revenda_veiculos.dominio.Foto;
cursoSpring.revenda_veiculos.dominio.Veiculo;
cursoSpring.revenda_veiculos.dominio.VeiculoRepositorio;

@Repository
@Transactional
public class VeiculoDAO implements VeiculoRepositorio {
48

CRUD Veculo
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 Veculo
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 Veculo
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 Veculo
Pgina 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>Veculos</title>
</head>
<body>
<h2>Veculos</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 veculo</a>
52

CRUD Veculo
Pgina veiculos/inicio.jsp (2):
<table>
<tr>
<th>Placa</th>
<th>Fabricante</th>
<th>Modelo</th>
<th>Ano</th>
<th>Cilindradas</th>
<th colspan="2">Opes</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 Veculo
Pgina veiculos/inicio.jsp (3):
<td>
<a href="${actionUrl}/excluir/${veiculo.id}">
EXCLUIR
</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>

54

CRUD Veculo
Pgina 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 veculo</title>
</head>
<body>
<h2>Novo veculo</h2>
<c:url var="actionUrl" value="/veiculos/salvar" />
<form:form action="${actionUrl}" method="post"
modelAttribute="veiculo" >
55

CRUD Veculo
Pgina 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 Veculo
Pgina 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 Veculo
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 Veculo
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 Veculo
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 mtodo no
private VeiculoRepositorio veiculoRepositorio;
contexto model. Assim, a lista
@Autowired
de modelos ficar disponvel
private ModeloRepository modeloRepositorio;
para as pginas acessadas

@ModelAttribute("modelos")
public List<Modelo> listaDeModelos(){
return modeloRepositorio.todos();
}

atravs deste controlador.

60

CRUD Veculo
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 Veculo
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",
"Veculo salvo com sucesso.");
}catch(Exception ex){
ex.printStackTrace();
rAttrs.addFlashAttribute("mensagem",
"Ocorreu um erro durante a operao.");
}
return "redirect:/veiculos";
}

62

CRUD Veculo
Classe CRUDVeiculo (5):
@RequestMapping("/excluir/{id}")
public String excluir(@PathVariable Integer id,
RedirectAttributes redAttr){
try{
veiculoRepositorio.excluir(id);
redAttr.addFlashAttribute("mensagem",
"Veculo excludo com sucesso.");
}catch(Exception ex){
ex.printStackTrace();
redAttr.addFlashAttribute("mensagem",
"Ocorreu um erro durante a operao.");
}
return "redirect:/veiculos";
}
}
63

CRUD Veculo
Classe ModeloDAO:
...
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional
public class ModeloDAO implements ModeloRepository {
...
}

64

CRUD Veculo: upload da foto


Dependncia para upload de arquivos:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>

65

CRUD Veculo: upload da foto


Classe AppConfig adio 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 Veculo: upload da foto


Pgina 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 Veculo: upload da foto


CRUDVeiculo atualizao do mtodo 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 Veculo: upload da foto


CRUDVeiculo atualizao do mtodo 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 file presente no
veiculo.setFoto(foto);
formulrio de submisso.
}
69

CRUD Veculo: upload da foto


CRUDVeiculo atualizao do mtodo salvar (2):
veiculoRepositorio.inserir(veiculo);
rAttrs.addFlashAttribute("mensagem",
"Veculo salvo com sucesso.");
}catch(Exception ex){
ex.printStackTrace();
rAttrs.addFlashAttribute("mensagem",
"Ocorreu um erro durante a operao.");
}
return "redirect:/veiculos";
}
...

70

CRUD Veculo: acessando a foto com Ajax


veiculos/inicio.jsp (1):
...
<head>
<c:url var="actionUrl" value="/veiculos" />
<title>Veculos</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 Veculo: acessando a foto com Ajax


veiculos/inicio.jsp (1):
...
<head>
<c:url var="actionUrl" value="/veiculos" />
<title>Veculos</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() {
Esta instruo foi movida para o incio
$("#dialogFoto").dialog({ da tag head para que a URL j esteja
autoOpen: false
disponvel aos scripts em JS.
});
});

72

CRUD Veculo: 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 Veculo: 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 Veculo: 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 Veculo: acessando a foto com Ajax


CRUDVeiculo mtodo 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 Veculo: acessando a foto com Ajax


CRUDVeiculo mtodo 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 mtodo,
SringMVC entende que no deve renderizar uma viso.
77

Pesquisa de veculo: Ajax + JSON


Adicionar biblioteca Jackson ao pom.xml:
...
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
...

78

Pesquisa de veculo: Ajax + JSON


VeiculoRepositorio: mtodo getPorModelo
...
import java.util.List;
...
public interface VeiculoRepositorio {
...
public List<Veiculo> getPorModelo(Integer idModelo);
}

79

Pesquisa de veculo: Ajax + JSON


VeiculoDAO: mtodo 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 veculo: 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 veculo: Ajax + JSON


CRUDVeiculo:
package cursoSpring.revenda_veiculos.web;
import java.util.List;
import org.springframework.web.bind.annotation.ResponseBody;
...
public class CRUDVeiculo {
Indica que a resposta do mtodo deve
...
ser colocada no payload da resposta
@RequestMapping("/busca")
HTTP. Por padro, Spring MVC
public String paginaDeBusca(){
converter os objetos Java retornados
return "veiculos/busca";
pelo mtodo em uma string JSON.
}
@RequestMapping("/pesquisar")
@ResponseBody
public List<Veiculo> pesquisar(@RequestParam Integer idModelo){
return veiculoRepositorio.getPorModelo(idModelo);
}
}

82

Pesquisa de veculo: Ajax + JSON


Pgina 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>Veculos</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 veculo: Ajax + JSON


Pgina 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 veculo: Ajax + JSON


Pgina veiculos/busca.jsp (3):
</head>
<body>
<h2>Busca de Veculos</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 veculo: Ajax + JSON


Pgina veiculos/busca.jsp (4):
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>

86

Servindo contedo esttico


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 contedo esttico


preciso registrar um gerenciador de recursos.
...
import
org.springframework.web.servlet.config.annotation.ResourceHandlerReg
istry;
@EnableWebMvc
URL de acesso aos arquivos.
@ComponentScan(basePackageClasses={OlaMundoController.class})
public class AppWebConfig extends WebMvcConfigurerAdapter{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
Diretrio em que se encontram os
...
arquivos (JS, CSS, imagens, etc).
}
88

Servindo contedo esttico


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 contedo esttico


index.jsp:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags/form"
Repare que no necessrio o uso da
prefix="form" %>
tag c:url para obter o endereo
<html>
completo da URL resources.
<body>
<h2>Hello World!</h2>
<img src="resources/logo.jpg" >
</body>
</html>

90

Referncias
Johnson, Rod et al. Spring Framework Reference
Documentation, 4.2.1 release. Disponvel em
<http://docs.spring.io/spring/docs/current/spring-frameworkreference/html/>
Mrcio dvila. Informaes teis sobre cabealhos HTTP e
tipos MIME. Disponvel em
<http://www.mhavila.com.br/topicos/web/http_mime.html>
Paraschiv, Eugen. Serve static resources with Spring. Disponvel
em <http://www.baeldung.com/spring-mvc-static-resources>.
Souza, Alberto. Spring MVC: domine o principal framework web
Java. So Paulo: Casa do Cdigo, 2015.
Stack Overflow. JSTL tag wiki. Disponvel em
<http://stackoverflow.com/tags/jstl/info>
91

Instituto Federal de Educao, Cincia e Tecnologia do Rio


Grande do Norte
Campus Natal Central
Diretoria Acadmica de Gesto e Tecnologia da Informao
Curso de formao em Spring Framework 4
Parte 03 Spring MVC
Autor: Alexandre Gomes de Lima
Natal, outubro de 2015.

92

También podría gustarte