JavaRush /Blogue Java /Random-PT /Introdução ao Maven, Spring, MySQL, Hibernate e a primeir...
Макс
Nível 41

Introdução ao Maven, Spring, MySQL, Hibernate e a primeira aplicação CRUD (parte 1)

Publicado no grupo Random-PT
Boa tarde. Neste artigo gostaria de compartilhar meu primeiro encontro com coisas como Maven, Spring, Hibernate, MySQL e Tomcat no processo de criação de uma aplicação CRUD simples. Esta é a primeira parte de 4. O artigo é destinado principalmente àqueles que já completaram 30-40 níveis aqui, mas ainda não se aventuraram além do Java puro e estão apenas começando (ou prestes a começar) a entrar no mundo aberto com todas essas tecnologias, frameworks e outras palavras desconhecidas. Introdução ao Maven, Spring, MySQL, Hibernate e a primeira aplicação CRUD (parte 1) - 1

Contente:

Introdução

Comecei a me familiarizar com tecnologias e frameworks que eram novos para mim, estudando vários exemplos em que eram usados, porque geralmente entendo melhor algo quando o vejo em ação usando um exemplo de aplicativo completo. Normalmente, esses exemplos são aplicativos CRUD ( C reate, Read , Update , D elete), a Internet está cheia de exemplos desse tipo com vários graus de complexidade. O problema é que eles geralmente não explicam em detalhes como, o que e por que foi feito ali, por que tal ou tal dependência foi adicionada, por que tal ou tal classe é necessária, etc. Na maioria dos casos, eles pegam um aplicativo totalmente finalizado, com um arquivo POM final, com versões finais das classes, e simplesmente percorrem cada uma delas, sem focar nas pequenas coisas que provavelmente parecem óbvias para uma pessoa experiente. Eu olhei muitos desses exemplos e geralmente fica claro como tudo funciona, mas como eles chegaram a isso não está totalmente claro. Portanto, decidi que tal exemplo seria útil não da posição de um desenvolvedor experiente, mas da posição de um iniciante que nunca lidou com Spring, Hibernate e outras coisas.
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 2
Tentarei descrever com o máximo de detalhes possível (tanto quanto meu entendimento me permite) todo o meu caminho de criação de um aplicativo CRUD, começando com algo no nível mais simples do Hello World. Em primeiro lugar, faço isso por mim mesmo, porque quando você tenta descrever, contar, explicar algo, fica muito melhor absorvido e organizado na sua cabeça. Mas se isso for útil para alguém e ajudá-lo a descobrir algo, ficarei muito feliz. Neste exemplo, vamos tentar criar uma aplicação CRUD simples usando Maven , Tomcat , Spring , Hibernate e MySQL . Etapas preliminares como instalação do Maven , MySQL , utilização da versão Ultimate da ideia, etc. Acho que não há necessidade de descrever em detalhes, não deve haver problemas com isso. Vale ressaltar que neste exemplo a configuração será feita utilizando classes Java (chamadas JavaConfig) sem utilizar xml.

Criando um Projeto

Então, como sou novato, não usaremos nenhum arquétipo obscuro. O Spring Initializr ainda parece muito assustador. Portanto, criaremos o projeto Maven simples mais comum. Não tenho nome de domínio, então no groupid escreverei apenas testgroup, e no artefato escreverei o nome, por exemplo, filmography(esta será uma lista de filmes). Criamos um projeto e escolhemos Enable auto-importquando a ideia o sugere. Graças a isso, toda vez que fizermos alguma alteração no arquivo POM (Project Object Model, este arquivo descreve toda a estrutura do projeto Maven), tudo será imediatamente aplicado automaticamente ao projeto. As bibliotecas serão retiradas de nosso repositório local se já as tivermos, ou se usarmos algumas dependências novas com as quais não lidamos antes, o Maven simplesmente irá baixá-las via Internet a partir do repositório central. O Maven também possui uma função para baixar fontes e documentação (Download Sources and/ou Documentation). Também é muito conveniente, se algo não estiver claro com alguma classe ou método, você pode ir até o código fonte e ver como tudo funciona lá dentro. Vamos adicionar alguns detalhes. Esta será uma aplicação web e usaremos o Tomcat . Para implantar um aplicativo no Tomcat, você precisa transferi-lo para lá na forma de um arquivo war (Web Application Resource, um formato especial para aplicativos da web). Para fazer isso, adicione a seguinte linha ao arquivo POM para que o aplicativo seja compilado em um arquivo war:
<packaging>war</packaging>
Bem, você também precisará de um diretório especial para fontes da web; no nosso caso, haverá páginas jsp e alguns recursos da web. Vamos criar um maindiretório webapp. Ele deve ser chamado exatamente assim e localizado exatamente mainda mesma maneira que java, resourcesporque esta é a estrutura de diretório padrão do Maven. Depois de instalar o pacote ware determinar que se trata de um projeto web, o diretório webappserá automaticamente marcado como fontes de aplicativos Web (haverá um ponto azul nele) e tudo relacionado à web será pesquisado nesta pasta. E um momento. Por padrão, o Maven usa a linguagem versão 1.5, mas eu quero usar, por exemplo, a versão 1.8 - Java 8 (Você pode pegar 10, ou 11, mas ainda não há planos de usar nenhum recurso daí, então que seja 8 ). Isso pode ser resolvido de forma muito simples, escrevemos no Google algo como “Maven java 8” e vemos o que precisa ser adicionado ao arquivo POM para que o Maven compile nossas classes para a versão necessária. Como resultado, temos o seguinte: Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 3

Conexão Spring MVC

Você tem que começar em algum lugar. De acordo com o plano, conectaremos o banco de dados e usaremos o Hibernate, mas tudo isso parece um pouco assustador por enquanto. Precisamos fazer algo mais simples primeiro. Spring MVC, isso já é melhor, já conhecemos o padrão MVC há muito tempo, ele foi utilizado em metade das grandes tarefas do curso. A partir daqui começaremos a dançar. Para criar uma aplicação web com Spring MVC, também precisamos de uma API Servlet, ou seja, aquela coisa com a ajuda da qual ocorrerá a interação solicitação-resposta. Vamos tentar conectar isso. Vamos ao Google, procuramos as dependências necessárias no repositório Maven e as adicionamos ao arquivo pom.xml. Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 4Na seção Bibliotecas Externas você pode ver que não apenas o spring-webmvc foi carregado , mas também um monte de outras coisas. Aqueles. não precisamos incluir dependências adicionais para spring core , context , beans , etc. que precisamos, tudo o que precisávamos foi obtido junto com spring-webmvc .

Precisamos fazer um pequeno aviso. Geralmente é recomendado adicionar uma dependência separadamente para cada biblioteca usada, mesmo que elas já estejam empacotadas com aquelas já adicionadas, porque isso pode ajudar a evitar alguns problemas e falhas.

Um exemplo simples. Digamos que adicionamos uma dependência que usa alguma API e, ao mesmo tempo, ela irá gerar algum tipo de implementação para esta API. E então adicionamos outra dependência que usa a mesma API e também puxa algumas de suas implementações para isso, mas desta vez é diferente. Assim, teremos 2 implementações diferentes da mesma API. E se nós mesmos quisermos usar alguns métodos desta API em algum lugar, então surgirá um problema, porque o sistema não saberá qual implementação usar, ele escolherá aleatoriamente, talvez não aquela que esperávamos. E se você especificar explicitamente uma dependência para uma das implementações, então será dada prioridade a ela.

No entanto, esta não é uma recomendação tão estrita; aplica-se principalmente a grandes projetos onde são utilizadas muitas bibliotecas diferentes de empresas diferentes. Não faremos isso aqui, para não carregar muito o arquivo POM; não são esperados problemas. Mesmo assim, ainda vale a pena manter isso em mente.

Mais uma nota. O que significa provideddepender javax.servlet-api? Escopo é o escopo da dependência, providedo que significa que a dependência estará disponível na fase de compilação e teste da aplicação, mas não será arquivada. O fato é que para implantar a aplicação usaremos um contêiner de servlet, Tomcat, e ele já possui essas bibliotecas dentro, portanto não há necessidade de transferi-las para lá e sobrecarregar o arquivo com carga desnecessária. Olhando para o futuro, pelo mesmo motivo dispensaremos o método usual main, pois ele já existe dentro do Tomcat.

Criando páginas e controlador

