Spring Namenconvention

Hallo,

die Frage ist vielleicht etwas dumm, beschäftigt mich aber sehr.

Es geht um ein Beispiel, wobei eine Form ausgewertet wird.
Zuerst die Dateien:

HTML-Seite "form"
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
        <form action="#" th:action="@{/}" th:object="${personForm}" method="post">
            <table>
                <tr>
                    <td>Name:</td>
                    <td><input type="text" th:field="*{name}" /></td>
                    <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
                </tr>
                <tr>
                    <td>Age:</td>
                    <td><input type="text" th:field="*{age}" /></td>
                    <td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age Error</td>
                </tr>
                <tr>
                    <td><button type="submit">Submit</button></td>
                </tr>
            </table>
        </form>
</body>
</html>
2. Der Conroller

Java:
package hello;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Controller
public class WebController implements WebMvcConfigurer{

    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/results").setViewName("results");
    }
    
    @GetMapping("/")
    public String showForm(PersonForm personForm) {
        return "form";
    }
    
    @PostMapping("/")
    public String checkPersonInfo(@Valid PersonForm personForm, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "form";
        }

        return "redirect:/results";
    }
}
3. PersonForm

Java:
package hello;

import javax.validation.constraints.Min;
import javax.validation.constraints.Size;

public class PersonForm {
    @Size(min=2, max=30)
    private String name;
    @Min(18)
    private Integer age;
    @Override
    public String toString() {
        return "PersonForm [name=" + name + ", age=" + age + "]";
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
}
Die "WebApplication"- Klasse ist normal.

Meine Frage ist einmal, dass Argumente der Methodenaufrufe insbesondere im Controller nicht verarbeitet werden. Es funktioniert aber dennoch.

Die Frage ist zum zweiten, welche Namen ich vergeben kann. Muss ein Controller den Begriff "Controller" im Namen haben?

Wo kann ich das sonst nachlesen, wie ich Namen der Klassen und Variablen gestalten muss?

Die Beziehung des HTML zum Controller ist mir auch nicht klar. Gibt es da eine gute Quelle, wo ich das nachlesen kann?
 
Erster Zwischenstand:

tatsächlich kann man auuf "spring.io" beim Durchsehen der Beispiele auch Quellen finden. Das Geheimnis der methoden liegt in den Annotationen. Es scheint nicht so zu sein, dass die Klassenbezeichnungen ausgwertet werden.

Aber es ist ja auch schöner statt z.B. dem klassischen "BindingResult br", das als "bindingResult" zu bezeichnen. Das macht das Programm jja letztlich auch viel lesbarer.
 
Meine Frage ist einmal, dass Argumente der Methodenaufrufe insbesondere im Controller nicht verarbeitet werden. Es funktioniert aber dennoch.
Was meinst du damit?

Die Frage ist zum zweiten, welche Namen ich vergeben kann. Muss ein Controller den Begriff "Controller" im Namen haben?

Wo kann ich das sonst nachlesen, wie ich Namen der Klassen und Variablen gestalten muss?
Nein, Klassen und Variablen kannst du im Wesentlichen so nennen, wie du möchtest, alles relevante läuft über Annotationen.

Nachzulesen wäre das in der offiziellen Doku zum jeweiligen Thema.

Die Beziehung des HTML zum Controller ist mir auch nicht klar. Gibt es da eine gute Quelle, wo ich das nachlesen kann?
Da besteht nur eine ziemlich lockere Beziehung.

Der Controller füllt ModelAttribute und gibt das template an - das wird dann mit den Modelattributen gerendert.
 
Nehmen wir mal diesen Code:

@GetMapping("/")
public String showForm(PersonForm personForm) {
return "form";
}

Er hat die Aufgabe, die "form.html" anzuzeigen. Erste Frage als WuWP(Wald und Wiesenrogrammierer): Wieso braucht er da ein Objekt PersonForm? Und was soll das überhaupt. Als WuWP habe ich gelernt, dass die Parameter auf einem Stack liegen und die Methoden diese vom Stack abrufen. Nun ist hier aber weder sichtbar ein Objekt initialisiert worden.

Die andere Methode


@PostMapping("/")
public String checkPersonInfo(@Valid PersonForm personForm, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "form";
}

return "redirect:/results";
}

ist für einen WuWP ebenso geheiimnisvoll. Wo sind die Daten, wenn sie validiert werden? Üblicherweise würde man sie aus der Webseiite in ein Objekt ziehen und dieses beauftragen, die Daten zu validieren( habe ich bei JSF gelesen). Hier aber nicht. Bis hierher spielt der wirkliche Inhalt der Daten überhaupt keine Rolle. Sie werden auf Gültigkeit geprüft, in diesem Fall Länge oder Wertebereich, ohne dass man sie sichtbar im Code hat.

Das ist spannend, und eine ganz schöne Umstellung, das so zu denken.

Es dauert eben von einem WuWP zu einem Meister der Spring-Ökologie zu werden.
 
erstmal, in Bezug auf recht high-leveliges Java, ignoriert solche Dinge:
Als WuWP habe ich gelernt, dass die Parameter auf einem Stack liegen und die Methoden diese vom Stack abrufen.

Erste Frage als WuWP(Wald und Wiesenrogrammierer): Wieso braucht er da ein Objekt PersonForm? Und was soll das überhaupt. [...] Nun ist hier aber weder sichtbar ein Objekt initialisiert worden.
Initialisiert wird das Objekt in diesem Fall von Spring, das passiert irgendwo im Hintergrund mit schwarzer Magie.
Das führt in diesem Fall dazu, dass ein PersonForm-Objekt in den Model-Attributen liegt, und damit zb im Thymeleaf-Template verfügbar ist.
Alternativ zum initialisieren durch Spring kannst du das auch selbst initialisieren, zB wenn du die Methode ein ModelAndView-Objekt zurückgeben lässt.

Wo sind die Daten, wenn sie validiert werden? Üblicherweise würde man sie aus der Webseiite in ein Objekt ziehen und dieses beauftragen, die Daten zu validieren( habe ich bei JSF gelesen). Hier aber nicht. Bis hierher spielt der wirkliche Inhalt der Daten überhaupt keine Rolle. Sie werden auf Gültigkeit geprüft, in diesem Fall Länge oder Wertebereich, ohne dass man sie sichtbar im Code hat.
Wieder ganz viel Spring-Magie :)

Der HTML-Request enthält die Daten, um das PersonForm-Objekt zu füllen, das passiert als erstes. Dann ist der Parameter mit @Valid annotiert - Spring validiert deshalb das Objekt mit der „normalen“ Bean Validation, zB anhand der Annotationen an den einzelnen Feldern des Objekts.
Das Resultat davon landet dann im BindingResult (dabei ist einer der wenigen Konventionen relevant: das BindingResult muss der Parameter hinter dem zu validierenden Objekt sein).
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben