Skip to main content
Dat 2. semester
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Library

I dag bygger vi ovenpå jeres bibliotekssystem.

Målet er, at vi går fra:

“Jeg kan logge ind”

til:

“Serveren ved, hvem jeg er, og kan vise mig de data, der hører til mig.”

Derefter laver vi en adminbruger, som får adgang til nogle ekstra funktioner.


Først: Hvis I vil undgå at skriv templates\ og .html hver gang I renderer en side, så kan i lave en lille konfigurationsklasse:

package configuration;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

public class ThymeleafConfig {

    public static TemplateEngine templateEngine() {

        TemplateEngine templateEngine = new TemplateEngine();

        ClassLoaderTemplateResolver templateResolver =
                new ClassLoaderTemplateResolver();

        templateResolver.setPrefix("templates/");
        templateResolver.setSuffix(".html");

        templateEngine.setTemplateResolver(templateResolver);

        return templateEngine;
    }
}

og bruge den i jeres main:

public static void main(String[] args) {

        Javalin app = Javalin.create(config -> {

            config.staticFiles.add("/public");

            config.fileRenderer(new JavalinThymeleaf(ThymeleafConfig.templateEngine()));

            UserController.setRoutes(config);
            LoanController.setRoutes(config);
            AdminController.setRoutes(config);

        }).start(7070);
    }

Opgave 1: Opret en bruger

Lav funktionaliteten til at oprette en bruger.

Når formularen sendes:

  1. Hent username og password med ctx.formParam().
  2. Opret brugeren gennem UserService.
  3. Hvis brugeren bliver oprettet, skal brugeren gemmes i session scope.
  4. Vis velkomstsiden.

Test, at brugeren bliver oprettet.

Husk

Vi gemmer hele User-objektet i sessionen:

ctx.sessionAttribute("user", user);

Opgave 2: Hvem er logget ind?

På velkomstsiden skal vi vise brugernavnet på den bruger, der er logget ind.

Brug Thymeleaf til at hente brugeren fra sessionen:

<span th:text="${session.user.username}">bruger</span>

Test derefter, at brugernavnet stadig bliver vist, når I laver en ny request.

Refleksion

  • Hvad er en session?
  • Hvorfor har vi brug for session scope?
  • Hvad er forskellen på session scope og attribute scope?

Opgave 3: Vis brugerens lån

På velkomstsiden skal brugeren kunne se sine bøger.

Brugeren ligger allerede i sessionen, og brugerens lån ligger på User.

Brug th:each:

<div class="books">

    <div class="book" th:each="loan : ${session.user.loans}">

        <h2 th:text="${loan.book.title}">
            Grapes of Wrath
        </h2>

        <p th:text="${loan.book.author.name}">
            John Steinbeck
        </p>

    </div>

</div>

Refleksion

Hvad sker der egentlig her?

session.user
loans
loan
book
author
name

Og hvad betyder:

th:each="loan : ${session.user.loans}"

Admin

Nu skal vi have forskellige typer brugere.

Opgave 4: Lav en adminbruger

Opret en adminbruger i vores system. I kan bare hardcode det i UserFactory.

Adminbrugeren skal have:

username
password
isAdmin

Test, at adminbrugeren kan logge ind.


Opgave 5: Adminfunktioner

På velkomstsiden skal administratoren have adgang til nogle ekstra funktioner.

Lav knapper til:

  • Alle brugere
  • Alle bøger
  • Find bruger
  • Find forfatters bøger

De skal kun vises, hvis den aktuelle bruger er administrator.

Brug Thymeleaf th:if:

<div th:if="${session.user.isAdmin}">
    ...
</div>

Refleksion

Hvad er forskellen på:

Authentication

Hvem er du?

Authorization

Hvad må du?


Attribute scope

Nu skal vi begynde at sende data fra controlleren til den konkrete HTML-side.

Opgave 6: Alle brugere

Lav en route:

/users

Controlleren skal:

  1. hente alle brugere fra UserService
  2. gemme listen i attribute scope
  3. rendere en Thymeleaf-side

Fx:

ctx.attribute("users", users);
ctx.render("users.html");

Lav derefter users.html.


Opgave 7: Vis brugerne i en tabel

Vis brugerne i en HTML-tabel.

Tabellen kan fx indeholde:

BrugernavnAdmin
Sallyfalse
admintrue

Brug th:each til at lave én række for hver bruger:

<tr th:each="user : ${users}">
    <td th:text="${user.username}">Sally</td>
    <td th:text="${user.isAdmin}">false</td>
</tr>

Opgave 8: Alle bøger

Lav en route:

/books

Controlleren skal:

  1. hente alle bøger
  2. lægge dem i attribute scope
  3. rendere books.html

Vis bøgerne i en Thymeleaf-tabel.

Tabellen skal vise:

TitelForfatterISBN

Brug th:each.


Opgave 9: Find bruger

Lav en formular, hvor administratoren kan søge efter en bestemt bruger.

<form action="/finduser" method="get">
    <input type="text" name="username">
    <button type="submit">Find bruger</button>
</form>

Controlleren skal hente brugernavnet med:

String username = ctx.queryParam("username");

Find brugeren gennem UserService.

Hvis brugeren findes:

ctx.attribute("user", user);
ctx.render("userinfo.html");

Vis brugerens oplysninger i en Thymeleaf-tabel.

Hvis brugeren ikke findes, skal der vises en passende fejlbesked.


Opgave 10: Find en forfatters bøger

Lav en formular, hvor administratoren kan søge efter en forfatter.

<form action="/booksbyauthor" method="get">
    <input type="text" name="author">
    <button type="submit">Find forfatters bøger</button>
</form>

Controlleren skal hente:

String author = ctx.queryParam("author");

Brug findByAuthor(...) i BookService til at finde bøgerne.

Læg resultatet i attribute scope:

ctx.attribute("books", books);

Vis resultatet i books.html.


Opgave 11: Genbrug books.html

Læg mærke til, at books.html ikke behøver at vide, hvor bøgerne kommer fra.

Den får bare en liste:

books

Derfor kan den samme side bruges til:

  • alle bøger
  • bøger af en bestemt forfatter

Dagens røde tråd

Vi har nu bevæget os gennem hele kæden:

HTML
Request
Controller
Service
Data
Controller
Attribute / Session
Thymeleaf
HTML

Og vi har brugt:

Session scope
til data, der skal leve på tværs af requests.

Attribute scope
til data, der skal bruges ved den konkrete rendering.

Thymeleaf
til at bruge data fra Java til at generere HTML.

Controlleren
til at koble HTTP, Java og HTML sammen.