Vamos tentar preparar algo simples agora. Primeiro, vamos criar um webappdiretório adicional, por exemplo pages, no qual nossas visualizações serão armazenadas, ou seja, páginas jsp e crie algumas páginas. Precisaremos de uma página onde futuramente será exibida uma lista de filmes, por exemplo films.jsp, e talvez possamos fazer uma página separada para edição, deixe assim editPage.jsp. Não vamos preenchê-los com nada sério por enquanto; apenas para teste, faremos um link de uma página para outra. Agora precisamos de uma classe que processe as solicitações, ou seja, controlador. Vamos adicionar um novo pacote controllere criar uma classe nele FilmController(em geral não é necessário empacotar tudo em pacotes diferentes, esta aplicação será muito pequena e simples, mas em um projeto normal pode haver muitos controladores, classes de configuração, modelos , etc., então mesmo começando com projetos pequenos, é melhor se acostumar imediatamente a fazer tudo de forma ordenada e estruturada para que não haja bagunça). Nesta aula criaremos métodos que retornarão nossas visualizações em resposta às solicitações.
package testgroup.filmography.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class FilmController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        return modelAndView;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView editPage() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("editPage");
        return modelAndView;
    }
}
Qual é o objetivo? Spring MVC tem uma coisa chamada DispatcherServlet. É como o controlador principal, todas as solicitações recebidas passam por ele e depois as repassam para um controlador específico. A anotação @Controllerapenas informa ao Spring MVC que esta classe é um controlador (bem, lógico em geral), o despachante irá verificar as anotações @RequestMappingpara chamar o método apropriado. A anotação @RequestMappingpermite definir endereços para métodos de controlador, pelos quais eles estarão disponíveis no cliente (navegador). Também pode ser aplicado à classe do controlador para definir, por assim dizer, o endereço raiz de todos os métodos. allFilms()O parâmetro do método valueé definido como " /", portanto ele será chamado imediatamente quando a combinação http://host:port/ for inserida no navegador (ou seja, por padrão é http://localhost:8080/ ou http ://127.0 .0.1:8080/ ). O parâmetro methodespecifica que tipo de solicitação é suportada (GET, POST, PUT, etc.). Como aqui só recebemos dados, GET é usado. Mais tarde, quando aparecerem métodos de adição e edição, já haverá solicitações POST. (A propósito, em vez de uma anotação @RequestMappingindicando um método, você pode usar anotações @GetMapping, @PostMappingetc. @GetMappingde forma equivalente @RequestMapping(method = RequestMethod.GET)). Em nossos métodos, criamos um objeto ModelAndViewe definimos o nome da view que precisa ser retornada.

Configuração

Vamos prosseguir para definir a configuração. configVamos criar uma classe no pacote WebConfig. Terá apenas um método que retorna um objeto do tipo ViewResolver, esta é a interface necessária para encontrar uma representação pelo nome.
package testgroup.filmography.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "testgroup.filmography")
public class WebConfig {

    @Bean
    ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
@Configurationinforma ao Spring que esta classe é uma classe de configuração e contém as definições e dependências beandos componentes. Beans são objetos gerenciados pelo Spring. A anotação é usada para definir um bean @Bean. @EnableWebMvcpermite importar a configuração do Spring MVC do arquivo WebMvcConfigurationSupport. Você também pode implementar, por exemplo, uma interface WebMvcConfigurerque possui vários métodos e personalizar tudo ao seu gosto, mas não precisamos entrar nisso ainda, as configurações padrão serão suficientes. @ComponentScaninforma ao Spring onde procurar os componentes que ele deve gerenciar, ou seja, classes marcadas com uma anotação @Componentou seus derivados, como @Controller, @Repository, @Service. Essas anotações definem automaticamente o bean de classe. No método, viewResolver()criamos sua implementação e determinamos onde exatamente procurar representações em webapp. Portanto, quando no método do controlador definimos o nome " films" a visualização será encontrada como " /pages/films.jsp" Então, temos uma classe de configuração, mas por enquanto é apenas uma espécie de classe separada, isso não afeta nossa aplicação de forma alguma . Precisamos registrar esta configuração no contexto Spring. Para isso você precisa de uma classe AbstractAnnotationConfigDispatcherServletInitializer. No pacote, configcriamos seu sucessor, digamos AppInitializer , e implementamos seus métodos.
package testgroup.filmography.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
O último método registra endereços e existem mais 2 métodos para registrar classes de configuração. As configurações da Web, onde ViewResolver's e similares são definidos, são colocadas em getServletConfigClasses(). É melhor ler sobre tudo isso na documentação e em vários guias, mas no nosso caso ainda não é necessário nos aprofundarmos nisso, o nosso, WebConfigem princípio, pode ser RootClassesdefinido em ambos, você pode até definir os dois ao mesmo tempo, ainda funcionará . Mais uma coisa. Pode haver problemas de codificação quando, ao enviar valores com caracteres russos do formulário, o resultado serão rabiscos. Para resolver este problema, adicionaremos um filtro que irá pré-processar as solicitações. Vamos para a classe AppInitializer e substituímos o método getServletFilters, no qual indicamos a codificação desejada, ela, claro, deve ser igual a qualquer outro lugar, como nas páginas e no banco de dados:
protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return new Filter[] {characterEncodingFilter};
    }
