Artigos de Tecnologia e Negócios > Programação

Primeiros passos com o Spring Framework

Elias Ribeiro
Elias Ribeiro
Imagem de destaque

Fomos chamados para implementar um sistema em uma loja de produtos eletrônicos que ajudasse no controle das quantidades de produto que temos em loja.

Começamos alinhando quais eram as operações que o cliente esperava poder realizar nesse controle de produtos.

Segundo ele, era preciso primeiro inserir um produto, depois precisavam poder sempre ver quantos produtos haviam lá.

Então começamos desenvolvendo esse código para adicionar produto.

public void adicionarProduto(Produto produto) {
        try {
            String sql = "insert into produtos (nome,quantidade) values (?,?)";
            PreparedStatement stmt = connection.prepareStatement(sql);
            stmt.setString(1, produto.getNome());
            stmt.setString(2, produto.getQuantidade());
            stmt.execute();
            stmt.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

Neste caso, usamos Servlets, porém percebemos que o código acabou ficando muito grande e não fizemos nem metade das coisas que o cliente pediu. Resolvemos apenas a parte de inserção de produtos, mas ainda faltam as features de ver, atualizar e remover.

Se considerarmos isso, ao final teríamos um código imenso e, consequentemente, prejudicaríamos a legibilidade e manutenção.

E como poderíamos resolver esse problema?

Utilizando Spring Framework

Uma forma mais elegante de resolver esse problema de códigos compridos e pouco legíveis pode ser utilizando o Spring.

O Spring é um framework que facilita bastante o desenvolvimento, ou seja com ele nós temos a legibilidade de código maior, implementações com menos código, facilidade na manutenção de código. Com isso teremos uma entrega mais rápida também.

Para começar, precisamos antes de mais nada criar um projeto.

Criando o projeto

Para criar o nosso projeto temos que acessar o site do spring e colocar as dependências  que queremos, mas quais queremos?

Nossa aplicação tem que ser web, para ser um acesso mais dinâmico, ou seja podemos acessar de qualquer dispositivo.

Como toda a aplicação web ela tem dados, e esses dados precisam ser guardados em algum lugar então precisamos de um banco de dados.

Tem que fazer o mapeamento das classes para o banco, para agilizando o processo em relação ao banco.

Então vamos usar a dependência Web para ser uma aplicação web que contenha o tomcat já incluso para que a gente não tenha que fazer toda a configuração.

Mysql vai ser o banco de dados que vamos utilizar nesta aplicação, pois tenho que salvar em algum lugar os dados. Com isso além de salvar, podemos alterar, remover, ou pesquisar por dados que estão dentro do banco.

JPA para persistir nossas classes no banco de dados, pois assim vamos fazer o mapeamento das nossas classes e fazer a criação de maneira automática.

Vamos nomear o group como br.com.sistema para ser o grupo da nossa aplicação e definir o artifact como usuários. Ficando da seguinte maneira:

Com isto feito vamos gerar o projeto clicando em Generate Project e vai ser gerado um zip, mas o que precisamos fazer com ele? Precisamos extrair para pegar o projeto que acabamos de criar e importar ele para algum lugar. Vamos importar para a IDE.

Configurando o projeto

Com essa importação já feita vamos rodar o projeto para ver se está tudo ok. Mas ao rodar tivemos um erro:

Por que este erro acontece, sendo que configuramos o nosso projeto de maneira correta? Note que o erro foi em configurar o DataSource, pois faltam alguns dados dentro dele.

Acontece pois quando colocamos a dependência do Mysql temos que configurar ele na nossa aplicação. Mas em qual lugar devemos fazer essa configuração?

Temos que fazer no application.properties, é lá que ficam todas as configurações de propriedade da aplicação.

Agora vamos pegar um exemplo parecido com o que está na documentação do spring. A primeira coisa a ser feita é passar a url.

Na nossa url vamos passar o tipo do banco, que é mysql, e a porta onde roda o banco, e vamos fazer um parâmetro chamado createDatabaseIfNotExist como true, para que ele crie o banco se não existir.

Temos também a questão de horários então vamos deixar o serverTimezone como UTC, para que não ocorra nenhum erro.

Até o momento estamos com o arquivo application.properties assim:

spring.datasource.url=jdbc:mysql://localhost:3306/produtos?createDatabaseIfNotExist=true&serverTimezone=UTC

Vamos iniciar o projeto para ver se está tudo ok. Bem ao rodar teremos um outro erro, este erro nós diz que estamos com a permissão negada.

Bem, falta a gente passar o usuário e senha para se logar, por que assim vamos conseguir acesso ao banco, sem isso sempre vai retornar acesso negado. Como passamos o usuário e senha?

Teremos que editar o  application.properties e passar o nosso usuário e senha do banco de dados. No meu caso a não tenho senha no banco, então eu deixo o campo vazio.

spring.datasource.username=elias
spring.datasource.password=

Além disso para ficar atualizando nossa entidades temos que definir a propriedade do ddl-auto. Bem nós vamos definir a propriedade de update, para que sempre que nossas entidades sejam atualizadas, o banco atualize também.

spring.jpa.hibernate.ddl-auto=update

Mas o que são essas entidades?

Entidades

Entidade são modelos da nossa tabela que vão estar no banco de dados. Mas como assim um modelo vai ser uma tabela no nosso banco de dados?  Quando nós configuramos o hibernate na nossa aplicação, ele faz a persistência dos dados no banco de dado ou seja o atributos que criamos na classe.

Porém como é possível saber que uma classe é uma entidade? Sabemos que em java existem anotações, então vamos procurar uma anotação para dizer que a classe é uma entidade.Ao abrir o link da documentação, logo olhamos a anotação @Entity.

Como o @Entity funciona? Ele mapeia a classe para o banco, porém quando fazemos essa anotação devemos mapear o ID da classe. Mas como é feito este ID? Para gerar o id passamos outra anotação chamada @Id.  Porém como este Id é feito? De um em um, dois em dois?

Para saber a quantidade de incremento que vamos passar teremos que utilizar outra anotação chamada @GeneraredValue que vai nos gerar um valor, mas isto não resolve nosso problema ainda, porque não sabemos o quanto que ele incrementa, para resolver isso vamos usar o parâmetro (strategy = GenerationType.IDENTITY) que incrementa de um em um, assim o id não se repete.

Sabendo disso tudo, precisamos alguma coisa para mapear os atributos de Nome e Quantidade, como nome e quantidade estão ligados a um produto, então vamos criar um pacote chamado modelo. Dentro desse pacote também criaremos uma classe produto com esses atributos e mapear como uma entidade.

@Entity
public class Produto {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String nome;
    private double quantidade;

//getters omitidos
}

Agora criamos esses atributos no banco de dados, mas ainda não inserimos, pesquisamos ou alteramos nada até o momento. E como isso pode ser feito? Será que dá para fazer direto na Entidade?

Repositório

Quando pensamos em inserir, pesquisar, alterar dados, logo pensamos em DAOS ou até mesmo em comandos SQL, isto é muito trabalhoso. Mas então como vamos fazer a persistência dos dados? Na classe de entidade?

Iremos fazer isto nós repositórios, pois facilita demais o processo do CRUD. Por boas práticas não vamos fazer dentro da classe entidade.

O repositório tem uma interface chamada CrudRepository que nos permite fazer um CRUD dos nossos dados, sem que a gente escreva uma linha de código.

Precisamos criar um pacote chamado repositório e uma interface chamada ProdutosRepository.

Nesta interface o que precisamos para fazer ela fazer essa persistência de dados ? Temos que estender a interface CrudRepository e passar a entidade que queremos e o tipo do ID dela. Com isto o nosso CRUD está pronto.

public interface ProdutosRepository extends CrudRepository<Produto, Long> {}

Porém como vamos controlar a aplicação para saber o que vamos fazer?

Controle

Os controles são o intermediário da nossa aplicação, ou seja ele fazem a comunicação com a parte frontal da nossa aplicação e com o banco de dados. Então ele pode fazer a inserção no banco de dados. Fazemos o controle da aplicação conforme o protocolo http. Como podemos ver o http tem os métodos: POST, GET. Vamos usar eles como para controlar nossa aplicação?

Nós vamos fazer esse controle por meio de anotações, mapeando com @GetMapping, @PostMapping para seguir o protocolo http. Beleza, agora fazemos para que serve essas anotações e o protocolo http. Mas como podemos fazer isto na aplicação ?

Bem podemos criar um pacote chamado controller e uma classe chamada ProdutoController para controlar o fluxo da nossa aplicação. Mas se usamos a anotação @Entity para dizer que a classe Produto é uma entidade, temos que usar alguma anotação para o controle?

Podemos fazer duas anotações @Controller e o @RestController.  O @Controller é usado para sinalizar que é uma classe do Spring MVC e bastante usado para redirecionar views. Já o @RestController faz automaticamente tudo o que o @Controller faz é retornar tudo em JSON e não precisamos utilizar a anotação @ResponseBody, pois, já está contido nele, então vamos usar o @RestController.

Temos que mapear a nossa classe com o @RestController ficando dessa maneira.

@RestController
public class ProdutoController{

}

Se rodarmos o projeto nada acontece ainda, pois não mapeamos a url do controller, precisamos fazer isto, de qual maneira?

Se você pensou em uma anotação acertou, temos que usar uma anotação para fazer isto, está anotação vai ser a @RequestMapping(“url que queremos”).

No nosso caso vamos fazer o na url (/api/produto) ficando da seguinte maneira:

@RequestMapping("/api/produto/")
@RestController
public class ProdutoController{

}

Bem fazendo dessa maneira ainda não vai nos retornar nada, pois não fizemos nenhum tipo de mapeamento de retorno. Como fazer este mapeamento? Utilizando o http ao nosso favor e fazendo o mapeamento com as anotações @GetMapping, @PostMapping.

@RequestMapping("/api/produto/")
@RestController
public class ProdutoController{
    @GetMapping()
    @PostMapping()
}

Mas assim como o RequestMapping temos que passar um caminho para cada anotação, só que elas tem um coisa de diferente que é ao invés de passar direto temos que utilizar o parâmetro value e o mapeamento delas.

@RequestMapping("/api/produto/")
@RestController
public class ProdutoController{
    @GetMapping(value = “listarProdutos”)
    @PostMapping(value = “inserirProdutos”)

}

Com isto feito percebemos que temos erros :

Este erro dá, pois não temos um alguma coisa que faça uso dessas anotações, o que podemos fazer para utilizar elas?

Uma boa ideia seria utilizar métodos com retornos para ficar mais simples de se utilizar, bem se temos que listar usuários é criar um método que contenha um retorno de uma lista de usuários.

@GetMapping(value = “listarProdutos”)
public List<Produto> listarProdutos(){

}

Mas o que o que vamos retornar? Bem lembra do nosso repositório lá temos bastante métodos e um deles é o findAll que busca todos os elementos que estão no banco.

Temos que fazer a injeção de dependência do repositório, podemos fazer está injeção pelo construtor, mas vamos optar por fazer com uma anotação chamada @Autowired  e utilizar os métodos do repositório.

@Autowired
private ProdutoRepository produtoRepositorio;

Bem vamos testar isto vamos utilizar o método findAll para ver se ele nos retorna os registros do banco de dados.

@GetMapping(value = “listarProdutos”)
public List<Produto> listarProdutos(){
    return produtoRepositorio.findAll();
 }

Bem mas na hora que formos testar queremos que nosso retorno um JSON, mas como pode ser feito isto ?

Existe o produces que é o valor que a gente vai produzir, e o consumes que é o valor que a gente vai consumir. Para o GetMapping nosso vamos produzir o valor em JSON, dessa maneira.

@GetMapping(value = “listarProdutos”, produces = MediaType.APPLICATION_JSON_VALUE)
public List<Produto> listarProdutos(){
    return  (List<Produto>) produtoRepositorio.findAll();
 }

Agora que sabemos disso no nosso @PostMapping como seria?  Com o PostMapping seria diferente, pois, nele nós teríamos consumir os dados da parte frontal para fazer a inserção no banco de dados, mas para enviar esses dados da parte frontal da aplicação pro controle, temos que fazer de qual maneira?

Temos uma anotação chamada @RequestBody para enviar pelo o corpo da requisição isso os dados e nós vamos utilizar ela.

Mas qual o tipo de método que eu crio para isso? Bem vamos criar um ResponseEntity para retornar as respostas conforme http status code que é uma das boas práticas que devemos seguir.

@PostMapping(value = “inserirProdutos”, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity adicionarProduto(@RequestBody Produto produto){
    produtoRepositorio.save(user);
return ResponseEntity.status(201).build();
}

Conclusão

Tivemos o problema em relação aos DAOS serem muito longos e resolvemos utilizar o Spring de outra maneira.

Quando utilizamos o Spring temos as vantagens do framework e conseguimos fazer um CRUD de maneira rápida.

E aí, o que achou do post? Fica até mais fácil trabalhar com o spring agora, não acha? Se quiser continuar estudando sobre o assunto. Temos uma formação Java que fala mais sobre o spring continue aprendendo!

Leia também:

Artigos de Tecnologia e Negócios > Programação

Cursos profissionais de Programação é na Alura, comece agora!

  • 970 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 970 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 970 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 970 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana