Post on 23-Nov-2015
1
Controlando o Spring MVC
Introduo
Atualmente no desenvolvimento de software, o grande bam bam bam dos modelos de desenvolvimento o MVC (Model-View-Controller), que foi descrito pela primeira vez por volta de 1970 por Trygve Reenskaug que trabalhavam com o Smalltalk (Linguagem de programao orientada a objeto). Foi criado
para fugir da antiga baguna onde cdigo se misturava com pagina que se misturavam com persistncia, e
facilitar a manutenabilidade do cdigo, onde uma mudana na view (pagina) no afete o Controller ou o model, e vice versa.
O Spring como no poderia ficar de fora, foi criado baseado nesse Spring MVC, no temos o @Controller
(que abordaremos mais a fundo nesse artigo), @Service (facilitador para acessar os Models a partir de um
framework de persistncia de sua escolha ou JDBC puro) e as Views so nossas .JSP, claro no apenas
isso que o framework possui, mas no vamos criar uma lista de funcionalidades agora, vamos nos
aprofundar nos Controllers do Spring e entender o que possvel criar com eles.
Requisitos
1. Um Dinamic Web Project configurado com as bibliotecas do Spring e rodando corretamente.
Observao: Ver referencia no fim do artigo para acessar artigo com exemplos de configurao,
usaremos o mesmo projeto contigo no artigo.
Entendendo o @Controller
Um Controller responsvel tanto por receber requisies como por enviar resposta ao usurio, algo
bem parecido com o Servlet do JSP, porem feito de forma mais elegante, e fcil. O Controller se
responsabiliza de informar a View, os atributos que sero visveis para a mesma, e tambm de
receber parmetros vindos da View, e por ultimo responder ao usurio o que foi requisitado, nem
sempre em uma View HTML, tambm pode ser retornado JSON, XML, etc.
Listagem 1: Crianco um controller
@Controller //Define que minha classe ser um controller
public class HomeController {
}
Vej na listagem um como simples criar um Controller, mas veja que seu controller no possui
nenhum mapping atrelado a ele, ento criemos uma view (.jsp) chamada home.jsp dentro da pasta /WEB-INF/views, e criaremos o mapping /home para exibir a view criada.
Listagem 2: Crianco um RequestMapping para HomeController
@Controller //Define que minha classe ser um controller
public class HomeController {
@RequestMapping("/home") //Define a url que quando for requisitada chamara o
metodo
public ModelAndView home(){
//Retorna a view que deve ser chamada, no caso home (home.jsp) aqui o
.jsp omitido
return new ModelAndView("home");
}
2
}
Agora sabemos como fazer uma requisio e retornar uma pagina, mas vamos supor que minha
sesso home possuam varias paginas dentro dela, exemplo /home/principal e /home/secundaria , para
isso vamos fazer uma pequena alterao no nosso HomeController.
Listagem 3: Modificando o HomeController
@Controller //Define que minha classe ser um controller
@RequestMapping("/home") //Define que qualquer ao desse controler deve preceder
/home
public class HomeController {
//Define a url que quando for requisitada chamara o metodo no caso
/home/principal ou /home/ ou /home
//Note que no obrigado apenas uma url, pode-se mapear varias para o mesmo
metodo
@RequestMapping( value = { "/" , "" ,"/principal" })
public ModelAndView homePrincipal(){
//Retorna a view que deve ser chamada, no caso principal
(principal.jsp) que esta dentro da pasta /home
return new ModelAndView("home/principal");
}
//Define a url que quando for requisitada chamara o metodo
@RequestMapping( "/secundaria" )
public ModelAndView homeSecundaria(){
//Retorna a view que deve ser chamada, no caso secundaria
(secundaria.jsp) que esta dentro da pasta /home
return new ModelAndView("home/secundaria");
}
}
Observao: No necessariamente as views devero estar contidas na pasta /home, apenas uma forma de organizar melhor as views.
Passando parmetros
Agora j entendemos melhor como funcionam as requisies e as respostas do Controller, agora veremos como receber parmetros e passar atributos para a View, para isso criaremos um novo Controller chamado ParamController, seguiremos o mesmo caminho do HomeController, mas agora acessando o a url /param.
Listagem 4: Criando e Mapeando o ParamController
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping(value = { "" , "/" } )
public ModelAndView recebeParam(@RequestParam String nome , Model model){
//@RequestParam indica que recebera um parametro "nome" que uma
String
//Model um auxuliar que ajudara a adicionar atributos a nossa view
model.addAttribute("nome" , nome);
return new ModelAndView("param/index");
}
}
3
No esquea de criar dentro de WEB-INF/views a pasta param e dentro dela a view index.jsp como descrito na listagem 5.
Listagem 5: Criando a view param/index.jsp
Controllers Spring
Param - Index
Parametro nome = ""
Pagina chamada a partir do mapping em ParamController
Explicando o que foi feito, ao mapear o @RequestParam eu estou dizendo ao mtodo que ele deve
esperar como parmetro de nome nome uma String, ou seja ao acessar /param?nome=SeuNomeAqui o parmetro nome ser atribudo a varivel nome, e o Model se encarregara de envia-lo como atributo a tela.
Muito fcil no? Mas espere, e se o parmetro no for passado o que acontecera ? ser retornado um
erro: Required String parameter 'nome' is not presente, para a segurana e garantia do funcionamento da aplicao isso timo, mas caso no queria que o parmetro seja obrigatrio basta
mapealo como @RequestParam(required = false), e veja como o nome recebe null, e nenhum erro ser retornado, o uso depender de sua necessidade.
Limitando os tipos de mtodos recebidos
Agora veremos como podemos limitar um mapping para receber apenas requisies via POST ou GET.
Observao: No ser abordado RESTful nesse artigo.
Para limitarmos um Mapping para receber apenas requisies GET ou POST adicionaremos ao nosso ParamController dois novos mtodos(Mappings) veja n listagem 6.
Listagem 6: Adicionando limitaes GET e POST
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping(value = { "" , "/" } )
public ModelAndView recebeParam(@RequestParam(required = false) String nome ,
Model model){
//@RequestParam indica que recebera um parametro "nome" que uma
String
//Model um auxuliar que ajudara a adicionar atributos a nossa view
model.addAttribute("nome" , nome);
return new ModelAndView("param/index");
}
4
@RequestMapping(value="/postonly" , method = RequestMethod.POST)
public ModelAndView postOnly(){
// o method define que tipo de requisio esse mapping vai aceitar
return new ModelAndView("param/postonly");
}
@RequestMapping(value="/getonly" , method = RequestMethod.GET)
public ModelAndView getOnly(){
return new ModelAndView("param/getonly");
}
}
Ao definir o method dizemos ao nosso controller que s ser executado o mtodo caso seja uma requisio do tipo especificado, caso nenhum method seja definido no @RequestMapping, por default ele recebera tanto GET quanto POST, caso tente acessar um mapping POST via GET ou vice
versa, ser retornado um erro: Request method 'GET' not supported o recebimento de parmetros e envio de atributos para a view continuam iguais sem nenhuma alterao.
Acesse a url no seu servidor param/getonly e veja que ocorre tudo normalmente, agora tente acessar param/postonly e veja o erro.
Recebendo formulrios completos
J vimos como receber parmetros, como limitar o tipo de requisio aceita, e os formulrios?
Calma, no ser necessria uma lista gigante de @RequestParam, a no ser que goste de escrever!
O Spring fornece uma anotao chamada @ModelAttribute, que pode ser um POJO um Domain
etc... Utilizaremos um POJO(Plain Old Java Object , Classe contendo apenas um construtor padro,
atributos e getters and setters) como exemplo, e usaremos tambm a tag de formulrio do Spring para
nos auxiliar no envio. Criemos ento um controller chamado FormController como na listagem 7.
Listagem 7: FormController
@Controller
@RequestMapping("/form")
public class FormController {
@RequestMapping(value = { "/" , "" } , method = RequestMethod.GET)
public ModelAndView carregaForm(Model model){
model.addAttribute("form", new Form());
return new ModelAndView("form/form");
}
@RequestMapping(value = { "/" , "" } , method = RequestMethod.POST)
public ModelAndView recebeForm(@ModelAttribute("form") Form form, Model model){
model.addAttribute("msg", "Voc enviou: " + form.getNome() + " " +
form.getSobrenome() );
return new ModelAndView("form/form");
}
}
Como devem ter percebido, possuo dois @RequestMapping apontando para o mesmo caminho, o
Spring fara a diferena de que mtodo ser chamado pelo tipo de requisio que est sendo feita.
Veja tambm que est sendo adicionado a nossa view um objeto nosso objeto Form. Criaremos agora o nosso objeto Form como na listagem 8.
5
Listagem 8: POJO Form
public class Form {
private String nome;
private String sobrenome;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getSobrenome() {
return sobrenome;
}
public void setSobrenome(String sobrenome) {
this.sobrenome = sobrenome;
}
}
Agora criaremos a nossa view contendo o formulrio, para isso adicionaremos uma jsp em /WEB-INF/views/form/ com o nome form.jsp , veja na listagem 9.
Listagem 9: View form.jsp
Controllers Spring
Form
Pagina chamada a partir do mapping em FormController
Nome:
Sobrenome:
Enviar
6
Veja que importamos a taglib form do Spring, ela ira nos auxiliar a ler um objeto que tenha sido passado pelo Controller , vamos dissecar o nosso formulrio, veja.
Listagem 10: Tag form:form
Perceba o atributo modelAttribute=form , com ele dizemos ao nosso formulrio com que objeto estamos trabalhando, no casso o objeto form que foi adicionado ao chamar a view.
Listagem 11: Tag form:label
Nome:
A tag form:label criara um label para o atributo nome como foi especificado atravs de path, cssStyle o mesmo que o style do HTML, foi adicionado apenas para deixar um pouco mais apresentvel o formulrio.
Listagem 12: Tag form:input
A tag form:input criar um campo , para o atributo nome do nosso objeto form.
Listagem 13: Tag form:button
Enviar
A tag form:button criara um boto de envio do formulrio.
Agora com tudo pronto rode sua aplicao, acesse a pagina do formulrio e veja o resultado como na
figura 1.
Figura 1: Pgina de formulrio antes do envio
7
E a figura 2 mostra aps o envio do formulrio.
Figura 2: Pgina de formulrio aps o envio
Veja que o formulrio j vem preenchido, o Spring faz isso por voc, note tambm que tudo que foi
enviado no formulrio ser inserido no @ModelAttribute do nosso mtodo recebeForm() no nosso Controller.
Concluindo
O Spring nos fornece varias ferramentas de fcil uso, e de rpido aprendizado, veja que um
framework bastante rpido, e sem muito peso para o nosso servidor, existem inmeras outras
utilidades no Controller, mas abordamos as mais utilizadas.
At a prxima.
Referencias
o Introduo ao Spring Framework