-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
461 lines (437 loc) · 26 KB
/
Copy pathindex.html
File metadata and controls
461 lines (437 loc) · 26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TADS Simulado — Spring Boot API</title>
<meta name="description" content="Resumo teórico e simulado de Spring Boot API — REST, JPA, Validação e Security/JWT, disciplina DSW.">
<script>
(function () {
var key = "tads-simulado-theme";
var stored = localStorage.getItem(key);
var theme = stored || (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
document.documentElement.setAttribute("data-theme", theme);
})();
</script>
<link rel="stylesheet" href="css/style.css">
</head>
<body id="top">
<header class="site-header">
<div class="header-inner">
<a class="brand" href="#top">
<span class="brand-mark">SBA</span>
<span class="brand-name">TADS-Simulado <span>/ Spring Boot API</span></span>
</a>
<nav class="site-nav">
<a href="#escopo">Escopo</a>
<a href="#simulado">Simulado</a>
<a href="#fontes">Fontes</a>
<button class="theme-toggle" id="theme-toggle" type="button" aria-label="Alternar tema claro/escuro">
<svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
<svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8Z"/></svg>
</button>
</nav>
</div>
</header>
<main class="container">
<section class="hero">
<span class="eyebrow">TADS · Desenvolvimento de Sistemas Web</span>
<h1>Simulado — Spring Boot API</h1>
<p class="lead">REST com Spring MVC, persistência com JPA/Spring Data JPA e autenticação com Spring Security + JWT. Baseado no conteúdo ministrado na disciplina DSW.</p>
<div class="meta-chips">
<span class="chip"><strong id="chip-count">20</strong> questões</span>
<span class="chip">~<strong>15</strong> min</span>
<span class="chip">Nível <strong>Intermediário</strong></span>
<span class="chip">Origem <strong>DSW</strong></span>
</div>
<div class="hero-actions">
<button class="btn btn-primary" id="start-btn" type="button">Iniciar simulado</button>
<a class="btn btn-ghost" href="#escopo">Ver escopo</a>
</div>
</section>
<section id="escopo">
<div class="section-head">
<span class="eyebrow">Estrutura</span>
<h2>Como o conteúdo se conecta</h2>
<p>O fluxo de uma API Spring Boot típica — da requisição até o banco de dados — organiza os capítulos deste simulado.</p>
</div>
<div class="pipeline">
<div class="pipeline-step"><span class="n">01</span>Fundamentos Spring<br>Bean · IoC · DI</div>
<div class="pipeline-step"><span class="n">02</span>Controller REST<br>Rotas · Verbos HTTP</div>
<div class="pipeline-step"><span class="n">03</span>Validação<br>Bean Validation</div>
<div class="pipeline-step"><span class="n">04</span>JDBC & ORM<br>Conceitos de base</div>
<div class="pipeline-step"><span class="n">05</span>JPA<br>Entidades · Relações</div>
<div class="pipeline-step"><span class="n">06</span>Spring Data JPA<br>Repository · Query</div>
<div class="pipeline-step"><span class="n">07</span>Security/JWT<br>AuthN · AuthZ</div>
</div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Capítulos</span>
<h2>Temas cobrados</h2>
<p>Distribuição das questões por área temática.</p>
</div>
<div class="chapters-grid" id="chapters-grid"></div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Fundamentação teórica</span>
<h2>Camadas de persistência: do JDBC ao Spring Data JPA</h2>
<p>ORM é uma técnica; JPA é a especificação de como aplicar essa técnica em Java; Hibernate é uma das bibliotecas que implementam essa especificação; e Spring Data JPA é um módulo do Spring que simplifica o uso do JPA — sem fazer parte do Jakarta/Java EE.</p>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Camada</th><th>O que é</th><th>Responsabilidade</th></tr>
</thead>
<tbody>
<tr>
<td>JDBC</td>
<td>API de baixo nível para conexão e execução de SQL</td>
<td>Abrir/fechar conexão, montar <code>PreparedStatement</code> e mapear <em>manualmente</em> cada linha do <code>ResultSet</code> para um objeto</td>
</tr>
<tr>
<td>ORM</td>
<td>Técnica/conceito (Object-Relational Mapping)</td>
<td>Definir como registros de tabelas se convertem em objetos, sem detalhar a implementação</td>
</tr>
<tr>
<td>JPA</td>
<td>Especificação Jakarta Persistence, parte do Jakarta EE</td>
<td>Padronizar anotações (@Entity, @Id...), o EntityManager e a linguagem JPQL, sem amarrar a um SGBD</td>
</tr>
<tr>
<td>Hibernate</td>
<td>Implementação (provider) do JPA</td>
<td>Traduzir as operações do EntityManager em SQL de fato; é a implementação usada pelo Spring Boot</td>
</tr>
<tr>
<td>Spring Data JPA</td>
<td>Módulo do Spring (não é parte do JEE)</td>
<td>Eliminar boilerplate: gera repositórios e queries a partir de interfaces e nomes de método</td>
</tr>
</tbody>
</table>
</div>
<div class="note">
<strong>Por que isso importa</strong>
No JDBC puro, cada consulta exige abrir conexão, escrever o SQL, iterar o <code>ResultSet</code> e popular o objeto manualmente. O ORM (via JPA/Hibernate) automatiza esse mapeamento: o desenvolvedor manipula objetos Java e o provider gera o SQL por trás. O Spring Data JPA vai um passo além, eliminando também a escrita repetitiva de métodos de CRUD e consultas simples.
</div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Fundamentação teórica</span>
<h2>Bean, IoC e Injeção de Dependência</h2>
<p>A base do Spring Framework é o container de <strong>IoC (Inversion of Control)</strong>: em vez de a própria classe criar suas dependências com <code>new</code>, é o container que cria, configura e entrega os objetos prontos para uso.</p>
</div>
<div class="note">
<strong>O que é um Bean</strong>
Bean é o termo do Spring para um objeto cuja criação e ciclo de vida são gerenciados pelo container — e não pelo próprio desenvolvedor. Uma classe se torna elegível a virar Bean principalmente de duas formas:
<ul>
<li><code>@Component</code> (ou suas especializações <code>@Service</code>, <code>@Repository</code>, <code>@Controller</code>/<code>@RestController</code>) — marca a própria classe para ser detectada e instanciada pelo <em>component scan</em>.</li>
<li><code>@Bean</code> — anotação usada em métodos dentro de uma classe de configuração (<code>@Configuration</code>), retornando o objeto que deve ser registrado como Bean.</li>
</ul>
Um Bean <strong>não</strong> é um arquivo de configuração, uma tabela de banco ou um endpoint — é sempre um objeto gerenciado pelo container.
</div>
<div class="note">
<strong>Injeção de Dependência (DI): construtor vs. atributo</strong>
O Spring resolve as dependências entre Beans automaticamente (Dependency Injection), e isso pode ser feito de formas diferentes:
<ul>
<li><code>@Autowired</code> em atributo — funciona, mas esconde as dependências dentro da classe e dificulta a criação de instâncias em testes sem subir o container.</li>
<li><strong>Injeção via construtor</strong> — é a forma recomendada em projetos novos: deixa explícito quais dependências são obrigatórias, permite declarar os atributos como <code>final</code> (imutáveis) e facilita a criação de testes unitários passando os mocks diretamente pelo construtor, sem depender do Spring.</li>
</ul>
As duas formas funcionam tecnicamente em versões atuais do Spring — a diferença é de clareza de design e testabilidade, não de disponibilidade do recurso.
</div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Fundamentação teórica</span>
<h2>Escopos de Bean no Spring</h2>
<p>O escopo define quantas instâncias de um Bean existem e por quanto tempo elas vivem. Fora do Singleton (padrão), os demais escopos exigem um contexto web ativo.</p>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Escopo</th><th>Características</th><th>Depende de contexto web?</th></tr>
</thead>
<tbody>
<tr><td>Singleton</td><td>Uma única instância por aplicação — é a configuração padrão quando nenhum escopo é indicado</td><td>Não</td></tr>
<tr><td>Prototype</td><td>Cada injeção/acesso gera um novo objeto</td><td>Não</td></tr>
<tr><td>Request</td><td>Bean criado e mantido durante o processamento de uma única requisição HTTP</td><td>Sim</td></tr>
<tr><td>Session</td><td>Bean criado e mantido durante a sessão de um usuário</td><td>Sim</td></tr>
<tr><td>Application</td><td>Bean criado uma vez por aplicação rodando dentro de um contexto web (equivalente ao ServletContext)</td><td>Sim</td></tr>
<tr><td>Websocket</td><td>Bean criado e mantido durante uma sessão acessada via Websocket</td><td>Sim</td></tr>
</tbody>
</table>
</div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Fundamentação teórica</span>
<h2>Controllers REST: rotas, verbos e anotações</h2>
<p>Uma API REST expõe recursos através de URLs e verbos HTTP, retornando dados (geralmente JSON) no corpo da resposta — diferente de uma aplicação MVC tradicional (SSR), em que o Controller retorna o nome de uma <em>view</em> a ser renderizada no servidor.</p>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Verbo HTTP</th><th>Operação</th><th>Status de sucesso típico</th></tr>
</thead>
<tbody>
<tr><td>GET</td><td>Consultar um recurso ou coleção</td><td>200 OK</td></tr>
<tr><td>POST</td><td>Incluir um novo recurso</td><td>201 Created, com o cabeçalho <code>Location</code> apontando para a URI do recurso criado</td></tr>
<tr><td>PUT</td><td>Atualizar (substituir) um recurso existente</td><td>200 OK ou 204 No Content</td></tr>
<tr><td>DELETE</td><td>Remover um recurso</td><td>204 No Content</td></tr>
</tbody>
</table>
</div>
<div class="note">
<strong>Principais anotações</strong>
<ul>
<li><code>@RestController</code> — equivale a <code>@Controller</code> + <code>@ResponseBody</code> aplicado a todos os métodos: o valor retornado é serializado diretamente como corpo da resposta HTTP (normalmente JSON), em vez de ser interpretado como o nome de uma view.</li>
<li><code>@PathVariable</code> — captura um valor a partir do próprio caminho da URL, como o <code>{id}</code> em <code>/produtos/{id}</code>.</li>
<li><code>@RequestParam</code> — lê parâmetros enviados via query string (ex.: <code>/produtos?categoria=roupas</code>).</li>
<li><code>@RequestBody</code> — converte o corpo da requisição (JSON) em um objeto Java.</li>
</ul>
</div>
<div class="note">
<strong>Stateless</strong>
Uma API REST é dita <em>stateless</em> quando o servidor não mantém nenhum estado de sessão do cliente entre requisições: cada requisição deve trazer, por si só, todas as informações necessárias para ser processada (incluindo credenciais/token de autenticação, quando aplicável).
</div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Fundamentação teórica</span>
<h2>Validação de dados com Bean Validation</h2>
<p>O Bean Validation (parte da especificação Jakarta) permite declarar regras de validação diretamente nos atributos das classes, usando anotações. O Spring integra essas anotações ao fluxo de requisições REST.</p>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Anotação</th><th>Regra validada</th></tr>
</thead>
<tbody>
<tr><td>@NotNull</td><td>O valor não pode ser nulo</td></tr>
<tr><td>@NotBlank</td><td>String não pode ser nula, vazia ou só espaços</td></tr>
<tr><td>@Size</td><td>Tamanho mínimo/máximo de uma String, coleção etc.</td></tr>
<tr><td>@Email</td><td>Formato válido de e-mail</td></tr>
<tr><td>@Min / @Max</td><td>Valor numérico mínimo/máximo permitido</td></tr>
<tr><td>@Past</td><td>A data deve ser anterior ao momento atual (ex.: data de nascimento)</td></tr>
<tr><td>@Future</td><td>A data deve ser posterior ao momento atual</td></tr>
<tr><td>@Pattern</td><td>O valor deve casar com uma expressão regular</td></tr>
</tbody>
</table>
</div>
<div class="note">
<strong>@Valid e mensagens customizadas</strong>
<ul>
<li>Quando <code>@Valid</code> é usado junto de <code>@RequestBody</code> no parâmetro de um método, o Spring aciona a validação de todas as anotações de Bean Validation presentes na classe do objeto recebido, retornando erro 400 automaticamente caso alguma restrição seja violada.</li>
<li>Para customizar as mensagens de erro (por exemplo, para internacionalização/i18n) usando um arquivo de mensagens (<em>resource bundle</em>), é preciso registrar um <code>MessageSource</code> associado a um <code>LocalValidatorFactoryBean</code>, através de <code>bean.setValidationMessageSource(messageSource)</code>. As chaves de mensagem usadas nas anotações seguem o formato <code>{chave-mensagem}</code>.</li>
</ul>
</div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Fundamentação teórica</span>
<h2>Mapeamento de entidades com JPA</h2>
<p>Cada entidade JPA é uma classe Java anotada que representa uma tabela do banco de dados; seus atributos representam as colunas e os relacionamentos entre entidades representam chaves estrangeiras (ou tabelas associativas).</p>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Anotação</th><th>Para que serve</th></tr>
</thead>
<tbody>
<tr><td>@Entity / @Table</td><td>Marca a classe como entidade e, opcionalmente, define o nome da tabela mapeada</td></tr>
<tr><td>@Id</td><td>Marca o atributo que representa a chave primária da entidade</td></tr>
<tr><td>@GeneratedValue</td><td>Indica que o valor da chave primária será gerado automaticamente</td></tr>
<tr><td>@Column</td><td>Customiza detalhes da coluna mapeada (nome, tamanho, obrigatoriedade)</td></tr>
<tr><td>@Transient</td><td>Marca um atributo que existe na classe Java, mas <strong>não</strong> deve ser persistido no banco de dados</td></tr>
</tbody>
</table>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Relacionamento</th><th>Uso</th></tr>
</thead>
<tbody>
<tr><td>@ManyToOne</td><td>Usado do lado "muitos" de uma relação um-para-muitos — ex.: cada <code>ImagemProduto</code> pertence a um único <code>Produto</code></td></tr>
<tr><td>@OneToMany(mappedBy = ...)</td><td>Usado do lado "um" da mesma relação, referenciando o atributo dono do relacionamento do outro lado</td></tr>
<tr><td>@ManyToMany + @JoinTable</td><td>Relação muitos-para-muitos; <code>@JoinTable</code> define o nome da tabela intermediária e suas colunas de junção (<code>joinColumns</code> e <code>inverseJoinColumns</code>)</td></tr>
<tr><td>@OneToOne</td><td>Relação um-para-um entre duas entidades</td></tr>
</tbody>
</table>
</div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Referência rápida</span>
<h2>Formas de consulta com JPA</h2>
<p>Comparativo entre as quatro abordagens de consulta vistas no material.</p>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Abordagem</th><th>Como funciona</th><th>Quando usar</th></tr>
</thead>
<tbody>
<tr>
<td>Query Methods</td>
<td>Spring Data JPA gera a query a partir do nome do método (ex: <code>findByLastnameAndFirstname</code>)</td>
<td>Consultas simples, sem escrever SQL/JPQL manualmente</td>
</tr>
<tr>
<td>JPQL (@Query)</td>
<td>Query escrita à mão referenciando entidades e atributos Java, não tabelas do BD</td>
<td>Consultas mais elaboradas, ainda portáveis entre bancos</td>
</tr>
<tr>
<td>Criteria API</td>
<td>Consulta construída dinamicamente via código Java, com tipagem em tempo de desenvolvimento</td>
<td>Filtros dinâmicos/condicionais complexos</td>
</tr>
<tr>
<td>@NativeQuery</td>
<td>SQL nativo do banco, referenciando tabelas/colunas reais</td>
<td>Recursos específicos do SGBD que o JPQL não cobre</td>
</tr>
</tbody>
</table>
</div>
<div class="note">
<strong>Boas práticas no Spring</strong>
<ul>
<li><code>spring.jpa.open-in-view</code> vem habilitado por padrão, mantendo a conexão aberta durante toda a requisição — não é recomendado para produção.</li>
<li>Alternativas: escrever <code>JOIN FETCH</code> nas consultas, usar Entity Graph, ou representar o retorno com DTOs em vez das entidades diretamente.</li>
<li><code>fetch = EAGER</code> resolve o sintoma, mas pode causar o problema N+1 — prefira <code>LAZY</code> combinado com uma das alternativas acima.</li>
</ul>
</div>
<div class="table-wrap">
<table class="compare-table">
<thead>
<tr><th>Interface</th><th>O que adiciona</th></tr>
</thead>
<tbody>
<tr><td>Repository</td><td>Interface raiz "marcadora", sem métodos próprios</td></tr>
<tr><td>CrudRepository</td><td>Estende Repository; adiciona métodos básicos de CRUD (save, findById, findAll, delete...)</td></tr>
<tr><td>PagingAndSortingRepository</td><td>Estende CrudRepository; adiciona <code>findAll(Sort)</code> e <code>findAll(Pageable)</code>, com suporte a ordenação e paginação</td></tr>
<tr><td>JpaRepository</td><td>Estende PagingAndSortingRepository; adiciona operações específicas do JPA (flush, batch delete etc.)</td></tr>
</tbody>
</table>
</div>
<div class="note">
<strong>Query Methods</strong>
Ao declarar um método de repositório seguindo a convenção de nomes do Spring Data JPA (ex.: <code>findByLastnameAndFirstname</code>), o próprio Spring Data interpreta o nome do método — o prefixo <code>findBy</code>, os nomes dos campos da entidade e palavras-chave como <code>And</code>/<code>Or</code>/<code>Between</code> — e <strong>gera automaticamente</strong> a query JPQL correspondente, sem exigir implementação manual.
</div>
<div class="tags" id="tag-list"></div>
</section>
<section>
<div class="section-head">
<span class="eyebrow">Fundamentação teórica</span>
<h2>Autenticação e autorização com Spring Security e JWT</h2>
<p>Em uma API REST stateless, a autenticação costuma ser feita por token: o cliente envia usuário/senha uma única vez, recebe um token JWT (JSON Web Token) e passa a enviá-lo no cabeçalho <code>Authorization</code> em cada requisição subsequente.</p>
</div>
<div class="note">
<strong>Estrutura de um JWT</strong>
Um token JWT é uma string dividida em três partes separadas por pontos, sempre na ordem <strong>Header.Payload.Signature</strong>:
<ul>
<li><strong>Header</strong> — metadados do token, como o algoritmo de assinatura usado.</li>
<li><strong>Payload</strong> — os <em>claims</em>: dados do usuário e demais informações que o token carrega (ex.: id, papéis/roles, data de expiração).</li>
<li><strong>Signature</strong> — assinatura que garante que o conteúdo do token não foi alterado após ser emitido.</li>
</ul>
</div>
<div class="note">
<strong>Fluxo de autenticação stateless</strong>
Depois que o JWT é emitido, o servidor não precisa consultar novamente o banco de dados (ou a senha) a cada requisição: basta validar a assinatura e a expiração do token e confiar nas informações (claims) nele contidas. É essa autocontenção do token que permite que a API continue stateless, sem manter sessão do usuário no servidor.
</div>
</section>
<section id="simulado" class="quiz-shell">
<div class="section-head">
<span class="eyebrow">Simulado</span>
<h2>Teste seus conhecimentos</h2>
<p>20 questões de múltipla escolha, uma alternativa correta cada.</p>
</div>
<!-- Intro state -->
<div id="quiz-intro" class="card" style="text-align:center; padding:40px;">
<p style="color:var(--ink-soft); margin-bottom:22px;">Pronto para começar? Você pode revisar o feedback de cada questão antes de avançar.</p>
<button class="btn btn-primary" id="start-btn-2" type="button">Iniciar simulado</button>
</div>
<!-- Question state -->
<div id="quiz-question" class="hidden">
<div class="progress-wrap">
<div class="progress-meta">
<span id="progress-label">Questão 1 de 20</span>
<span class="score-pill">Acertos: <strong id="score-count">0</strong></span>
</div>
<div class="progress-track"><div class="progress-fill" id="progress-fill"></div></div>
</div>
<div class="card question-card">
<div class="question-eyebrow" id="question-chapter">Fundamentos Spring</div>
<p class="question-text" id="question-text"></p>
<div class="alternatives" id="alternatives"></div>
<div class="feedback" id="feedback">
<span class="fb-label" id="fb-label"></span><span id="fb-text"></span>
</div>
<div class="quiz-footer-actions">
<button class="btn btn-primary" id="next-btn" type="button" disabled>Próxima questão</button>
</div>
</div>
</div>
<!-- Results state -->
<div id="quiz-results" class="card results-card hidden">
<span class="eyebrow" style="justify-content:center;">Resultado</span>
<div class="results-score"><span id="final-score">0</span>/<span id="final-total">20</span></div>
<p class="results-note" id="results-note"></p>
<div class="results-actions">
<button class="btn btn-primary" id="retry-btn" type="button">Refazer simulado</button>
<a class="btn btn-ghost" href="#fontes">Ver fontes de estudo</a>
</div>
</div>
</section>
<section id="fontes">
<div class="sheet">
<span class="tick-tl"></span><span class="tick-br"></span>
<h2>Fontes</h2>
<p class="sheet-lead">Este resumo foi elaborado a partir do conteúdo teórico da disciplina de Desenvolvimento de Sistemas Web (DSW), organizado nos sete temas abaixo, com apoio da documentação oficial do Spring.</p>
<div class="source-list">
<a class="source-item" href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/" target="_blank" rel="noopener">
<span class="file-tag">BOOT</span>
<span class="file-label">Spring Boot Reference</span>
</a>
<a class="source-item" href="https://docs.spring.io/spring-framework/reference/core/beans/definition.html" target="_blank" rel="noopener">
<span class="file-tag">IOC</span>
<span class="file-label">IoC Container & Beans</span>
</a>
<a class="source-item" href="https://docs.spring.io/spring-data/jpa/reference/jpa.html" target="_blank" rel="noopener">
<span class="file-tag">JPA</span>
<span class="file-label">Spring Data JPA Reference</span>
</a>
<a class="source-item" href="https://docs.spring.io/spring-security/reference/servlet/architecture.html" target="_blank" rel="noopener">
<span class="file-tag">SEC</span>
<span class="file-label">Spring Security Architecture</span>
</a>
<a class="source-item" href="https://jakarta.ee/specifications/bean-validation/" target="_blank" rel="noopener">
<span class="file-tag">VAL</span>
<span class="file-label">Bean Validation Specification</span>
</a>
<a class="source-item" href="https://restfulapi.net/hateoas/" target="_blank" rel="noopener">
<span class="file-tag">REST</span>
<span class="file-label">HATEOAS</span>
</a>
</div>
<p class="source-citation">Baseado no conteúdo da disciplina Desenvolvimento de Sistemas Web (DSW), ministrada pelo Prof. Fernando Tsuda, e na documentação oficial do Spring (links acima).</p>
<p class="source-note">Os slides e materiais da disciplina DSW são de uso exclusivo dos alunos matriculados no curso e não são redistribuídos neste site — o conteúdo acima é um resumo teórico próprio, elaborado apenas para fins de estudo e revisão.</p>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container footer-inner">
<span>Resumo baseado no conteúdo da disciplina DSW (Prof. Fernando Tsuda) e na documentação oficial do Spring.</span>
<span>Simulado hospedado no <a href="https://github.com/SenacOS" target="_blank" rel="noopener">SenacOS</a></span>
</div>
</footer>
<script src="js/theme.js"></script>
<script src="js/quiz-data.js"></script>
<script src="js/quiz.js"></script>
</body>
</html>