Bom, parece que está tudo configurado, você pode tentar rodar e ver o que acontece. Executar -> Executar -> Editar configurações -> Adicionar nova configuração -> Servidor Tomcat -> Local Em seguida, você precisa selecionar um artefato para implantar. A ideia em si dará uma dica : Aviso: Nenhum artefato marcado para implantação . Clique no botão consertar e selecione ...: war explodid . Ou você pode ir para Deployment -> add -> Artifact -> ...: war explodid . Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 5E você também precisa ir em Deployment e definir o campo de contexto Applecation (isso fará parte do endereço da url onde o aplicativo estará disponível no navegador) como " /". Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 6Então nosso aplicativo estará imediatamente disponível em http://localhost:8080/ (mas você também pode especificar algo lá, por exemplo " /filmography", e então você só precisará adicionar isso a todos os endereços, ou seja, por exemplo, não haverá " http://localhost:8080/edit" , mas será "http://localhost:8080/filmography/edit" ). Clique em Executar e espere até que comece. Aqui está o que descobri: Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 7tudo parece estar bem, mas há uma ressalva. O fato é que nossas páginas agora estão acessíveis ao público e podem ser acessadas diretamente escrevendo o caminho na barra de endereço. Entramos em http://localhost:8080/pages/films.jsp e agora recebemos nossa página sem o conhecimento do controlador. De alguma forma, isso não está muito correto, então criaremos um webappdiretório especial WEB-INF. O que está dentro ficará oculto ao público e só poderá ser acessado por meio de um controlador. Colocamos o diretório com nossas visualizações ( pages) em WEB-INFe, ViewResolverconsequentemente, o adicionamos ao prefixo:
viewResolver.setPrefix("/WEB-INF/pages/");
Agora obtemos nossa página em http://localhost:8080 , mas se tentarmos diretamente http://localhost:8080/WEB-INF/pages/films.jsp obteremos um erro 404. Bem, ótimo, temos o aplicação web mais simples, Hello World, como dizem. A estrutura do projeto atualmente se parece com esta:
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 8

Modelo

Já temos visualizações e um controlador, mas no MVC também existe uma 3ª letra, então para completar o quadro também adicionaremos um modelo. No pacote, modelvamos criar uma classe Film, por exemplo, com os seguintes campos: int id, String title(título), int year(ano de lançamento), String genre(gênero) e boolean watched(ou seja, você já assistiu este filme ou não).
package testgroup.filmography.model;

public class Film {
    private int id;
    private String title;
    private int year;
    private String genre;
    private boolean watched;
// + Getters and setters
}
Nada de especial, apenas uma classe comum, campos privados, getters e setters. Objetos de tais classes também são chamados POJO(Plain Old Java Object), bem, ou seja, "objeto Java simples". Vamos agora tentar criar tal objeto e exibi-lo na página. Por enquanto, não nos preocuparemos muito em como criá-lo e inicializá-lo. Para experimentar, vamos criá-lo estupidamente diretamente no controlador, por exemplo, assim:
public class FilmController {
    private static Film film;

    static {
        film = new Film();
        film.setTitle("Inception");
        film.setYear(2010);
        film.setGenre("sci-fi");
        film.setWatched(true);
    }
E adicione este objeto ao nosso ModelAndViewusando o método addObject:
@RequestMapping(method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        modelAndView.addObject("film", film);
        return modelAndView;
    }
Agora podemos exibir este objeto em nossa página. Em films.jspvez de Hello World escreveremos ${film}e o objeto correspondente ao nome do atributo " film" será substituído aqui. Vamos tentar executá-lo e ver o que aconteceu (para uma saída clara do objeto, a classe Filmfoi redefinida toString()):
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 9

Controlador de visualização de modelo

Neste estágio, parece que já temos um aplicativo Spring MVC completo. Antes de prosseguir, seria bom dar uma olhada em tudo novamente e descobrir como tudo funciona. Na Internet você encontra muitas fotos e diagramas sobre isso, gosto deste:
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 10
Quando escrevemos uma solicitação na linha do navegador, ela é aceita Dispatcher Servlet, então ele encontra um controlador adequado para processar essa solicitação HandlerMapping(esta é uma interface para selecionar um controlador, verifica qual dos controladores disponíveis possui um método que aceita tal endereço) , chama um método adequado e Controllerretorna informações sobre a visualização, então o despachante encontra a visualização desejada pelo nome usando ViewResolver'a, após o qual os dados do modelo são transferidos para esta visualização e obtemos nossa página como saída. Algo assim. Continua... Apresentando Maven, Spring, MySQL, Hibernate e o primeiro aplicativo CRUD (parte 1) Apresentando Maven, Spring, MySQL, Hibernate e o primeiro aplicativo CRUD (parte 2) Apresentando Maven, Spring, MySQL, Hibernate e o primeira aplicação CRUD (parte 3) Introdução ao Maven, Spring, MySQL, Hibernate e a primeira aplicação CRUD (parte 4)
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION