Até pouco tempo o Java possuia um ciclo atualizações grande, entre o lançamento da versão 5 (07/2004) até a versão 9 (07/2017) foram treze anos. A partir desta nona versão o ciclo foi alterado e agora há lançamento de novas versões duas vezes ao ano, nos meses de março e setembro, por isso que entre a versão 9 e a 12 (a mais atual), o intervalo é de 1 ano e meio.
Este grande intervalo entre as antigas versões era necessário devido ao seu complexo processo de atualização. Visando estabilidade e segurança, cada versão passava por vários testes e interações até serem liberados para os usuários. É preciso dizer que infelizmente nem sempre a versão lançada fornecia estabilidade e segurança. Qualquer usuário que já tenha instalado o Java no seu computador sabe que mensalmente havia alguma atualização de segurança.
Tudo isso dificultava a adição de novos recursos na linguagem, o que permitiu o destaque de alguns frameworks. Dentre vários, o que mais ganhou os holofotes foi o Spring. Criado para aplicações Java EE, hoje o Spring é um projeto que contém várias bibliotecas, de segurança (Spring Security) à big data (Spring XD).
Dentre todos os projetos abaixo da asa do Spring, o que mais se destaca é o Spring Boot.
Curso PHP - Orientação a Objetos - Parte 1
Conhecer o cursoSpring Boot
Todo desenvolvedor Java sabe que as vezes configurar uma aplicação pode ser um trabalho hercúleo. Às vezes são horas de configurações e apenas alguns minutos de codificação.
O Spring Boot veio para resolver esta situação. Utilizando como base o Core do Spring, o Spring Boot trabalha seguindo convenções e configurações padrão para abstrair o máximo possível das configurações necessárias de uma aplicação Spring.
Basta você definir qual tipo de aplicação deseja criar, escolher o starter apropriado, que o Spring se encarregará as configurações básicas necessárias da aplicação que escolheu.
O starter escolhido contém todas as dependências que sua aplicação necessita para funcionar. Então não é necessário nem se preocupar com as dependências do projeto.
Mesmo funcionando através de convenção, caso queira, é possível customizar todas as configurações da aplicação, de forma simples ou complexa, dependendo do que pretende fazer.
O maior benefício deste framework é que permite o desenvolvedor se preocupar com o ponto mais importante da aplicação, as regras de negócio.
Para demonstrar esta facilidade, neste artigo veremos como definir uma API REST utilizando este framework.
Criando a aplicação
Existem algumas formas de criar uma aplicação Spring Boot. Ela pode ser criada no Eclipse, utilizando a IDE Spring Tool Suíte, que também é fornecida como plug-in para o Eclipse, Visual Studio Conde e Atom. Ou mesmo no site Spring Initializr.
No momento estou utilizando uma máquina Mac OS X com o Visual Studio Code instalando, assim vou criar a aplicação inicial utilizando a extensão deste editor fornecida pela Microsoft:
Ao criar, a aplicação terá a estrutura abaixo:
Neste projeto os pontos mais importantes são o arquivo pom.xml, que contém o starter web e das dependências que definimos:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.treinaweb</groupId>
<artifactId>springbootapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
E o arquivo DemoApplication.java que contém o nosso método main
:
package br.com.treinaweb.springbootapiexemplo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Caso não esteja habituado com o Spring Boot, pode estranhar a criação de um método main
em uma aplicação web. Isso ocorre porque este método será responsável por carregar todas dependências embutidas na aplicação, isso inclui o servidor web (o Tomcat).
Desta forma, para esta aplicação web não é necessário definir um arquivo war e adicioná-lo no servidor.
Caso execute a aplicação agora, notará que o servidor embutido será iniciado e a aplicação já poderá ser utilizada. Só que no momento ela não possui nada.
Criando a entidade e repositório
Uma das conversões que o Spring Boot adota é que ele reconhece como componentes da aplicação, todas as classes definidas no mesmo pacote da classe que contém o método main
ou em um package “abaixo” do package.
Ou seja, como a nossa classe está definida no pacote br.com.treinaweb.springbootapiexemplo
, qualquer classe definida nele ou em um “subpackage” dele, será reconhecida pelo Spring Boot. Desta forma, vamos definir a nossa entidade no pacote br.com.treinaweb.springbootapiexemplo.entity
:
package br.com.treinaweb.springbootapi.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Pessoa
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(nullable = false)
private String nome;
public long getId() {
return id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setId(long id) {
this.id = id;
}
}
Já o repositório ficará no pacote br.com.treinaweb.springbootapi.repository
:
package br.com.treinaweb.springbootapi.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import br.com.treinaweb.springbootapi.entity.Pessoa;
@Repository
public interface PessoaRepository extends JpaRepository<Pessoa, Long> { }
Note que para o repositório foi necessário apenas estender da interface JpaRepository
do Spring Data. Esta interface possui métodos para as operações padrão de um CRUD.
Aproveitando que definimos o repositório, vamos configurar o banco de dados. Esta configuração deve ser definida no arquivo application.properties:
## Database Properties
spring.datasource.url = jdbc:mysql://localhost:3306/treinaweb?useSSL=false
spring.datasource.username = root
spring.datasource.password = root
## Hibernate Properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update
Alguns comportamentos do Spring Boot podem ser alterados com configurações neste arquivo. Vamos deixar apenas as configurações do banco.
Controller
Por fim, vamos definir o controller da nossa aplicação. Assim como antes, ele será definido em um sub-package do package padrão da aplicação:
package br.com.treinaweb.springbootapi.controller;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import br.com.treinaweb.springbootapi.entity.Pessoa;
import br.com.treinaweb.springbootapi.repository.PessoaRepository;
@RestController
public class PessoaController {
@Autowired
private PessoaRepository _pessoaRepository;
@RequestMapping(value = "/pessoa", method = RequestMethod.GET)
public List<Pessoa> Get() {
return _pessoaRepository.findAll();
}
@RequestMapping(value = "/pessoa/{id}", method = RequestMethod.GET)
public ResponseEntity<Pessoa> GetById(@PathVariable(value = "id") long id)
{
Optional<Pessoa> pessoa = _pessoaRepository.findById(id);
if(pessoa.isPresent())
return new ResponseEntity<Pessoa>(pessoa.get(), HttpStatus.OK);
else
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@RequestMapping(value = "/pessoa", method = RequestMethod.POST)
public Pessoa Post(@Valid @RequestBody Pessoa pessoa)
{
return _pessoaRepository.save(pessoa);
}
@RequestMapping(value = "/pessoa/{id}", method = RequestMethod.PUT)
public ResponseEntity<Pessoa> Put(@PathVariable(value = "id") long id, @Valid @RequestBody Pessoa newPessoa)
{
Optional<Pessoa> oldPessoa = _pessoaRepository.findById(id);
if(oldPessoa.isPresent()){
Pessoa pessoa = oldPessoa.get();
pessoa.setNome(newPessoa.getNome());
_pessoaRepository.save(pessoa);
return new ResponseEntity<Pessoa>(pessoa, HttpStatus.OK);
}
else
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@RequestMapping(value = "/pessoa/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Object> Delete(@PathVariable(value = "id") long id)
{
Optional<Pessoa> pessoa = _pessoaRepository.findById(id);
if(pessoa.isPresent()){
_pessoaRepository.delete(pessoa.get());
return new ResponseEntity<>(HttpStatus.OK);
}
else
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
Na classe acima, é importante destacar alguns detalhes:
- A anotação
@RestController
permite definir um controller com características REST; - A anotação
@Autowired
delega ao Spring Boot a inicialização do objeto; - A anotação
@RequestMapping
permite definir uma rota. Caso não seja informado o método HTTP da rota, ela será definida para todos os métodos. - A anotação
@PathVariable
indica que o valor da variável virá de uma informação da rota; - A anotação
@RequestBody
indica que o valor do objeto virá do corpo da requisição; - E a anotação
@Valid
indica que os dados recebidos devem ser validados.
Pronto, a nossa aplicação pode ser utilizada.
Para testar os endpoints, vamos utilizar o Postman:
Post
Get
Get id
Put
Conclusão
O Spring Boot facilita muito a criação de aplicações web em Java, caso seja um desenvolvedor desta linguagem, é quase uma obrigação conhecê-lo.
Você pode baixar a aplicação deste artigo no meu Github.