Desenvolvendo uma Aplicação Web com Spring Boot e Spring MVC

Nesse artigo será mostrado como desenvolver uma aplicação Web com o Spring MVC e o Spring Data utilizando o Spring Boot com o Maven para configuraração, o que facilita muito o desenvolvimento desse tipo de aplicação.

O Spring Boot é uma ferramenta para o desenvolvimento de aplicações que utilizam o framework Spring sem que seja necessária praticamente nenhuma configuração.

O Spring Boot é capaz de identificar quais as principais características da aplicação que está sendo desenvolvida e fazer automaticamente as configurações necessárias como, por exemplo, o arquivo applicationContext.xml, o web.xml e os data sources. Com isso os programadores ganham muito em produtividade, focando apenas no desenvolvimento da aplicação e não na configuração das ferramentas e frameworks utilizados, que são repetidos em praticamente todos os projetos.

O Spring sempre foi conhecido por ser um framework robusto e completo, mas que necessita de diversas configurações. Porém, versão a versão a ferramenta vem melhorando essa característica. Inicialmente, toda a configuração do Spring era feita com arquivos XML, mas na versão 2.5 foram introduzidas as anotações para que a mesma fosse feita diretamente no código, eliminando boa parte dos arquivos XML, facilitando bastante a configuração das aplicações. Agora com o Spring Boot, a ideia é que praticamente nenhuma configuração seja necessária, nem mesmo com anotações no código.

Ele tem quatro componentes principais para realizar as funções descritas anteriormente:

  1. Configuração Automática: O Spring Boot identifica automaticamente as configurações necessárias pelo tipo de aplicação, por exemplo, se é uma aplicação Web, com JPA ou uma API Rest;
  2. Dependências Automáticas: O Spring Boot adiciona, pelo tipo de projeto, um conjunto de bibliotecas que já foram testadas juntas, diminuindo problemas de compatibilidade;
  3. Interface de Linha de Comando: disponibiliza uma interface de linha de comando onde o programador pode, de maneira fácil, criar, executar e modificar uma aplicação;
  4. Actuator: É uma ferramenta que permite ao programador verificar o que está acontecendo internamente em uma aplicação com o Spring Boot.

Nesse artigo será mostrado como configurar a aplicação utilizando as configurações e as dependências automáticas do Spring Boot para criar uma aplicação web de maneira rápida e fácil e com praticamente nenhuma configuração necessária. Tecnicamente, vamos construir uma aplicação com o framework Spring MVC, o Spring Data JPA para fazer a persistência dos dados, o banco de dados H2 que já vem na instalação padrão do Spring Boot e o Thymeleaf para definir as visões. Este último é um template engine que substituiu o JSP.

Desenvolvimento da Aplicação

Será desenvolvida uma aplicação bem simples, apenas para demonstrar a funcionalidade do Spring Boot e, por isso, ela terá uma lista de livros que será organizada pelo nome do autor. Existirá uma página para cada um destes onde será exibida a sua respectiva lista de livros e um formulário que permitirá o cadastro de novos livros para esse autor. A aplicação desse artigo foi desenvolvida utilizando a IDE Eclipse, porém qualquer IDE pode ser utilizada.

Para a configuração da aplicação foi utilizado o Apache Maven (o Spring Boot suporta também o Gradle), para isso foram adicionadas quatro dependências do mesmo:

A Listagem 1 mostra o código do arquivo pom.xml com as dependências adicionadas.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.devmedia.mvc</groupId> <artifactId>agenda</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Listagem 1. Pom.xml para a configuração da aplicação com o Maven

A tag no arquivo indica qual a versão do Spring Boot será utilizada no projeto, e assim, todas as bibliotecas do Spring Boot também utilizam essa versão. Verifiquem que na tag das três bibliotecas do Spring Boot (spring-boot-starter-web, spring-boot-starter-data-jpa, spring-boot-starter-thymeleaf) não são adicionadas as versões porque todas elas utilizam a versão que foi definida na tag .

Com a aplicação configurada, o primeiro passo no desenvolvimento foi a implementação da classe que representa os objetos que serão persistidos no banco de dados, que é a classe Livro. Essa classe tem diversas anotações do JPA, como a @Entity para indicar que a classe é uma entidade do banco de dados, a @Id para indicar que o campo id é o identificador da entidade, a @GeneratedValue que indica que o valor será gerado banco de dados e a @Column para definir alguns parâmetros das colunas como o nome, se ela pode receber valores nulos ou se o valor da coluna é único. A Listagem 2 mostra o código da classe Livro com suas anotações.

package com.devmedia.mvc.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Livro { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; @Column(name="titulo", nullable=false) private String titulo; @Column(name="isbn", nullable=false, unique=true) private String isbn; @Column(name="autor", nullable=false) private String autor; @Column(name="description", nullable=true) private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } public String getAutor() { return autor; } public void setAutor(String autor) { this.autor = autor; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
Listagem 2. Classe Livro com anotações JPA

Utilizando o H2, o banco de dados será sempre criado quando a aplicação for executada, o que facilita o desenvolvimento, pois não é necessária nenhuma configuração inicial para usar a aplicação. Por simplicidade, nesse artigo usaremos o H2 mesmo, porém o Spring Boot funciona com qualquer banco de dados que tenha um Driver JDBC.

Utilizando o Spring Data JPA é possível criar um repositório para a classe Livro: este é uma interface que contém diversos métodos pré-implementados para a manipulação de dados de uma entidade como métodos para salvar, deletar, listar e recuperar pelo o ID da classe. Para criar essa interface basta estender a interface JpaRepository; os tipos passados são a classe da entidade usada (no caso a classe Livro) e o tipo do atributo que é o identificador dessa classe (que neste caso é um Long).

Além disso, o programador pode criar diversos métodos específicos de busca, para isso basta seguir o padrão de nomeação dos métodos como, por exemplo, findByNomeAtributo. A Listagem 3 mostra o código dessa interface.

package com.devmedia.mvc.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import com.devmedia.mvc.entity.Livro; public interface LivroRepository extends JpaRepository<Livro, Long> { /** * Encontra todos os livros de um mesmo autor. * * @param autor * @return lista de livros */ List<Livro> findByAutor(String autor); /** * Encontra um livro a partir do seu título. * Retorna uma lista pois podem existir * mais de um livro com mesmo título. * * @param titulo * @return lista de livros */ List<Livro> findByTitulo(String titulo); /** * Encontra um livro a partir de seu isbn, como o isbn é único, apenas um livro pode ser encontrado. * * @param isbn * @return livro */ Livro findByIsbn(String isbn); }
Listagem 3. Classe repositório da entidade Livro

Verifiquem que foram adicionados três métodos novos para busca:

A classe Controller é bastante simples, primeiro é adicionada a anotação @Controller para indicar que a classe é um controlador, e a anotação @RequestMapping, que indica o caminho para acessar esse controlador. É adicionado um atributo do tipo LivroRepository, que é o repositório criado na Listagem 3, onde o próprio Spring fará a injeção dessa dependência. Além disso, existem dois métodos: um para listar os livros de um determinado autor e que será acessado quando a requisição para esse controlador for do tipo GET, e o método para adicionar um livro, que será acessado quando a requisição for do tipo POST. A Listagem 4 mostra o código dessa classe.

package com.devmedia.mvc.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.devmedia.mvc.entity.Livro; import com.devmedia.mvc.repository.LivroRepository; import java.util.List; @Controller @RequestMapping("/") public class LivroController { private LivroRepository livroRepository; @Autowired public LivroController( LivroRepository livroRepository) { this.livroRepository = livroRepository; } @RequestMapping(value = "/", method = RequestMethod.GET) public String listaLivros(@PathVariable("autor") String autor, Model model) { List<Livro> listaLivros = livroRepository.findByAutor(autor); if (listaLivros != null) { model.addAttribute("livros", listaLivros); } return "listaLivros"; } @RequestMapping(value = "/", method = RequestMethod.POST) public String adicionaLivroAutor(@PathVariable("autor") String autor, Livro livro) { livro.setAutor(autor); livroRepository.save(livro); return "redirect:/"; } }
Listagem 4. Controller da classe Livro

O método listaLivros é bastante simples, pois ele será acessado quando a requisição para esse controlador for do tipo GET e receberá como parâmetro o nome de um autor, por onde é feita uma busca no banco de dados para encontrar todos os livros desse autor. Caso sejam encontrados livros, essa lista é adicionada no model para que seja mostrada depois na tela da aplicação, o que será mostrado na próxima listagem.

O método adicionaLivroAutor é parecido com o anterior, pois ele será acessado quando a requisição para o controlador for do tipo POST e recebe também como parâmetro o nome de um autor. A diferença é que, além disso, ele também deve receber os dados de um livro, o que será feito por um formulário, que também será mostrado na próxima listagem. O livro enviado pela requisição será cadastrado no banco de dados utilizando a interface repositório. Por fim, esse método redireciona para o método listaLivros, e o livro que acabou de ser cadastrado já será exibido na tela.

Com todas as classes para acesso e inserção dos dados, basta criar a visão e para isso foi criado o arquivo listaLivros.html na pasta src/main/resources/templates. Essa tela tem duas partes, sendo a primeira uma lista dos livros do autor que foi recuperado a partir da URL de acesso, que deve ser feita no formato http://localhost:8080/nomeAutor. Se não existir nenhum livro cadastrado para o autor será mostrado o texto “Nenhum Livro Cadastrado para esse autor”, caso contrário será mostrada a lista de livro. A segunda parte da tela é um formulário de cadastro de livros com os dados Titulo, ISBN e descrição, e o autor é cadastrado com o nome do autor da página acessada. A Listagem 5 mostra o código dessa tela.

<html> <head> <title>Reading List</title> </head> <body> <h2>Lista de Livros por Autor</h2> <div th:unless="${#lists.isEmpty(livros)}"> <dl th:each="livro : $"> <dt class="bookHeadline"> <span th:text="${livro.titulo}">Title</span> by <span th:text="${livro.autor}">Author</span> (ISBN: <span th:text="${livro.isbn}">ISBN</span>) </dt> <dd class="bookDescription"> <span th:if="${livro.description}" th:text="${livro.description}" >Description</span> <span th:if="${livro.description eq null}"> Nenhuma descrição foi adicionada para esse livro!</span> </dd> </dl> </div> <div th:if="${#lists.isEmpty(livros)}"> <p>Nenhum Livro Cadastrado para esse autor</p> </div> <hr /> <h3>Adicione um novo livro para o autor:</h3> <form method="POST"> <label for="title">Title:</label> <input type="text" name="titulo" size="50"></input><br /> <label for="isbn">ISBN:</label> <input type="text" name="isbn" size="15"></input><br /> <label for="description">Description:</label><br /> <textarea name="description" cols="80" rows="5"> </textarea> <br /> <input type="submit"></input> </form> </body> </html>
Listagem 5. Visão para o cadastro e Listagem de Livros

Por último, é necessário criar a classe que inicializa a aplicação com o Spring Boot e cria o banco de dados H2 e o Apache Tomcat. A única configuração necessária nesse arquivo é dizer onde estarão as entidades, os repositórios e os controladores (se tudo estiver no mesmo pacote isso não é necessário). A Listagem 6 mostra o código dessa classe.

package com.devmedia.mvc.application; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.orm.jpa.EntityScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication @EntityScan(basePackages = { "com.devmedia.mvc.entity" }) @EnableJpaRepositories(basePackages = { "com.devmedia.mvc.repository" }) @ComponentScan(basePackages = {"com.devmedia.mvc.controller"}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Listagem 6. Classe que inicializa a aplicação

Para rodar a aplicação no Eclipse basta executar a classe Application e esperar o Tomcat ser inicializado. Assim que isso acontecer, acesse de qualquer browser o endereço http://localhost:8080/nomeDeAutor. Com isso será mostrada a tela da aplicação desenvolvida. Inicialmente a lista de livros estará vazia, mas você pode cadastrar quantos livros quiser utilizando o formulário que está na parte de baixo da tela. A Figura 1 mostra como exemplo a aplicação sendo executada com o nome do autor Eduardo: vejam que existem dois livros cadastrados para esse autor e abaixo aparece o formulário, onde podem ser cadastrados mais livros para este. O endereço de acesso para essa página foi http://localhost:8080/Eduardo.

Figura 1. Tela da Aplicação desenvolvida com a lista de livros do autor Eduardo.

Caso a aplicação seja acessada com o nome de outro autor é exibida a lista correspondente a este, como mostra a Figura 2, onde a página foi acessada passando o nome Luiz como nome do autor. A aplicação diferencia o autor que está sendo acessado pela URL que foi acessada: nesse caso o autor é o Luiz, pois o endereço usado na requisição foi http://localhost:8080/Luiz.

Figura 2. Tela da aplicação desenvolvida com a lista de livros do autor Luiz

Esse artigo mostrou como desenvolver uma aplicação simples com o Spring Boot utilizando os frameworks Spring Data e Spring MVC. Nessa aplicação não foi necessária praticamente nenhuma configuração, nem de banco de dados, nem de arquivos XML e praticamente nenhuma anotação de configuração. Esse é o grande objetivo do Spring Boot, que permite ao o programador focar apenas no desenvolvimento dos requisitos funcionais da aplicação, evitando o trabalho repetitivo que são necessários em todos os projetos.


Saiu na DevMedia!

  • O que é UML?: Neste curso entenderemos o que é UML, a Unified Modeling Language, bem como quais são os principais diagramas que podemos criar com essa linguagem.
  • Seu banco está protegido de SQL Injection?: E se o usuário conseguir enviar um trecho de SQL com o qual ele consiga roubar ou danificar os dados do banco? Saiba neste DevCast o que é SQL Injection e, mais importante, como proteger a sua aplicação deste ataque tão comum.
  • Primeiros passos com Spring Security: Um requisito fundamental no desenvolvimento de qualquer aplicação é a segurança. Pensando na importância desse assunto, neste curso você aprenderá a adicionar segurança em aplicações web ao mesmo tempo em que dá os primeiros passos com o framework Spring Security.

Saiba mais sobre Spring e Java ;)

  • Guia de Spring Framework: Neste Guia de Referência você encontrará o conteúdo que precisa para aprender a desenvolver aplicações utilizando o Spring Framework e seus subprojetos.
  • O que é Spring MVC?: Neste curso você aprenderá o que é o Spring MVC, framework criado com o intuito de simplificar e trazer mais produtividade ao desenvolvimento de aplicações Web
  • Segurança com Spring Security: Durante este vídeo será demonstrado como trabalhar com o Spring Security em uma aplicação com o Spring MVC. O Spring Security é um projeto do Spring Framework com a finalidade de adicionar segurança em aplicações Java Web.

Artigos relacionados