Baixe o app para aproveitar ainda mais
Prévia do material em texto
Escrito por Carlos Filipe Andrade dos Santos 15/08/2020 Spring MVC Nesse post vamos falar sobre uma das tecnologias mais usadas e mais eficientes em se tratando de programação Java WEB. Vamos aprender como funciona o Spring MVC e faremos uma aplicação simples para demonstrar a utilização de seus recursos mais utilizados. O que é o Spring MVC? Spring Web MVC é a estrutura da web original construída na API Servlet e foi incluída no Spring Framework desde o início. O nome formal, “Spring Web MVC,” vem do nome de seu módulo de origem (spring-webmvc), mas é mais conhecido como “Spring MVC”. O Spring Framework é um framework muito conhecido e utilizado na programação Java WEB. Ele implementa muitas funções, como injeção de dependência, persistência de dados e uma implementação MVC. Com ele nós conseguimos construir aplicações WEB robustas e flexíveis. O Spring MVC é moderno e usa os recursos atuais da linguagem e todo poder do container Spring. Ele tem todas as funcionalidades necessárias para atender as requisições HTTP, delegar responsabilidades de processamento de dados para outros componentes e preparar a resposta que precisa ser dada. Como Funciona? Assim como outros frameworks WEB, o Spring MVC funciona em um modelo flexível que suporta diversos workflows, onde um servlet central (DispatcherServlet) fornece um algoritmo compartilhado para processamento de solicitação, enquanto o trabalho real é executado por componentes configuráveis e delegados. MVC é acrônimo de Model, View e Controller e o fluxo de requisição funciona como mostrado na figura abaixo: Fluxograma MVC - Fonte:https://blog.algaworks.com/spring-mvc/ Os passos mostrados acima funcionam assim: 1. Acessamos uma URL no browser que envia a requisição HTTP para o servidor que roda a aplicação WEB com Spring MVC. https://www.devmedia.com.br/curso/spring-mvc/2134 https://blog.algaworks.com/spring-mvc/ 2. O controlador do framework irá procurar qual classe é responsável por tratar essa requisição e a classe faz o papel do controller. 3. O controller passa os dados para o model, que por sua vez executa todas as regras de negócio, como cálculos, validações e acesso ao banco de dados. 4. O resultado das operações realizadas pelo model é retornado ao controller. 5. O controller retorna o nome da view, junto com os dados que ela precisa para renderizar a página. 6. O Framework encontra a view que processa os dados, transformando o resultado em um HTML. 7. Finalmente, o HTML é retornado ao browser do usuário. O controller é a classe Java com os métodos que tratam essas requisições. Portanto, tem acesso a toda informação relacionada a ela como parâmetros da URL, dados submetidos através de um formulário, cabeçalhos HTTP, etc. O model seria como as classes de serviços, repositórios e as entidades de banco de dados. A view são nossas páginas JSP que irão tornar-se em HTML para chegar aos usuários. Utilizando o Spring MVC Para fazer uma demonstração vamos fazer uma aplicação back-end de um formulário de cadastro de clientes de um banco, só para demonstrar como utilizar o Spring MVC. Vamos criar uma classe chamada clientes com atributos e seus gets e sets, uma classe controlador e o que mais for necessário no decorrer do projeto Vamos utilizar nesta aplicação o Java 11, Tomcat 8, o Spring Framework 5 e usaremos para edição o Visual Studio Code(VScode). A aplicação terá, além da tela de formulário, uma tela que exibe os detalhes do cliente cadastrado no formulário, e uma tela que lista todos os clientes já cadastrados na aplicação e ainda retornaremos todos os clientes da nossa base de dados em formato JSON. Para isso vamos fazer alguns passos. 1. Criando Controlador Vamos criar uma classe comum e anotá-la como @Controller, que fará com que o Spring reconheça a classe como um controlador. As ações nessa são métodos Java comuns que serão configuradas para responder as requisições web, usando anotações. package com.cfilipe; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @Controller @RequestMapping("/clientes") public class ClientesController { @Autowired private Clientes clientes; @RequestMapping(method = RequestMethod.GET) public ModelAndView listar() { ModelAndView modelAndView = new ModelAndView("clientes-lista.jsp"); modelAndView.addObject("clientes", clientes.findAll()); return modelAndView; } } - @Controller - anotação que torna a classe um controlador. - @RequestMapping - configura qual o path inicial para todas as ações do nosso controlador e depois especificando como será a requisição que a ação listar() vai atender. - @Autowired - injetará o nosso repositório clientes pelo Spring Framework. A propriedade method da nossa anotação @RequestMapping está especificando um método HTTP que é o GET.A anotação não tem um path e o método listar() é a ação padrão do nosso controlador e vai responder para uma requisição do tipo GET com o path /funcionarios. - A classe ModelAndView foi utilizada para especificar a view que será renderizada para o usuário final e para informarmos quais os dados ela utilizará para isso. - funcionario-lista.jsp e o método addObject é utilizado para adicionarmos uma lista de objetos que serão exibidos por ela. 2. Recebendo Dados do Formulário Faremos um formulário para receber os dados que serão submetidos e recebidos. package com.cfilipe; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.Date; public class Cliente { private String nome; private String cpf; private String telefone; private String endereco; private String conta; private String agencia; private float salario; //gets e sets foram suprimidos } Vamos construir o formulário. Com as tags Spring irá exibir as informações do cliente caso elas já venham preenchidas. <s:url value="/clientes/salvar" var="acao" /> <sf:form method="post" modelAttribute="clientes" action="${acao}"> <div> <label for="nome">Nome:</label> <sf:input path="nome" /> </div> <div> <label for="cpf">CPF:</label> <sf:input path="cpf" /> </div> <div> <label for="telefone">Telefone:</label> <sf:input path="telefone" /> </div> <div> <label for="endereco">Endereço:</label> <sf:input path="endereco" /> </div> <div> <label for="conta">Conta:</label> <sf:input path="conta" /> </div> <div> <label for="agencia">Agencia:</label> <sf:input path="agencia" /> </div> <div> <label for="salario">Salario:</label> <sf:input path="salario" /> </div> <button type="submit">Salvar</button> </sf:form> Para receber os dados da submissão do formulário faremos a ação que é feita na classe ClientesController: @Controller @RequestMapping("/clientes") public class ClientesController { ... @Autowired private ClienteService clienteService; @RequestMapping(method = RequestMethod.POST, path = "/salvar") public RedirectView salvar( Cliente cliente; RedirectAttributes redirectAttributes) { clienteService.salvar(cliente); redirectAttributes.addFlashAttribute( "mensagem", "Cadastro feito com sucesso!"); return new RedirectView("/cliente", true); }} - Cliente – será preenchido com os dados do formulário. - RedirectAttributes – incluir o atributo com a mensagem que será exibida após o redirecionamento. - Com a instância Funcionario preenchida podemos manipulá-la como quisermos. Salvar como no caso. - RedirectView - foi usado para fazer um redirecionamento de página e não uma renderização. Para imprimir os dados do formulário para o usuário fazemos a ação: @RequestMapping(method = RequestMethod.GET, path = "/novo") public ModelAndView novo() { ModelAndView modelAndView = new ModelAndView("cliente-formulario.jsp"); modelAndView.addObject("cliente", new Cliente()); return modelAndView; } 3. Enviando dados para a página Enviamos os dados quando utilizamos os métodos addAttribute da interface Model, addObject da classe ModelAndView e até no método addFlashAttributeda classe RedirectAttributes. Mas vamos fazer simulando a função de edição. Para fazermos isso adicionamos algumas modificações no nosso formulário que contém as tags Spring: <s:url value="/clientes/salvar" var="acao" /> <sf:form method="post" modelAttribute="clientes" action="${acao}"> <c:if test="${not empty cliente.id}"> <div> <label>Código:</label ${cliente.id} <sf:hidden path="id" /> </div> </c:if> <div> <label for="nome">Nome:</label> <sf:input path="nome" /> </div> ... - Criamos o identificador do cliente e usamos o campo hidden para armazená-lo. Agora vamos adicionar a ação edicao() na classe ClientesController chamada para abrir este formulário. @RequestMapping(method = RequestMethod.GET, path = "/edicao") public ModelAndView edicao(@RequestParam Long id) { ModelAndView modelAndView = new ModelAndView("cliente-formulario.jsp"); modelAndView.addObject("cliente", clientes.findOne(id)); return modelAndView; } - @RequestParam - nos ajuda a ter acesso aos parâmetros da requisição. Passando o identificador do cliente que queremos editar para essa ação e ele fará a pesquisa do mesmo e devolverá para nossa view preparar o formulário que será enviado ao browser. A URL para invocação seria: http://localhost:8080/app/clientes/edicao?id=1. Para ajudar o Spring MVC a encontrar as que serão retornadas usamos a interface ViewResolver. A resolução padrão das páginas é feita em conjunto com a URL da requisição. No caso de, por exemplo, utilizarmos a URL http://localhost:8080/app/clientes/novo para invocar nossa ação novo(): @GetMapping("/novo") public String novo() { return "cliente-formulario.jsp"; } O Spring MVC vai procurar pela página cliente-formulario.jsp em um diretório da nossa aplicação web chamada “clientes”. A configuração dessa interface é feita através do Java desta forma: @Configuration public class ViewResolverConfig { @Bean public ViewResolver internalResourceViewResolver(){ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/paginas/"); viewResolver.setViewNames(new String[] {"*.jsp"}); return viewResolver; }} http://localhost:8080/app/clientes/edicao?id=1 http://localhost:8080/app/funcionarios/novo 4. Criar uma API RESTfull Se for preciso retornar retornar todos os clientes da sua base no formato JSON. Existem alguns recursos no Spring MVC para isso. Existem alguns caminhos para fazer isso, aqui vamos fazer de duas maneiras diferentes: 1- Adicionado uma ação ao @Controller: @Controller @RequestMapping("/clientes") public class ClientesController { ... @ResponseBody @GetMapping("/todos") public List<Cliente> todos() { return clientes.findAll(); } } - @ResponseBody - diz ao Spring MVC para jogar o retorno do método na resposta. - Agora podemos fazer uma requisição de uma lista com todos os clientes para http://localhost:8080/app/funcionarios/todos. e teríamos um arquivo JSON assim: [ { "id": 1, "nome": "Carlos", "cpf": "11111111111", "telefone":"99999999", "endereco":"rua L, num 1", "conta":"0001-1", "agencia":"001" }, { "id": 2, "nome": "Filipe", "cpf": "22222222222", "telefone":"888888888", "endereco":"rua B, num 3", "conta":"0030-6", "agencia":"002" }, { "id": 3, "nome": "Joel", "cpf": "6666666666", "telefone":"666666666", "endereco":"rua C, num 4", "conta":"0005-7", "agencia":"055" } ] http://localhost:8080/app/funcionarios/todos 2 - Criando uma novo controlador um @RestController: @RestController @RequestMapping("/api/clientes") public class ClientesResource { @Autowired private Clientes clientes; @GetMapping public List<Cliente> todos() { return clientes.findAll(); } } A URL para invocar a ação todos(), nesse novo controlador, fica assim agora: http://localhost:8080/app/api/clientes. Assim nossa aplicação fica mais elegante e não precisa de algumas anotações, eu particularmente prefiro dessa forma pois o código fica mais limpo, com o mesmo resultado. Conclusão O Spring MVC é uma boa alternativa para programação WEB pela facilidade e quantidade de funcionalidades e recursos que nos ajuda a melhorar nossos códigos. É realmente um ótimo framework web. Usando o Spring Boot muitos passos não precisa ser feito pois algumas etapas ele inclui na declaração do projeto, que foi nesse caso, mas é possível fazer em um projeto Java WEB modificando algumas configurações e implementando outros códigos. Os dados teriam que ser processados em HTML para fazer as telas que serão visíveis para o usuário, tanto de coleta de dados como para mostrar as listas de clientes, mas vamos concluir por aqui, pois o objetivo era explicar como utilizar o Spring MVC para tratar uma requisição e o objetivo foi concluído. Carlos Filipe Andrade dos Santos cfilipeas06@gmail.com http://localhost:8080/app/api/funcionarios mailto:cfilipeas06@gmail.com
Compartilhar