Escolar Documentos
Profissional Documentos
Cultura Documentos
Camada de visão
Prof. Denis Cople
Descrição
Utilização de ferramentas como Thymeleaf e Bootstrap na construção da camada View de uma arquitetura
MVC para Web, em sistemas baseados no framework Spring, viabilizando a criação de interfaces
responsivas e design profissional, com pouco esforço de programação.
Propósito
Definir interfaces de sistemas Web criados com o framework Spring, com grande produtividade,
obedecendo ao padrão arquitetural MVC, além da garantia de responsividade, por meio de ferramentas
como Thymeleaf e Bootstrap, as quais viabilizam a criação de interfaces com design profissional.
Preparação
Antes de começar, é necessário configurar o ambiente com a instalação do JDK, Spring Tools Suite e
NetBeans completo, em versão com suporte a projetos Maven, além de adicionar o servidor Tomcat EE na
instalação da IDE. Também será necessário acessar a internet tanto para testes quanto para o download de
artefatos via Maven. Por fim, acesse os arquivos dos projetos desenvolvidos.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 1/89
10/04/2023, 21:18 Camada de visão
Objetivos
Módulo 1
Módulo 2
Módulo 3
meeting_room
Introdução
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 2/89
10/04/2023, 21:18 Camada de visão
Na sequência, veremos como pode ser feita a integração com sistemas Spring Web, por meio de templates
do Thymeleaf, dentro de uma arquitetura MVC, de forma muito simples e concisa.
Por fim, aplicaremos o framework Bootstrap em um sistema cadastral completo, com a definição de telas
alinhadas aos melhores princípios de design e responsividade exigidos pelo mercado, além de incluir os
componentes de segurança necessários para definir um modelo de autenticação básico, integrando-se às
interfaces criadas com muita fluidez.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 3/89
10/04/2023, 21:18 Camada de visão
HTML 5
A linguagem HTML (Hypertext Markup Language) fornece a base estrutural para as páginas disponibilizadas
na Internet. Visa estruturar a página com base em tags, ou etiquetas, em que temos uma Q, segundo o perfil
de exibição, formulários de cadastro e elementos para a navegação entre páginas. Inclusive, o nome
hipertexto se refere à capacidade de navegação ao longo do texto.
Sintaxe
A sintaxe XHTML equivale ao HTML 4.0 Strict, que evoluiu para o HTML 5.
Toda página apresenta um cabeçalho (head), em que temos o título (title) apresentado no topo da janela do
navegador, ligações (link) com recursos externos, folhas de estilo e demais elementos de uso geral. Na
sequência, deve ser definido o corpo da página (body), contendo a parte visual de nosso documento.
No corpo do documento, temos elementos estruturais de texto, como a utilização de fontes padronizadas
para títulos, delimitação de parágrafos e criação de listas. Embora o HTML não diferencie maiúsculas e
minúsculas, as páginas serão validadas na W3C apenas se as tags forem escritas com letras minúsculas.
Vejamos algumas tags:
Tags Utilização
h1, h2, h3, h4, h5, Aplica a formatação padronizada para títulos, em que h1 utiliza fonte
h6 maior, e vai diminuindo com a numeração.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 4/89
10/04/2023, 21:18 Camada de visão
Tags Utilização
Tags básicas
Vejamos uma aplicação no Exemplo001.html.
HTML
content_copy
A tag meta permite definir metadados, aqui definida a página de código UTF-8, permitindo o uso de
acentuação em palavras da língua portuguesa. No HTML, também temos símbolos especiais, chamados de
entidades, que são iniciadas com ‘e comercial &’ e fechadas com ponto e vírgula, como b, representando o
símbolo de copyright.
Outro elemento é o comentário utilizado no HTML, iniciado com sinal de exclamação e duas subtrações, e
fechado com duas subtrações.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 5/89
10/04/2023, 21:18 Camada de visão
Abrindo a página no navegador, teremos o resultado a seguir. Para facilitar os testes, podemos criar um
aplicativo Web, no NetBeans, e acrescentar a página HTML.
Visualização de Exemplo001.html
Tabelas
Nas tabelas, temos uma divisão em linhas, e cada linha com suas respectivas colunas, definindo células de
informação. Com base em atributos como colspan e rowspan, as células podem ser combinadas, e ainda
temos a possibilidade de uma linha de cabeçalho. Vejamos algumas tags:
Tags Utilização
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 6/89
10/04/2023, 21:18 Camada de visão
Tags Utilização
HTML
content_copy
A tabela foi criada com alguns atributos visuais, incluindo a borda de espessura 1 e utilização de 100% do
espaço horizontal disponível. Note o uso de colspan na primeira e última linhas, em que células
subsequentes são mescladas, com base no valor definido por meio do atributo.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 7/89
10/04/2023, 21:18 Camada de visão
Visualização de Exemplo002.html
Formulários
Nos formulários, podemos contar com os componentes mais tradicionais das interfaces de usuário, como
botões, caixas de texto e caixas de seleção. Vejamos algumas tags:
Tags Utilização
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 8/89
10/04/2023, 21:18 Camada de visão
Tags Utilização
Para textos maiores, devemos utilizar o textarea, que permite quebra de linhas, sendo configurado em
termos do número de linhas e colunas.
Quanto a elementos multivalorados, como listas, temos as opções select e datalist, ambos definindo os
elementos da lista por meio de option. No entanto, o datalist deve ser utilizado para pequenos conjuntos de
valores fixos, enquanto o select, que permite o uso de uma chave e um texto para a opção, reflete melhor um
conjunto dinâmico.
HTML
content_copy
Nosso formulário tem como destino um endereço fictício, associado por meio de action, usando o método
POST do protocolo HTTP. Após o preenchimento dos dados, o clique no componente do tipo submit, ou
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 9/89
10/04/2023, 21:18 Camada de visão
botão de envio, tentará enviar os dados em background para o endereço, o que causará um erro de acesso,
mas, no caso de uma rota real, estaria enviando esses dados para um componente do servidor capaz de
tratá-los, como um Servlet, por exemplo.
O id deve ser utilizado nos relacionamentos internos da página, enquanto name define a variável que será
enviada para o servidor. O value define o valor que será enviado para o servidor, associado à variável
definida via name, devendo ser fixado para todos os componentes que não permitem edição de valor via
teclado.
A lista de valores simples datalist deve ser associada ao componente do tipo input por meio do atributo list.
Note o uso de id para o relacionamento, da mesma forma que nas tags do tipo label, para associação com
os componentes corretos.
Formulário Exemplo003.html.
MathML
O MathML é uma linguagem de marcação para exibir e capturar estruturas e conteúdo matemático.
Vejamos um Exemplo004.html.
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 10/89
10/04/2023, 21:18 Camada de visão
A sintaxe MathML é bastante complexa e extensa, mas a listagem nos traz muitos elementos de utilização
comum. Inicialmente, definimos uma linha principal com mrow, e na sequência, temos a integral e seus
limites, dentro de msubsup, com o símbolo em mo, limite inferior em mn e limite superior em mi.
O conteúdo interno da integral será uma fração, com mfrac, em que a parte superior deve ficar em uma tag
mrow, a qual envolve, no exemplo, um logaritmo na base 3, definido com msub, com a função em mi e a
base em mn, seguido da variável x na tag mi, enquanto a parte inferior tem apenas a variável x em uma tag
mi. Na última parte, temos o sinal diferencial, em uma tag mo, seguido da variável para integração x na tag
mi.
Toda a expressão matemática deve ser encapsulada em uma tag math, em que devemos estar atentos para
a utilização do namespace adequado. Para testar, devemos utilizar o Firefox, pois nem todos os
navegadores oferecem suporte direto ao MathML, sendo necessário adicionar plugins a navegadores como
Chrome e Edge.
Âncoras
As âncoras, com base na tag a, definem a navegação entre páginas e conteúdo, justificando a classificação
dos documentos como hipertexto. Uma âncora pode definir um local dentro de uma página extensa, navegar
para o trecho nomeado, ou definir um link para algum endereço. É bastante comum sua utilização junto a
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 11/89
10/04/2023, 21:18 Camada de visão
Vejamos o Exemplo005.html.
HTML
content_copy
Como um dos objetivos é demonstrar a navegação interna da página, para situações em que o conteúdo é
muito extenso, foram adicionadas muitas quebras de linha. Para marcar o local da página, utilizamos o
atributo id da âncora, enquanto a navegação para o trecho ocorre com o uso do valor de id, precedido por
cerquilha, no atributo href.
A navegação para outros sites ou páginas também é definida no atributo href, com o descritivo da âncora
colocado entre a tag e seu fechamento. No lugar do texto descritivo, podemos usar uma imagem (img),
definindo um ícone clicável.
O resultado da execução da página, que receberá o nome Exemplo005.html, é apresentado a seguir. Como
temos uma página extensa, foi dividida em duas partes, em que o clique sobre a âncora com texto "própria"
levará para o final dela.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 12/89
10/04/2023, 21:18 Camada de visão
Visualização do Exemplo005.html.
CSS
Folhas de estilo
Com o papel estrutural que o HTML assumiu, vários dos atributos de configuração tipográfica das versões
antigas se tornaram obsoletos, deslocando-se a responsabilidade para as folhas de estilo, ou CSS (Cascade
Style Sheets).
As folhas de estilo podem ser adicionadas na tag do HTML (inline), em um trecho delimitado por style, ou
em um arquivo externo. Em termos de reutilização e responsividade, a melhor opção é o uso de arquivo
externo, pois permite centralizar as formatações e versionar para cada plataforma, ou seja, utilizar pontos
de quebra para formatações específicas.
Vamos voltar ao primeiro exemplo de HTML e aplicar algumas formatações sobre as tags, adotando um
setor delimitado por style.
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 13/89
10/04/2023, 21:18 Camada de visão
Aqui definimos elementos comuns para algumas tags visuais, como cor da fonte (color), cor do fundo
(background-color) e alinhamento do texto (text-align). Também temos uma borda do tipo tracejada sendo
aplicada ao redor das listas.
Podemos aplicar as formatações a várias tags simultaneamente, desde que as separemos por vírgula, e
qualquer atributo definido será combinado com as formatações já existentes. Aliás, as folhas de estilo são
denominadas como "em cascata" porque podem ser sobrepostas.
Qualificador hover
O qualificador hover permite definir uma formatação para o momento em que o mouse repousa sobre o
componente. No exemplo, a página tem fundo preto e fonte branca como padrão, mas, quando o mouse
passa sobre um parágrafo, ele muda a cor de fundo para marrom.
Para formatar um elemento específico da página, o seletor correto seria um identificador, ou id, em que uma
utilização comum é na criação de áreas para organização do conteúdo. Como o padrão tableless
desencoraja o uso de tabelas com esse fim, o uso de áreas identificadas, com base em tags do tipo div,
formatadas via CSS, transformou-se na estratégia preferencial.
Identificadores são voltados para a individualização de algum componente na página, sendo definidos na
folha de estilo com um nome precedido de cerquilha. Para que a formatação seja utilizada, devemos ter um
componente com atributo id utilizando o mesmo nome.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 14/89
10/04/2023, 21:18 Camada de visão
Exemplos práticos
Exemplo 1
A seguir, um arquivo de folha de estilos com o nome Exemplo006.css.
CSS
content_copy
De acordo com a formatação adotada, toda tag div definirá uma área com largura (width) de 200 pixels e
altura (height) de 150 pixels, utilizando texto alinhado ao centro e tamanho de fonte ajustado para 40 pixels.
Em seguida, temos a individualização das características para cada uma das áreas que será criada. A
combinação das formatações da div e do identificador definirão o posicionamento e as dimensões dessas
áreas.
Nas formatações específicas, temos a definição da cor de fundo (background-color), estilo da borda (boder-
style), e posicionamento absoluto, em relação ao limite superior esquerdo da página, considerado como
origem dos eixos horizontal e vertical. Com os valores utilizados, teremos uma área a 10 pixels do topo e 10
pixels da esquerda, e outras duas áreas utilizando os valores 110 e 210, respectivamente.
A página Exemplo006.html, com a listagem a seguir, utiliza a folha de estilos definida anteriormente.
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 15/89
10/04/2023, 21:18 Camada de visão
A página é bastante simples, com a definição das áreas por meio de tags do tipo div, relacionadas aos
estilos específicos por meio do atributo id. Devemos lembrar que teremos a combinação das formatações
para a tag e para o identificador em cada área.
O relacionamento entre os arquivos HTML e CSS foi definido por meio da tag link, em que temos o atributo
rel com o valor stylesheet (folha de estilos), e o nome do arquivo em href. Vejamos o resultado da interface:
Exemplo de CSS.
Ao contrário dos identificadores, que definem formatações para elementos específicos, as classes,
definidas com a utilização de ponto antes do nome, servem para formatar elementos que se repetem ao
longo da página.
Exemplo 2
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 16/89
10/04/2023, 21:18 Camada de visão
HTML
content_copy
O que temos no código é a definição de uma lista principal, em que os itens são links para outras páginas e
endereços, além de um item contendo outra lista, o que seria um submenu, com mais alguns links. A relação
com a folha de estilos ocorre por meio da tag link, na divisão head, a qual não terá efeito antes da criação do
arquivo.
Como podemos observar, temos a exibição das listas, contendo as âncoras, em que os links estão
funcionais, mas ainda sem a formatação adequada. Veremos que as folhas de estilos efetuam
modificações extremas na forma de apresentação, permitindo que o HTML assuma apenas o papel
estrutural, de acordo com a divisão de responsabilidades exigida pela W3C.
Vamos estilizar nosso menu por meio da criação do arquivo Exemplo007.css, contendo a listagem a seguir.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 17/89
10/04/2023, 21:18 Camada de visão
CSS
content_copy
Se voltarmos ao nosso código HTML, veremos que a lista principal, na primeira tag ul, tem o valor menu no
atributo class, definindo a utilização das formatações associadas à classe menu, da folha de estilos. Da
mesma forma, a lista interna é atribuída à classe submenu, que também será especificada na folha de
estilos.
Começamos com uma formatação geral, por meio do asterisco, para a remoção das margens da página,
além da definição da fonte com 12 pixels, na tag body. Nos passos seguintes, temos as classes menu e
submenu sendo configuradas.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 18/89
10/04/2023, 21:18 Camada de visão
Segundo as características definidas, uma tag li, dentro de um elemento menu, respeitará uma sequência de
posicionamento a partir da esquerda, além de apresentar uma borda tracejada de 1 pixel à direita (border-
right).
Da mesma forma, na formatação seguinte, temos as âncoras dentro das tags li, a partir de menu, com
remoção do sublinhado, por meio de text-decoration, definição do espaçamento em padding, e visualização
(display) como bloco, em que temos a área preenchida, sem outros elementos HTML ao redor, a não ser que
sejam configurados com valor left em float.
Ainda com relação às âncoras, o qualificador hover fará com que seja
utilizado fundo preto e fonte branca quando o mouse estiver sobre
elas.
Temos ainda a formatação para a tag li, a partir de submenu, com definição da borda inferior, visualização
em bloco e largura de 120 pixels. Como o submenu estará dentro de menu, temos formatações que se
propagam para li, como a borda direita, ao mesmo tempo em que, devido à precedência da visualização do
contêiner, as tags li de submenu ficarão invisíveis no início.
Para que o submenu fique visível, temos uma formatação muito específica, em que o qualificador hover é
aplicado uma tag li de menu sequenciada por ul, mudando o valor do atributo display da ul para block
enquanto o mouse estiver sobre o item. Vejamos a interface resultante:
Java Script
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 19/89
10/04/2023, 21:18 Camada de visão
O dinamismo das páginas exige a utilização de uma linguagem de programação adequada, no caso o Java
Script, e interação baseada na utilização de eventos.
Utilizamos o Java Script para controle de elementos da página HTML e sua interatividade, em que o código
pode ser incluído na própria página, ou organizada no formato de biblioteca, como um arquivo externo.
Caracterizada originalmente como uma linguagem para o navegador, hoje temos muitas tecnologias que
adotam Java Script no lado servidor, como NodeJS.
Uma variável pode ser declarada com o uso de var, ou simplesmente por meio da inicialização. Como o Java
Script não é fortemente tipado, a variável assume o tipo do valor associado a ela. Os tipos com os quais a
linguagem trabalha são: numérico, booleano, texto, objeto e vetor, este último como objeto da classe Array.
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 20/89
10/04/2023, 21:18 Camada de visão
No exemplo, são declaradas três variáveis, com a utilização de var, sendo efetuadas algumas operações
aritméticas sobre elas. A cada passo, é impresso na página o valor das variáveis, dentro de tags do tipo li,
por meio de document.writeln, com a concatenação dos valores no texto efetuada pelo sinal de adição.
Com relação aos operadores do Java Script, podem ser observados na tabela seguinte:
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 21/89
10/04/2023, 21:18 Camada de visão
A divisão inteira trunca o valor no Java, mas não no Java Script, pois não temos como diferenciar entre
inteiro e ponto flutuante. Outra diferença para o Java é a comparação de texto: no Java, é necessário o
método equals, enquanto o Java Script adota o operador de igualdade padrão.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 22/89
10/04/2023, 21:18 Camada de visão
Estrutura condicional
A similaridade entre Java Script e derivados do C também ocorre na sintaxe para as estruturas de decisão e
de repetição. Vejamos um exemplo de estrutura condicional, no arquivo Exemplo009.html.
HTML
content_copy
A função prompt serve para solicitar ao usuário a digitação de um valor a partir de um diálogo de entrada,
enquanto a função eval efetua a conversão do texto para número. De acordo com nosso exemplo, a variável
x recebe o valor digitado pelo usuário, com o uso da função prompt, ocorrendo a conversão para numérico
por meio de eval.
Com base no valor digitado, a página apresentará uma das alternativas de frase, sempre com o
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 23/89
10/04/2023, 21:18 Camada de visão
encapsulamento na tag h1, ocorrendo a escolha da frase pela estrutura condicional if..else, segundo a
condição x > 5. Vejamos o resultado final:
As funções, bem como os métodos da orientação a objetos, são processos nomeados, que podem ou não
apresentar parâmetros e retornar valores. Criamos funções no Java Script com o uso de function, e elas
podem retornar valores para o chamador por meio de return.
JavaScript
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 24/89
10/04/2023, 21:18 Camada de visão
Nessa biblioteca, temos duas funções: cálculo do fatorial e a verificação se o número fornecido é primo. Em
ambos os casos, temos um parâmetro de entrada x e uso de return para fornecimento do resultado, embora
não sejam elementos obrigatórios.
Já para o teste de primalidade, ele foi codificado com base em uma estrutura de repetição, em que ocorre o
retorno de false quando o parâmetro é divisível por algum valor do loop, segundo o teste do resto da divisão,
ou true, após o loop, quando não é divisível por nenhum dos valores, o que é justificado pela regra de que o
número primo só pode ser dividido por 1 ou por ele mesmo.
Com nossa biblioteca Java Script pronta, vamos criar o arquivo Exemplo010.html.
HTML
content_copy
O primeiro ponto a ser observado é a inclusão da biblioteca criada anteriormente, ao nível da divisão head
de nossa página. Basta utilizar o atributo src de script, tendo como valor o nome da biblioteca, ou seja,
ExemploLib.js.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 25/89
10/04/2023, 21:18 Camada de visão
Temos duas tags div, utilizadas para dividir a página em duas colunas. Dentro de cada uma, são definidas
estruturas de repetição para a chamada das funções. Ambas as colunas terão largura de 200 pixels, sendo
posicionadas lado a lado, partindo da esquerda.
Temos a impressão dos fatoriais de 3 a 8, como elementos de lista, a partir de uma estrutura de repetição
do tipo while, em que o incremento da variável de controle ocorre ao final do loop. Já para a segunda coluna
temos uma estrutura do tipo for, com a variável de controle indo de 50 até 75, e a condicional permitindo
emitir apenas os valores em que ePrimo retorna true.
Execução de Exemplo010.html.
Tratamento de eventos
O conceito de eventos utiliza um conjunto de ações predeterminadas para as quais podemos dar uma
resposta programada ao chamador. No caso do HTML, o modelo de resposta parte dos atributos de evento
existentes nas tags HTML sendo relacionados com funções em Java Script.
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 26/89
10/04/2023, 21:18 Camada de visão
A página contém apenas uma caixa de texto e um botão. Ao clicar sobre o botão, será apresentada uma
mensagem de boas-vindas. Note a utilização do método getElementById, ao nível do Java Script, para
capturar o elemento HTML a partir de seu identificador (id).
Criamos uma função, em Java Script, com o nome mostraMensagem, em que a caixa de texto é capturada
por meio do valor do atributo id, fornecendo o valor digitado para a variável nome, a partir de seu campo
value. Em seguida, ocorre a utilização da função alert, em que a mensagem será a concatenação da
expressão "Bem-vindo" com o nome digitado, causando a exibição de uma janela de diálogo simples,
apresentando as boas-vindas.
O método é associado ao clique do botão por meio do evento onclick, um dos atributos da tag. Vejamos o
resultado a seguir.
Execução de Exemplo011.html.
Notação JSON
Um elemento de grande relevância para a sintaxe do Java Script é a notação JSON (Java Script Object
Notation), que permite a definição de objetos de forma simples, além de ser o modelo padrão de dados para
Web Services do tipo RESTful. Um pequeno exemplo pode ser observado a seguir:
JSON
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 27/89
10/04/2023, 21:18 Camada de visão
Algo muito interessante no JSON é a simplicidade de escrita, com os atributos seguidos de seus valores,
segundo um padrão chave-valor. Essa simplicidade permite uma leitura natural dos objetos, o que justifica
sua ampla adoção para transmissão de dados na Web.
JQuery
Um framework Java Script que faz bom uso dos seletores CSS e notação JSON é o JQuery, algo que
justifica sua ampla utilização pelo mercado, com uma escrita simples e extensões muito abrangentes,
incluindo JQuery UI, que facilita a criação de interfaces com aspecto profissional e a definição de temas.
Vamos explorar as possibilidades do JQuery para a construção de interfaces, ou seja, trabalharemos com
temas e uso dos componentes JQuery UI. Começaremos baixando um tema adequado, a partir do endereço
https://jqueryui.com/themeroller, em que podemos escolher nossas configurações ou utilizar um tema da
galeria, clicando em download ao final.
Vamos utilizar o tema UI darkness. Após clicar em download, será aberta uma página, em que devemos
escolher a versão 1.13.1, para utilização com JQuery na versão 1.8 ou superior. Deixamos todas as opções
marcadas e clicamos no segundo botão de download, extraindo o conteúdo no diretório em que estão
nossas páginas HTML, ou na divisão Web Pages do projeto Web, no NetBeans, além de renomear o diretório
de base da biblioteca para jquery-ui.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 28/89
10/04/2023, 21:18 Camada de visão
Aplicação básica
Vamos criar o arquivo Exemplo012.html.
HTML
content_copy
Temos a inclusão das folhas de estilo e bibliotecas Java Script na divisão header, enquanto no corpo foi
definido apenas um componente de texto, identificado como dataCadastro. Também temos um pequeno
trecho em Java Script, criado segundo o padrão do JQuery, com a transformação do campo de texto em
calendário.
Para utilizar o JQuery em nossas páginas, deve ser definida uma função global. No corpo dela, trabalhamos
com os mesmos seletores adotados pelo CSS para obter os elementos da página, seguido da aplicação de
modificadores adequados, como datepicker, que transforma a entrada de texto em calendário interativo. O
resultado pode ser observado a seguir:
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 29/89
10/04/2023, 21:18 Camada de visão
HTML
content_copy
No exemplo, temos uma página para definição de listas de tarefas, com a inclusão de tarefas na lista a partir
de um diálogo modal.
Vamos analisar o diálogo modal, que é construído sobre um elemento do tipo div, com o título "Definição de
Tarefas", contendo um formulário em seu interior. Para transformar o componente em um diálogo modal,
invocamos o modificador dialog, tendo como atributos: altura (height) de 200 pixels, largura (width) de 350
pixels, abertura automática (autoOpen) desativada e comportamento modal ativado.
O primeiro botão invocará a função criarTarefa, responsável pela adição de uma tarefa à lista, e o segundo
apenas provocará o fechamento do diálogo a partir de uma função anônima. Temos ainda o evento de
fechamento do diálogo (close), que limpa o campo de texto (edtTarefa) quando o diálogo é fechado,
fornecendo um texto vazio para val.
Comentário
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 30/89
10/04/2023, 21:18 Camada de visão
A criação da tarefa pode ser observada na função criarTarefa, em que temos a inclusão de um elemento do
tipo li à lista, identificada como listaTarefas, por meio do método append. Além da utilização de uma classe
CSS e de um estilo complementar para definição do espaçamento, modificando a aparência padrão do item
de lista, temos a captura do valor que foi digitado no campo de texto, por meio da val, para utilização no
item. Note que o fechamento do diálogo é invocado após o acréscimo da tarefa.
Note o uso do método on, que associa um evento de determinado tipo a uma função para o tratamento. A
mesma técnica foi adotada para a resposta ao clique no botão btnDialog, que efetua a abertura do diálogo
com a chamada do tipo open.
Para a lista, foi utilizado o modificador sortable, que permite arrastar os itens adicionados à lista,
modificando sua ordem de apresentação.
Chamadas assíncronas
Algo que se tornou muito comum nos sites atuais foi a utilização de chamadas assíncronas, segundo um
compêndio de tecnologias conhecido como AJAX. A biblioteca JQuery fornece um método muito simples
para efetuar chamadas desse tipo. Como o Java Script permite lidar com JSON de forma nativa, o
tratamento da resposta para Web Services RESTful não oferece qualquer tipo de dificuldade.
Em termos de componentes HTML relevantes, temos apenas uma caixa de texto (edtNome), um botão
(btnEnviar) e uma divisão (listaDrinks). A divisão merece atenção especial, pois serve de base para um
componente accordion, o qual fornece a criação de áreas retráteis agrupadas, em que cada área receberá
um título, por meio da tag h3, e o conteúdo em uma div.
Temos a associação do clique ao botão, com uma função de tratamento que limpa o conteúdo interno de
listaDrinks, eliminando os resultados de consultas anteriores, formando o endereço de pesquisa,
concatenando o valor digitado em edtNome, e efetuando a chamada AJAX.
Como temos uma chamada assíncrona, é fornecido um objeto com o endereço (url) e a manipulação para
um retorno bem-sucedido (success), em que invocamos tratarDados com a passagem do retorno.
Comentário
O endereço é um serviço RESTful internacional para a consulta de receitas de drinks, que retorna diversas
informações no formato JSON. Como cada drink normalmente apresenta variações, teremos um vetor de
registros em que resgataremos os campos strDrink, strDrinkThumb e strInstructions, representando,
respectivamente, o nome, a foto e a receita do drink. Lembre-se de que as receitas estarão em inglês, mas a
tradução da página, por meio do navegador, apresentou ótimos resultados nos testes efetuados.
A função tratarDados recebe a resposta no formato JSON, e utiliza o operador forEach sobre o vetor drinks,
invocando adicionaLinha a cada registro, com a atualização do accordion, ao final, por meio da opção
refresh.
registro e o índice no vetor, em que item servirá de base para construir uma área de nosso accordion, com o
título (h3) associado a strDrink e o conteúdo (div) definido a partir de uma imagem apontando para
strDrinkThumb, ao lado do texto referente às instruções da receita (strInstructions). Vejamos o resultado:
Utilização de AJAX.
Existem muitos outros componentes disponíveis na biblioteca JQuery UI, inclusive opções para a criação de
menus, barras de progresso e abas de navegação.
video_library
Teoria na prática
Construção de páginas com JQuery UI.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 33/89
10/04/2023, 21:18 Camada de visão
Segundo as diretivas da W3C, enquanto o HTML fica com a responsabilidade de estruturar as páginas,
toda formatação visual deve ser implementada por meio de folhas de estilo. Mais do que formatações,
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 34/89
10/04/2023, 21:18 Camada de visão
o CSS permite controlar alguns comportamentos, como a mudança do aspecto do componente com a
passagem do mouse sobre ele, o que é feito com o qualificador
A empty.
B visited.
C focus.
D hover.
E active.
Com o CSS, aplicamos formatações a elementos específicos da página, por meio de seletores, além de
permitir a definição de alguns comportamentos via qualificadores. Por exemplo, empty define a
aparência quando o componente não tem filhos, focus para aquele componente que detém o foco,
visited é utilizado nos links já visitados, active para o momento em que ocorre o clique, e hover para a
passagem do mouse sobre o componente.
Questão 2
A dialog
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 35/89
10/04/2023, 21:18 Camada de visão
B slider
C accordion
D tooltip
E spinner
Por meio do uso de accordion, conseguimos criar uma sequência de painéis, em que o título de cada
um é definido via tag h3 e o conteúdo em uma tag div, sendo o método aplicado a uma div que envolve
todos os pares h3/div. Por padrão, apenas um painel começa selecionado, ficando aberto (visível),
enquanto os demais apresentam apenas o título. O clique sobre o título de outro painel altera o painel
selecionado, ocultando o conteúdo dos demais.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 36/89
10/04/2023, 21:18 Camada de visão
Framework Thymeleaf
Por meio do framework Thymeleaf, criamos templates HTML, os quais promovem uma separação natural
da camada de visualização, definindo modelos que funcionam como protótipos de design naturais. Ele
trabalha com outros formatos, além do HTML, incluindo XML, texto e Java Script, de acordo com o modo de
operação utilizado. A principal diferença ocorre ao nível das críticas quanto à formação do arquivo ou tags
utilizadas.
Como podemos escolher entre diferentes dialetos, cada dialeto trará as regras de formação para o tipo de
arquivo e integração com os componentes naturais do ambiente, como os managed beans do ambiente
Java Web.
Camada model
Vamos criar um projeto do tipo Web Application, com gerenciamento pelo Maven, no NetBeans, como na
imagem a seguir. Nosso projeto terá o nome ExemploTh001, e o Group Id será com.universidade, utilizando
servidor Apache Tomcat, com Java EE versão 7.
Agora, vamos incluir a dependência do Thymeleaf no arquivo pom.xml, com o acréscimo do fragmento
apresentado a seguir:
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 37/89
10/04/2023, 21:18 Camada de visão
O projeto deverá apresentar problemas com a adição da dependência, com um sinal de exclamação sobre o
ícone do projeto no navegador do NetBeans. Clique com o botão direito sobre o projeto e escolha a opção
"Resolve Project Problems".
Dica
A versão do JDK interferirá na utilização do Maven, sendo aconselhável adotar ao menos a plataforma 1.8,
que já traz o protocolo SSL atualizado.
Com o projeto configurado, vamos iniciar a codificação do aplicativo com a criação da classe Contato, no
pacote com.une sa.exemploth001.model.
JAVA
content_copy
No mesmo pacote, criaremos a classe ContatoRepositorio, simulando o acesso a uma base de dados, para
que possamos testar as interfaces gerenciadas pelo Thymeleaf.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 38/89
10/04/2023, 21:18 Camada de visão
JAVA
content_copy
As classes representam, respectivamente, uma entidade do sistema e o repositório para ela, em que o meio
de armazenamento é um HashMap estático. O repositório fornece métodos para incluir, excluir e obter a
lista de contatos, além de ser inicializada com dois contatos de exemplo.
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 39/89
10/04/2023, 21:18 Camada de visão
A classe segue o padrão Factory, com apenas um método estático, para recebimento de um contexto Web
(ServletContext) e retorno de um gerenciador de templates. As configurações do gerenciador indicam o uso
de sintaxe HTML, com arquivos colocados no diretório templates de WEB-INF (prefixo), utilizando extensão
html (sufixo), além de adotar cache de uma hora.
Comentário
Antes de chegar até o Servlet, a requisição passa pelos filtros de interceptação definidos, o que permite
automatizar ações como verificação de usuário e log de eventos.
Camada Controller
Antes de criar nosso filtro, vamos definir uma interface de comandos para nosso sistema, com o nome
IController, no pacote com.unesa.exemploth001.controller.
JAVA
content_copy
A interface criada definirá o modelo de chamadas da camada controller, utilizado nas ações do sistema,
cujas classes ficarão no mesmo pacote de IController. Começaremos definindo a classe ContatosList:
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 40/89
10/04/2023, 21:18 Camada de visão
Vamos acrescentar a variável listaContatos, com a listagem de contatos obtida do repositório, para que seja
utilizada no template. Em seguida, ocorre o processamento para o template "contatos", utilizando o contexto
Thymeleaf (ctx) e a stream de saída para escrita do HTML (writer).
JAVA
content_copy
Aqui temos a ação de inclusão de contato, em que devemos obter os parâmetros enviados pela requisição
HTTP, criação de uma entidade a partir desses dados, e uso do repositório para a inclusão. O restante do
processo é equivalente ao da ação de listagem anterior.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 41/89
10/04/2023, 21:18 Camada de visão
Nada muito diferente ocorre para a ação de exclusão, que terá o nome ContatosExcluir.
Java
content_copy
Assim como na inclusão, após obter o nome enviado por meio da requisição e invocar a exclusão a partir do
repositório, configuramos os dados para exibição dos contatos.
Camada View
Temos o mesmo template para as três ações definidas. Para criá-lo, vamos adicionar uma página HTML
com o nome contatos, no diretório templates, a partir de WEB-INF, de acordo com código a seguir:
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 42/89
10/04/2023, 21:18 Camada de visão
Temos uma página HTML comum, com um formulário contendo dois campos e uma tabela, mas devemos
estar atentos ao uso de atributos definidos no namespace do Thymeleaf, que foi configurado ao nível da raiz
do documento, com o alias th. Serão esses atributos que sofrerão modificações pelo gerenciador de
templates durante o processamento.
Começando pela tabela, temos o comando th:each, que repetirá o trecho para cada elemento de
listaContatos, fornecida pelas ações, associando cada um à variável local contato. Em cada célula da linha,
teremos o valor preenchido, com o uso de th:text, a partir do campo específico de contato. Utilizamos ainda
o campo artificial contatoStat para colorização de linhas ímpares.
Comentário
Note o uso de cifrão ($) para acesso a um valor, colocado entre chaves. Também temos o uso de arroba (@),
executado localmente, o que foi utilizado na construção de um link dinâmico, com a passagem da rota e
seus parâmetros, colocados entre parênteses, definindo o endereço para exclusão de um registro
específico.
Quanto ao formulário, o único elemento relevante é o uso do atributo th:action, fornecendo a rota para
inclusão, em que o uso de arroba corrige eventuais modificações da URL.
Observamos que precisaremos do mapeamento de rotas para nossas ações, o que será feito pela classe
ControllerMappings, no pacote com.universidade.exemploth001.controller.
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 43/89
10/04/2023, 21:18 Camada de visão
Nosso mapeamento foi definido com base em um HashMap, em que cada rota é associada a um
controlador para processamento da ação específica. A classe oferece apenas um método público, com o
nome fromPath, que recebe a rota e retorna o controlador correto.
Filtro de interceptação
Vamos definir o filtro de interceptação, com a criação da classe AppFilter, que ficará no pacote
com.universidade.exemploth001.web.
JAVA
content_copy
O mapeamento do filtro ocorre para qualquer rota iniciada com app, por meio da anotação WebFilter.
Detectada uma url com essas características, o fluxo é desviado para o método doFilter, em que é invocado
o método interno para processamento (process). O fluxo é devolvido para a cadeia de filtros quando o
método retorna false.
O processamento do filtro é iniciado com alguns testes para saber se existe uma classe de ação apropriada,
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 44/89
10/04/2023, 21:18 Camada de visão
retornando false quando um controlador não é encontrado. Caso seja encontrado, a resposta é iniciada com
a configuração do tipo de conteúdo e alguns cabeçalhos para impedir a utilização de cache no cliente.
Comentário
No passo seguinte, um objeto do tipo WebContext é instanciado, e o controlador que foi obtido
anteriormente processa a resposta, utilizando o objeto instanciado, o gerenciador de templates do filtro e o
escritor do canal de saída da resposta HTTP. Note que o gerenciador de templates é obtido no método init
do filtro, a partir de nossa classe EngineFactory.
Se o processamento não gerar falhas, o método retorna true ao chamador, mas se uma exceção ocorre, ela
é encapsulada em um ServletException, sendo ecoada para o contexto de execução com throw. Executando
o projeto, podemos acessar o endereço http://localhost:8080/app/contato/list, obtendo a saída a seguir:
Criação do projeto
Embora seja possível utilizar o NetBeans para criação de aplicativos Spring Boot, com a simples alteração
do arquivo pom.xml em um aplicativo padrão Maven algumas plataformas tornam a tarefa mais simples.
Uma opção muito interessante é o Spring Tools Suite, baseado no Eclipse, que pode ser baixado a partir do
endereço https://spring.io/tools, com a instalação fornecida no formato de um arquivo jar executável, o qual
efetua uma simples extração de arquivos.
Para criar o projeto, escolha a opção de menu File, seguida de New e Spring Starter Project, adotando o
nome ExemploTh002, além do grupo com.universidade e pacote de mesmo nome, como pode ser
observado na imagem seguinte:
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 45/89
10/04/2023, 21:18 Camada de visão
Clicando no botão Next, devemos selecionar os pacotes do Spring que serão adicionados ao arquivo de
configuração pom.xml. Utilizaremos Spring Data JPA, H2 Database, Thymeleaf e Spring Web, como
observado a seguir:
Ao clicar em Finish, teremos um projeto Spring Boot com inclusão do Thymeleaf, modelo objeto-relacional
do JPA, arquitetura MVC do Spring Web e banco de dados do tipo H2, que trabalha em memória, eliminando
a necessidade de configurações. Para testar o projeto, vamos clicar com o botão direito sobre ele, no
Package Explorer, situado na divisão esquerda do ambiente, e escolher Run As, seguido de Spring Boot
App.
Poderemos observar as mensagens referentes à execução na divisão inferior, painel Console, na imagem
seguinte. Apesar de estar em execução, nosso sistema não tem rotas definidas, e a chamada ao endereço
de base (localhost:8080) retornará um erro.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 46/89
10/04/2023, 21:18 Camada de visão
JAVA
content_copy
Aqui definimos um controlador Spring Web, com a anotação Controller, tendo o mapeamento da raiz para o
método showHome, por meio da anotação GetMapping. No método, temos um parâmetro do tipo Model,
para a atribuição de valores que serão repassados para o template, e um retorno do tipo texto, que deverá
indicar o nome do template, sem a extensão HTML.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 47/89
10/04/2023, 21:18 Camada de visão
Para criar o arquivo, utilizamos o botão direito sobre o diretório templates, seguido de New e File, sendo
adotado o nome home_tl.html. A extensão deve ser digitada, e o conteúdo do novo arquivo é apresentado
na listagem seguinte.
HTML
content_copy
Aqui temos a criação de uma lista HTML, em que os elementos são obtidos por meio de th:each, a partir da
coleção departamentos, fornecida pelo controlador. Cada elemento é recuperado na variável departamento,
utilizada para substituir o conteúdo valor, com o uso de th:text. Da mesma forma, recuperamos a data para
preenchimento do elemento span.
Como os templates são estáticos, devemos parar a execução e reiniciar o servidor, o que é feito de forma
rápida pela opção relaunch, na barra de ferramentas da IDE, com um ícone mesclando os símbolos stop e
run. O resultado pode ser observado na imagem a seguir:
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 48/89
10/04/2023, 21:18 Camada de visão
A sintaxe para configuração dos templates inclui muitas diretivas. Na tabela seguinte, temos os símbolos
utilizados pelo Thymeleaf, segundo a Standard Expression Syntax:
Símbolo Utilização
${...} Acessa o valor de uma variável, que pode ser local ou fornecida no Model.
Definição de mensagens
Para demonstrar o uso de mensagens, um recurso muito útil para a definição de mensagens padronizadas,
inclusive com suporte a idiomas, vamos criar o arquivo messages.properties no diretório resources, mesmo
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 49/89
10/04/2023, 21:18 Camada de visão
JAVA
content_copy
Em seguida, modificamos nosso arquivo de template (home_tl.html), alterando o trecho do título, conforme
apresentado a seguir:
HTML
content_copy
Ao executar novamente o servidor, nossa página apresentará o título definido no arquivo de propriedades, ou
seja, "Lista de Departamentos".
Aqui utilizamos o Spring Tools Suite por ser uma ferramenta mais prática para a criação dos aplicativos
Spring Boot, mas, se quiser utilizar o NetBeans, basta criar um projeto-padrão, com base no Maven, e alterar
o arquivo pom.xml, incluindo as dependências corretas, como o que é apresentado a seguir, extraído de
projeto exemplo:
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 50/89
10/04/2023, 21:18 Camada de visão
O exemplo demonstra a grande facilidade oferecida pelo Spring Boot, em conjunto com Thymeleaf, para a
criação de aplicativos.
Persistência e controle
Camada de persistência
Para criar nossa camada de persistência, vamos utilizar um banco de dados do tipo H2, que pode trabalhar
em memória, sem exigir configurações avançadas. Para acessar outros bancos, o arquivo
application.properties deverá ser alterado, incluindo as informações necessárias para conexão com o
banco de dados e gerenciamento de transações.
Já que estamos trabalhando no modelo MVC, nossas entidades e repositórios serão criados no pacote
com.universidade.model. Começaremos definindo uma entidade com o nome Departamento:
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 51/89
10/04/2023, 21:18 Camada de visão
Nossa classe é uma entidade JPA, o que é estabelecido pela anotação Entity, sendo incluídos os campos
idDepto, chave primária com valor gerado automaticamente, e nome. Também temos um relacionamento de
um para muitos (OneToMany) com a entidade Funcionario, expresso por um conjunto (Set) de nome
funcionarios.
JAVA
content_copy
Agora, temos os campos matricula, nome e dataCadastro, sendo matrícula a chave primária, além da
contraparte do relacionamento estabelecido anteriormente. Note o uso da anotação ManyToOne,
especificado como obrigatório, em um atributo de nome departamento, que é relacionado à propriedade
idDepto da entidade anterior (JoinColumn).
Cada uma das entidades precisará de um repositório JPA, que no Spring é definido por uma simples
interface, em que a comunicação com o banco é toda implementada pelo framework. Temos o conteúdo do
primeiro repositório apresentado a seguir:
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 52/89
10/04/2023, 21:18 Camada de visão
Definimos uma herança para a interface JpaRepository, com a especificação do tipo da entidade e de sua
chave primária. Ocorrerá o mesmo para o segundo repositório:
JAVA
content_copy
Camada de controle
Nossa camada model está completa e já podemos criar a classe DepartamentoController, no pacote
com.universidade.controller, representando nosso primeiro controlador.
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 53/89
10/04/2023, 21:18 Camada de visão
Temos um controlador capaz de interceptar as rotas HTTP, por meio do mapeamento dos métodos pelas
anotações GetMapping e PostMapping. Temos ainda o relacionamento com um repositório, instanciado no
contexto do Spring por meio da anotação Autowired.
Comentário
O primeiro mapeamento ocorre para a rota /departamentos, em que o método de reposta adicionará uma
lista de departamentos aos dados da página, obtida pelo repositório por meio de findAll, retornando em
seguida o nome do template. Temos na rota /departamentos/excluir um comportamento muito similar, mas
ocorrendo a exclusão do departamento selecionado a partir de idDepto, com base no método deleteById do
repositório.
A inclusão utiliza a rota /departamentos/cadastro nos modos GET e POST, em que o modo GET associará
um atributo do tipo Departamento aos dados da página para cadastro, cujo nome é retornado ao final,
enquanto no modo POST recebemos os dados do formulário já preenchido em um parâmetro depto, do tipo
Departamento, anotado como ModelAttribute, procedendo com a persistência dos dados por meio do
método save do repositório, obtenção do conjunto de entidades atualizado via findAll, e retorno do template
para listagem.
Ainda não criamos nossos templates, mas a execução do aplicativo irá gerar as tabelas do banco H2, assim
como faria em qualquer outro banco, com a estrutura a seguir:
Como o banco é recriado a cada execução, por estar trabalhando em memória, precisamos de alguns dados
de teste, o que será obtido com a execução de alguns comandos SQL. Teremos de adicionar um arquivo
com o nome import.sql, na raiz de resources, contendo a listagem a seguir, sem quebras de linha nos
comandos:
SQL
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 54/89
10/04/2023, 21:18 Camada de visão
Algo interessante em nossa camada de controle é o fato de que o mesmo método utilizado para incluir um
registro permite também alterá-lo. Com base nessa característica, para adicionar a possibilidade de edição
no sistema, basta inserir um segundo mapeamento para a rota que inicia o template para preenchimento de
dados, mas com o acréscimo de um segmento com o identificador, permitindo fornecer os dados atuais da
entidade.
O método adicionado pode ser observado na listagem seguinte, para a classe DepartamentoController:
JAVA
content_copy
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 55/89
10/04/2023, 21:18 Camada de visão
Interface do CRUD
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 56/89
10/04/2023, 21:18 Camada de visão
Temos a definição de um link para inclusão de departamentos, com uso de arroba e indicação da rota
/departamento/cadastro no atributo th:href, seguido da definição de uma tabela para exibição dos dados.
Na tabela, teremos outros links para exclusão e alteração de um departamento. A exclusão utiliza a sintaxe
para uso de parâmetros na requisição, enquanto a alteração trabalha com fornecimento da chave em um
segmento da rota.
Por meio de th:each, recuperamos os departamentos que foram enviados pelo controlador, obtendo cada
um deles na variável depto, e utilizamos cada ocorrência para a construção de uma linha da tabela. Os
valores de cada campo da entidade são acessados com o uso de cifrão, utilizado tanto para o
preenchimento das células de valores quanto na definição dos links de forma dinâmica.
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 57/89
10/04/2023, 21:18 Camada de visão
Nosso formulário utilizará o objeto depto, fornecido pelo controlador, por meio de th:object, e iniciará a ação
definida por th:action para a rota /departamentos/cadastro, no modo POST. Observe a utilização de
asterisco para acesso aos campos do objeto, com base em th:field, em cada um dos campos de nosso
formulário.
Como a chave primária é gerada automaticamente para o departamento, ela é colocada em um campo
escondido (hidden), evitando a edição pelo usuário. Já o campo referente ao nome será apresentado em
branco para a inclusão, ou com o valor corrente na alteração.
Já podemos acessar os diversos links oferecidos pela tela de listagem, pois o controlador está preparado
para todas as rotas solicitadas. Clicando na opção "Novo Departamento", abriremos o formulário de dados
em branco.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 58/89
10/04/2023, 21:18 Camada de visão
HTML
content_copy
Há muita similaridade com a tela de listagem de departamentos, agora com as rotas iniciadas por
/funcionários, mas temos algumas pequenas novidades. Note o uso da macro, precedida por cerquilha,
com o nome dates.format, que permite formatar a data de cadastro, bem como o acesso ao nome do
departamento de forma direta, a partir do atributo de relacionamento existente na classe Funcionario.
Listagem de funcionários.
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 59/89
10/04/2023, 21:18 Camada de visão
Nesse caso, temos a chave primária digitada pelo usuário. Há também a definição de um campo de seleção
para o campo departamento, em que as opções são preenchidas a partir da lista de departamentos com o
nome deptos, fornecida pelo controlador. Observe a utilização de th:each, para a iteração, th:value, para
definição do valor fornecido pela opção, e th:text, para o texto apresentado.
Com o template criado, acessando os links para alteração ou inclusão, teremos a exibição da tela a seguir:
video_library
Teoria na prática
Utilizando Thymeleaf com Spring Boot
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 60/89
10/04/2023, 21:18 Camada de visão
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 61/89
10/04/2023, 21:18 Camada de visão
As diretivas utilizadas no Thymeleaf permitem uma integração muito simples entre o template HTML e
o contexto do framework Spring, possibilitando recuperação de valores e reutilização de fragmentos,
entre diversas outras possibilidades. Se quisermos recuperar o nome da empresa a partir de um
parâmetro global, para que seja apresentado em cada página, qual símbolo seria utilizado pela diretiva
de recuperação?
A Arroba
B Cifrão
C Til
D Asterisco
E Cerquilha
Segundo a Standard Expression Syntax, o uso de cerquilha (#) permite recuperar textos padronizados a
partir de arquivos de propriedades, particularmente com a definição de um arquivo message.properties,
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 62/89
10/04/2023, 21:18 Camada de visão
no diretório resources, em que serão colocadas as mensagens do sistema, como pares de chave e
valor, com a recuperação posterior a partir da chave.
Questão 2
Os templates do Thymeleaf utilizam atributos nas tags HTML, definidos em seu namespace, para definir
ações diversas, como controle de visibilidade e substituição de conteúdo para a tag, sendo
normalmente adotado o prefixo th. Se quisermos repetir determinado trecho, para todos os elementos
de uma coleção, qual seria o atributo adotado na tag principal do trecho?
A Th:each
B Th:text
C Th:object
D Th:action
E Th:value
A utilização de th:each permite repetir a tag e seu conteúdo interno, ou seja, o trecho da página, para
cada objeto da coleção. Em termos práticos, recuperamos uma coleção enviada pelo controlador,
precedida de cifrão, atribuindo a um objeto em cada iteração. O objeto pode ser acessado no conteúdo
interno, recuperando suas propriedades. Um exemplo de utilização desse controle de fluxo seria
th:each="depto: $$ {deptos}".
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 63/89
10/04/2023, 21:18 Camada de visão
Framework do Bootstrap
O framework Bootstrap permite a definição de interfaces muito agradáveis, com uma estética alinhada aos
padrões de mercado, além de trazer elementos que garantem a responsividade, ou seja, adapta-se a
diferentes plataformas de forma natural. Com o Bootstrap, obtemos um conjunto de componentes
responsivos, com visual moderno, perfeitamente alinhados aos padrões estabelecidos no mercado.
O Bootstrap encapsula o framework JQuery, adicionando diversas funcionalidades por meio de classes CSS.
Podemos baixar o framework no endereço https://getbootstrap.com/. Além de oferecer diversas opções de
formatação para componentes, como botões e caixas de texto, temos a definição de contêineres, muito
úteis para a organização da tela.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 64/89
10/04/2023, 21:18 Camada de visão
Estilos de botões
Para compreender a utilização do Bootstrap, vamos criar o arquivo Exemplo015.html, em um projeto Web
do NetBeans, dando continuidade aos exemplos iniciais do conteúdo.
HTML
content_copy
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Exemplo015</title>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7
8 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.c
9 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundl
10
11 </head>
12 <body>
13 <div class="container">
14 <h2>Estilos de Botões</h2>
No cabeçalho do arquivo, temos as importações necessárias para uso do Bootstrap, ou seja, a folha de
estilo bootstrap.min.css e o script bootstrap.bundle.min.js, ambos obtidos a partir do repositório npm, na
versão 5.0.2. Todos os arquivos que utilizarem o framework deverão ter as mesmas importações de nosso
exemplo.
Podemos observar a definição da área principal do aplicativo, com a classe container, e diferentes
formatações para os botões, com a classe btn, que pode ser especializada para suas subclasses, como btn-
success e btn-info, modificando o aspecto dos botões, segundo padrões adotados nas diferentes
plataformas, particularmente Web e móvel.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 65/89
10/04/2023, 21:18 Camada de visão
HTML
content_copy
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Exemplo016</title>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7
8 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.c
9 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundl
10
11 </head>
12 <body>
13 <div class="container">
14 <h2>Exemplo de Modal</h2>
Na primeira parte do código, temos um botão, configurado com o aspecto btn-danger, e dois atributos
especiais, data-bs-toggle e data-bs-target: o primeiro define que será alterada a visibilidade de um
elemento modal, e o segundo indica o modal a partir do id. Em seguida, temos a construção do modal em si,
com id myModal, por meio de tags div.
Comentário
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 66/89
10/04/2023, 21:18 Camada de visão
A divisão de nível mais alto do diálogo é configurada com as classes modal e fade, além de usar um atributo
role, com valor dialog, o que indica uma caixa de diálogo. Em seguida, temos um segundo nível, configurado
como modal-dialog, e um terceiro, do tipo modal-content, que será responsável pelo conteúdo interno da
caixa de diálogo.
O conteúdo do diálogo é composto de três áreas, configuradas como modal-header, para as informações de
título, modal-body, para as informações que serão exibidas, e modal-footer, para a parte inferior do diálogo,
normalmente com alguns botões de resposta.
Os dois botões são configurados para o fechamento do diálogo, por meio do atributo data-bs-dismiss,
utilizando o valor modal. O primeiro é o botão de fechamento padrão para janelas, posicionado no canto
superior direito, e o segundo, um botão padrão, colocado na parte inferior. Podemos observar nosso diálogo
sendo ativado:
Sistema de Grid
O sistema de grid do Bootstrap é outro elemento importante, utilizado na organização da tela a partir de
divisões. Ele segmenta a tela em até 12 colunas, que podem ser combinadas, como na listagem seguinte,
que deverá ficar no arquivo Exemplo017.html.
HTML
content_copy
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Exemplo017</title>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7 <style> div {border: black dashed thin} </style>
8
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 67/89
10/04/2023, 21:18 Camada de visão
9 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.c
10 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundl
11
12 </head>
13 <body>
14 <div class="container-fluid">
Temos a primeira linha (row) com duas células de uma coluna (col-sm-1), uma célula de duas colunas (col-
sm-2) e duas de quatro colunas (col-sm-4), a segunda linha com uma célula de quatro colunas e uma de
oito colunas (col-sm-8), e apenas uma célula de 12 colunas (col-sm-12) na terceira linha. O resultado pode
ser observado a seguir:
HTML
content_copy
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Exemplo018</title>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7
8 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.c
9 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundl
10
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 68/89
10/04/2023, 21:18 Camada de visão
11 </head>
12 <body>
13 <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
14
A barra de navegação do exemplo poderia ser utilizada como menu principal do sistema, pois viabiliza
mudança de páginas e indicação da opção corrente de forma automática. Definimos o componente de
navegação no nível mais alto, utilizando fundo escuro (navbar-dark e bg-dark), além do preenchimento
horizontal (navbar-expand-lg).
O conteúdo do menu é divido em três colunas, segundo os valores de grid do Bootstrap. A primeira contém
a opção principal do menu (navbar-brand), e a última, um botão comum, no estilo btn-danger. Na coluna do
meio, temos uma lista, configurada como navbar-nav, em que cada item é uma opção de navegação (nav-
item) contendo um link (nav-link), sendo a opção corrente configurada no link por meio da classe active.
Definição do menu
Utilizar o framework Bootstrap sob o Thymeleaf é uma tarefa simples, pois não requer grandes
modificações nos templates HTML. Nossa preocupação inicial será apenas a inclusão de uma dependência
no arquivo pom.xml, como no fragmento a seguir:
Arquivo De Configuração
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 69/89
10/04/2023, 21:18 Camada de visão
Os elementos WebJars são as bibliotecas do Bootstrap oferecidas no formato jar, para permitir a utilização
ao nível do projeto, sem a necessidade de acesso ao repositório remoto. Aqui foi escolhida a versão 5.0.2,
devido à existência de documentação mais completa.
Vamos acrescentar a página menu.html no projeto ExemploTh002, nosso exemplo de CRUD, no diretório
templates, como as demais páginas, utilizando o conteúdo a seguir:
HTML
content_copy
O código utilizado é apenas uma adaptação de nosso menu anterior, mas, agora, com indicação real de
navegação. Esse template será incluído em todas as páginas, aproveitando o recurso de fragmentos
oferecido pelo Thymeleaf.
dos links passam a apontar para as rotas de nosso sistema, sempre por
meio do atributo th:href, com a utilização de arroba para correção.
Temos ainda a indicação da opção ativa com uma inclusão condicional de classe, efetuada no atributo
th:classappend, com base em uma condição na qual o estilo active será utilizado apenas quando a variável
pagina tiver o valor equivalente ao do teste.
HTML
content_copy
Nosso novo template inclui os arquivos CSS e JS necessários para o Bootstrap, no cabeçalho, sempre com
a utilização do Thymeleaf para a correção dos endereços.
A utilização do fragmento ocorre imediatamente no início do corpo da página, com uma div que tem o
conteúdo substituído, por meio do atributo th:replace, em que indicamos o template (menu) e o nome do
fragmento (menuprincipal). Note a utilização de til para uso do fragmento, bem como a passagem da
variável pagina na chamada, que, nesse caso, estará em branco, pois não se trata de nenhuma das opções
de cadastro.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 71/89
10/04/2023, 21:18 Camada de visão
Agora, vamos modificar a classe HomeController, criada anteriormente, para que utilize o novo template na
rota referente à raiz. Vamos utilizar o código apresentado a seguir, mantendo a chamada do exemplo antigo
na rota /old:
JAVA
content_copy
Neste ponto, é possível navegar para as páginas de cadastro, mas sem a possibilidade de usar o menu para
retornar porque não foi incluído nos templates. Precisamos alterar os templates para inclusão do menu, o
que é feito por meio da adição das importações do Bootstrap no final do cabeçalho, e inclusão do fragmento
imediatamente no início do corpo da página.
O trecho de código apresentado a seguir mostra a modificação que precisa ser efetuada nos templates
deptolist e deptodata, de forma semelhante à página inicial, mas, agora, utilizando o valor "departamentos"
para a variável do fragmento:
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 72/89
10/04/2023, 21:18 Camada de visão
Executando novamente o aplicativo, teremos acesso às páginas de departamento com exibição do menu,
tanto para a listagem quanto para o cadastro, e poderemos retornar para a listagem rapidamente com o
clique sobre a opção de menu. Também teremos a indicação da opção de cadastro em uso, com fonte mais
clara, como podemos observar na imagem seguinte:
O mesmo procedimento deve ser feito para os templates funcdata e funclist, mas, agora, com a utilização
do valor "funcionarios" na variável do fragmento:
HTML
content_copy
Definimos as classes de botão para os links e a formatação da tabela, em que foram utilizadas as classes
table e table-striped, para expandir o conteúdo na largura da página e trabalhar com alternância de fundo
nas linhas. Temos uma classe col-sm-2, aplicada às células com os links de alteração e exclusão, para que
não utilizem um espaçamento maior do que o necessário.
Todos os links receberam a classe btn, sendo adotado btn-danger para exclusão, e btn-primary para
inclusão e alteração, além da adoção de tamanho pequeno para os botões de alteração e exclusão, por meio
da classe btn-sm. O resultado é apresentado a seguir:
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 74/89
10/04/2023, 21:18 Camada de visão
O resultado das alterações efetuadas pode ser observado na imagem seguinte, obtida durante a execução
do sistema:
Templates de cadastros
Podemos modificar os formulários do sistema, a começar pelo template deptodata.
As alterações efetuadas foram mínimas, incluindo o encapsulamento do conteúdo original em uma div com
a classe container, e o uso das classes btn e btn-primary no botão de envio. Quanto aos componentes de
entrada, cada conjunto formado por label e input é colocado em uma div do tipo form-group, além do uso da
classe form-control no input e form-label no label, o que traz, além de boa organização, alguns efeitos
visuais no ganho de foco.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 76/89
10/04/2023, 21:18 Camada de visão
A presença de uma caixa de seleção levou à adoção da classe form-select. Vejamos o resultado das
modificações:
Tratamento de erros
Em muitas situações, você deve ter tentado excluir um departamento e ocorreu um erro, o que normalmente
é causado pela quebra da integridade referencial, imposta pelo relacionamento de um para muitos. É
interessante informar o erro ao usuário de forma adequada, utilizando mensagens claras. Faremos isso
aproveitando nossa tela inicial, no template home, de acordo com a listagem seguinte:
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 77/89
10/04/2023, 21:18 Camada de visão
Tudo que fizemos foi acrescentar uma div com a classe container, no primeiro nível, e uma div interna com
as classes alert e alert-danger, que será responsável por emitir um alerta, na tela principal, com a
mensagem de erro. O texto da mensagem é preenchido pelo atributo th:text, mas será exibido apenas se um
objeto de mensagem for enviado a partir do controlador, com base na condição utilizada no atributo th:if.
JAVA
content_copy
Execute novamente o aplicativo e tente remover um departamento que tenha funcionários, o que fará exibir
a mensagem enviada a partir do tratamento da exceção pelo controlador, como observado a seguir:
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 78/89
10/04/2023, 21:18 Camada de visão
Configuração da autenticação
Nosso aplicativo está totalmente funcional, mas seria interessante acrescentar algum modelo de
autenticação. Não trabalharemos com um padrão robusto, mas apenas com um exemplo simples, adotando
usuário fixo no controlador de autenticação, o que não impedirá a utilização de todo o fluxo de execução,
com os componentes associados e a integração com Thymeleaf.
Arquivo De Configuração
content_copy
Tentando executar novamente o aplicativo, será exibida a tela de login, impedindo a utilização do sistema,
pois a autenticação não está configurada. Precisamos configurá-la criando a classe AuthController, no
pacote com.universidade.
Java
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 79/89
10/04/2023, 21:18 Camada de visão
Atenção!
No método configure, tendo como parâmetro um objeto do tipo HttpSecurity, efetuamos todo o controle de
autenticação, com bloqueio por padrão, mas liberando as rotas para a raiz e para o login. Outro elemento
configurado é o modelo utilizado para o login, que, no caso, será feito a partir de um formulário (formLogin),
além do redirecionamento do logout para a página inicial, por meio de logoutSuccessUrl, impedindo que
seja solicitado um novo login de imediato.
O segundo método configure, com parâmetro do tipo WebSecurity, é necessário para garantir a
funcionalidade do Bootstrap, mesmo que o usuário não esteja autenticado. Para tal, usamos a diretiva
ignoring, aplicada a toda rota partindo de webjars.
Já podemos executar nosso projeto e verificar como o login é solicitado quando acessamos o cadastro de
departamentos ou o de funcionários. Nosso próximo passo será implementar o logout, com a modificação
do template menu, apenas no trecho em que encontramos o botão de saída do sistema, conforme o
fragmento de código apresentado a seguir:
HTML
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 80/89
10/04/2023, 21:18 Camada de visão
Trocamos o botão por um link, apontando para a rota logout, e permitimos sua visualização apenas quando
há um usuário logado, o que é feito com o teste isAuthenticated, no atributo sec:authorize. Apenas com a
utilização dos extras do Thymeleaf para integração com Spring Security, incluídos nas dependências do
projeto, foi possível utilizar o dialeto específico voltado para a segurança.
HTML
content_copy
Por se tratar de uma personalização, devemos manter a chamada do formulário e o nome de cada campo.
No caso, os campos são username e password, com envio de informação para /login, no modo POST.
Temos ainda uma div configurada como alert-danger para avisar que os valores utilizados são inválidos, a
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 81/89
10/04/2023, 21:18 Camada de visão
qual é ativada apenas quando existe param.error fornecido pelo controlador do Spring Security.
Todas as demais configurações utilizadas são semelhantes às que foram adotadas nas demais páginas do
sistema. Podemos observar a aparência da nova tela de login a seguir:
Novamente, temos que nos integrar ao comportamento do framework. Tudo de que precisamos é uma
chamada para a rota /logout em modo POST. Nossa janela apenas apresenta um título, mensagem para o
usuário, e botão do tipo btn-danger, para efetivar o logout, como podemos observar a seguir:
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 82/89
10/04/2023, 21:18 Camada de visão
Para que as personalizações sejam efetivadas, precisamos adicionar dois mapeamentos em modo GET na
classe HomeController.
JAVA
content_copy
As rotas chamadas no modo GET direcionarão para nossos templates, enquanto o modo POST é
interceptado pelo Spring Security, mantendo todo o arcabouço de autenticação.
Precisamos alterar o método configure, com parâmetro do tipo HttpSecurity, em nossa classe
AuthController, responsável pela autenticação dos usuários, de acordo com o fragmento de código
apresentado a seguir. Note que incluímos apenas os elementos necessários para indicar as rotas para o
login (loginPage) e para o logout (logoutUrl):
JAVA
content_copy
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 83/89
10/04/2023, 21:18 Camada de visão
Ao trabalhar com modelos mais robustos de autenticação, podem ser necessárias alterações no arquivo
application.properties, bem como no acesso a bancos de dados externos.
video_library
Teoria na prática
Construção de Menus com Bootstrap.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 84/89
10/04/2023, 21:18 Camada de visão
A btn-primary
B btn-success
C btn-info
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 85/89
10/04/2023, 21:18 Camada de visão
D btn-danger
E btn-link
As classes específicas para botões apresentam cores e formatos padronizados para cada ambiente de
execução quando adotamos o Bootstrap. Quanto ao exemplo de nosso sistema, a exclusão de todos os
registros de uma base é sempre uma operação perigosa, que exige plena atenção do usuário na
confirmação, o que levará à adoção da classe btn-danger, como em < button class=".btn .btn-danger" >
Confirmar < /button >, causando a utilização da cor vermelha, normalmente associada ao perigo.
Questão 2
Uma caraterística muito interessante do Thymeleaf é sua fácil integração com o modelo de segurança
do Spring, com base no Spring Security, o que permite a definição de templates com o controle da
disponibilidade de elementos para perfis específicos de usuários, ou simplesmente a alternância da
visibilidade de algum trecho quando ocorre autenticação. Para o segundo caso, qual método retorna ao
estado atual da autenticação?
A isLogged
B isAuthorized
C isAuthenticated
D isCertified
E isOpened
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 86/89
10/04/2023, 21:18 Camada de visão
Para integrar o Thymeleaf com Spring Security precisamos apenas acrescentar a dependência
thymeleaf-extras-springsecurity na versão utilizada pelo projeto. Com o acréscimo dessa dependência,
o prefixo sec (Security) fica disponível para uso nos atributos das tags, com acesso aos mecanismos
de segurança do ambiente.
Considerações finais
De forma geral, pessoas têm competências diferentes. Muitos programadores não apresentam habilidade
para a construção de interfaces de usuário complexas, algo que é uma característica dos designers.
Entretanto, com a alta padronização das interfaces atuais, surgiram ferramentas que viabilizam a
construção de interfaces de alta qualidade com baixo esforço.
Mesmo com a disponibilidade dessas ferramentas, o conhecimento dos princípios elementares para a
construção de páginas é necessário, principalmente para sua organização estrutural. É preciso conhecer
sintaxes como HTML, Java Script e CSS, além de frameworks comuns no mercado, como JQuery UI.
Após a compreensão dos princípios para a construção das páginas, precisamos integrá-las com os
componentes da camada Controller, dentro de uma arquitetura MVC. O uso de Thymeleaf nos proporcionou
essa integração de forma natural, com base em templates HTML, que podem ser manipulados por
designers, por meio de ferramentas de edição apropriadas.
Com as interfaces integradas, os sistemas garantem as funcionalidades definidas nos requisitos, mas o
mercado exige características como responsividade e padronização no design das páginas. O Bootstrap
permite o acréscimo dessas características de forma não invasiva, por meio de classes para estilização,
garantindo qualidade e produtividade necessárias.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 87/89
10/04/2023, 21:18 Camada de visão
headset
Construção da camada View
Para encerrar, ouça sobre processo de criação para páginas HTML, bem como a integração com a camada
de controle de um sistema Spring Web por meio do Thymeleaf.
Referências
BOAGLIO, F. Spring Boot. 1. ed. São Paulo: Casa do Código, 2017.
BURKE, B; MONSON, R. Enterprise Java Beans 3.0. 5. ed. São Paulo: Pearson, 2007.
DEITEL, H; DEITEL, P. Java, Como Programar. 10. ed. São Paulo: Pearson, 2016.
HORSTMANN, C. Modern Java Script For The Impatient. 1. ed. USA: Addison-Wesley, 2020.
PATEL, N. Spring 5.0 Projects. 1. ed. Reino Unido: Packt Publishing, 2019.
TURNQUIST, G. Learning Spring Boot 2.0. 2. ed. Reino Unido: Packt Publishing, 2017.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 88/89
10/04/2023, 21:18 Camada de visão
Explore +
Acesse o guia CSS Tutorial, disponibilizado pela W3Schools, e navegue pelas opções do menu, no lado
esquerdo da página, para aprender tudo que é necessário sobre CSS.
Explore os diversos exemplos disponibilizados pelo JQuery UI (jqueryui.com), navegando pelas opções do
menu lateral esquerdo e utilizando a opção "view source" para conferir os códigos.
Confira o guia Bootstrap 5 Tutorial - An Ultimate Guide for Beginners e navegue pelas opções do menu
lateral esquerdo para aprender a utilizar o Bootstrap com base em exemplos.
Leia o artigo Working with Fragments in Thymeleaf, oferecido pelo Baeldung, e compreenda melhor a
utilização de fragmentos no Thymeleaf.
Leia o artigo Use Thymeleaf Templates with Spring WebFlux to Secure Your Apps, de Jimena Garbarino,
descrevendo a autenticação em arquitetura de fluxo com Spring e Thymeleaf.
https://stecine.azureedge.net/repositorio/00212ti/03593/index.html# 89/89