[Spring Boot] Annotazioni: @Controller Vs @RestController

di il
13 risposte

[Spring Boot] Annotazioni: @Controller Vs @RestController

Buonasera,

Ho eseguito questa procedura non usuale per mostrare le view all'utente(test sul localhost), tutto funziona ma ChatGpt mi assicura che ho sbagliato perché avrei, e probabilmente è così, fuso le annotazioni in oggetto: @Controller e @RestController.

ChatGpt argomenta che @RestController è da usare con formato JSON mentre @Controller con web page e template.

Procedura funzionante ma errata:

"../static/login.html" (Se uso folder: template non funziona)

 
@Controller

public class RestControl {

@GetMapping("/login")

public ModelAndView index() { 

 ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("login.html"); 

 return modelAndView

}

}

 @PostMapping("/login")

public String login(Model model, @ModelAttribute("user_login") User user){

 if (userService.checkCredentials(user)) {

 return "Autorizzato";

 }

 else {

 return "Non autorizzato";

 }

}

Questa è la login.html:

<form th:action="@{/login}" th:object="${user_login}" method="post">

     <br>

  <label for="username">Username:</label><br>

  <input type="text" id="username" name="username" th:field="*{username}"><br>

<hr>

  <label for="password">Password:</label><br>

  <input type="password" name="password" th:field="*{password}"><hr><br>

  <button type="onsubmit" value="Submit">Accedi</button><br>

  </form>

 

Funziona, si, ma io voglio ridirigere l'utente ad una pagina web, non visualizzare semplice testo, ed il metodo PostMapping non consente questo.

A prescindere poi che questo approccio stando a quanto detto da ChatGpt non è formalmente corretto.

Quindi tento di usare @Controller come letto in 1000 pagine WEB,

Creo una classa CController e la annoto con @Controller, volendo uso anche per essa l'annotazione RequestMapping("/") ed inserisco semplicemente:

@GetMapping("/index")

public String login(){ 

    return "login"

}

Mi da errore:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sat Jul 26 21:21:51 CEST 2025

There was an unexpected error (type=Internal Server Error, status=500).

Non riesco a capire come usare l'annotazione @Controller.

13 Risposte

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Comunque se metto correttamente "login.html" invece che con "login" nel metodo GET ed inserisco la pagina in folder-static, funziona, in template no. 

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Ciao, no così non va bene stai reinventando la ruota
    il login va gestito tramite security filter chain
    così come te lo sta facendo fare chat gpt diventa un casino

    studia questo articolo: https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/form.html

    ti darà basi più solide rispetto a chat gpt

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    26/07/2025 - dev-vico ha scritto:

    Comunque se metto correttamente "login.html" invece che con "login" nel metodo GET ed inserisco la pagina in folder-static, funziona, in template no. 

    assicurati di aver inserito nel pom le seguenti dipendenze:

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
                <version>3.4.2</version>
    </dependency>

    <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-springsecurity6</artifactId>
    </dependency>

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Ora lo studio grazie, ma devo capire queste basi.
    Non riesco a venire a capo del perché il @Controller non funziona a dovere.

    Per il momento non inserisco ancora spring-security.

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Al posto di @GetMapping prova a mettere @RequestMapping

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Se è in template non lo vede anche con RequestMapping. Solo se è in static visualizza pagina.

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    26/07/2025 - dev-vico ha scritto:

    Per il momento non inserisco ancora spring-security.

    ah ok, studialo con calma (è uno degli argomenti più complicati)

    io ci ho messo 3 mesi a capire come funzionava

    c'è tanta confusione in Italia su spring security perché le guide in italiano si basano su spring 2.0 (siamo uno stato retrogrado), consulta le guide e gli articoli relativi a spring 3.x in lingua inglese, sono decisamente migliori delle risorse in italiano

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    26/07/2025 - dev-vico ha scritto:

    Se è in template non lo vede anche con RequestMapping. Solo se è in static visualizza pagina.

    aspetta ti giro un controller in cui avevo utilizzato thymeleaf

    package luca.engineer.controllers;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.annotation.AuthenticationPrincipal;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RequestPart;
    
    import jakarta.servlet.http.HttpSession;
    
    import java.nio.charset.StandardCharsets;
    import java.util.ArrayList;
    import java.util.Base64;
    
    import luca.engineer.models.Attività;
    import luca.engineer.models.Lezione;
    import luca.engineer.models.User;
    import luca.engineer.repositories.AttivitàRepository;
    import luca.engineer.repositories.LezioneRepository;
    import luca.engineer.repositories.UserRepository;
    
    @Controller
    public class PagesController {
    
    	@Autowired
    	UserRepository userRepository;
    	
    	@Autowired
    	LezioneRepository lezioneRepository;
    	
    	@Autowired
    	AttivitàRepository attivitàRepository;
    	
    	@GetMapping("/")
    	public String indexPage() {
    		return "login"; //redirect alla login
    	}
    	
    	@GetMapping("/login")
    	public String loginPage() {
    		return "login";
    	}
    	
    	@GetMapping("/register")
    	public String registerPage() {
    		return "register";
    	}
    	
    	@GetMapping("/register/success")
    	public String registerSuccessPage() {
    		return "register-success";
    	}
    	
    	@GetMapping("/app/")
    	public String dashboardPage(HttpSession session, Model model, @AuthenticationPrincipal UserDetails currentUser) throws Exception {
    		User user = (User) userRepository.findByEmail(currentUser.getUsername()).orElseThrow(() -> new Exception());
            session.setAttribute("idUser", user.getIdUser());
    		return "dashboard";
    	}
    	
    	/*************************** BEGIN LEZIONI ************************************************/
    	
    	@GetMapping("/app/lezioni")
    	public String lezioniPage(HttpSession session, Model model) throws Exception {
    		Long idUser = new Long((long) session.getAttribute("idUser"));
    		User user = userRepository.findById(idUser).orElseThrow(() -> new Exception());
    		model.addAttribute("lezioni", user.getLezioni());
    		return "lezioni";
    	}
    	
    	@GetMapping("/app/lezioni/{idLezione}")
    	public String lezioneOpenPage(@PathVariable Long idLezione, Model model) throws Exception {
    		Lezione lezione = lezioneRepository.findById(idLezione).orElseThrow(() -> new Exception());
    		model.addAttribute("titolo", lezione.getTitolo());
    		model.addAttribute("descrizione", lezione.getDescrizione());
    		model.addAttribute("url", lezione.getUrl());
    		model.addAttribute("id", lezione.getIdLesson());
    		return "lezione-open";
    	}
    	
    	@GetMapping("/app/lezioni/aggiungi")
    	public String lezioniAggiungiPage(HttpSession session, Model model) {
    		Long idUser = new Long((long) session.getAttribute("idUser"));
    		model.addAttribute("idUser", idUser);
    		return "lezioni-aggiungi";
    	}
    	
    	@GetMapping("app/lezioni/aggiungi/success")
    	public String lezioneAggiungiSuccessPage(Model model) {
    		return "lezione-aggiungi-success";
    	}
    	
    	@GetMapping("app/lezione/rimuovi/success")
    	public String lezioneRimuoviSuccessPage(Model model) {
    		return "lezione-rimuovi-success";
    	}
    	
    	/*************************** END LEZIONI ************************************************/
    	
    	/*************************** BEGIN ATTIVITA' ************************************************/
    	
    	@GetMapping("/app/attivita")
    	public String attivitàPage(HttpSession session, Model model) throws Exception {
    		Long idUser = new Long((long) session.getAttribute("idUser"));
    		User user = userRepository.findById(idUser).orElseThrow(() -> new Exception());
    		model.addAttribute("attività", user.getAttività());
    		return "attività";
    	}
    	
    	@GetMapping("/app/attivita/{idAttività}")
    	public String attivitàOpenPage(@PathVariable Long idAttività, Model model) throws Exception {
    		Attività attività = attivitàRepository.findById(idAttività).orElseThrow(() -> new Exception());
    		model.addAttribute("esercizio", attività.getEsercizio());
    		model.addAttribute("serie", attività.getSerie());
    		model.addAttribute("ripetizioni", attività.getRipetizioni());
    		model.addAttribute("idAttivita", idAttività);
    		return "attività-open";
    	}
    	
    	@GetMapping("/app/attivita/aggiungi")
    	public String attivitàAggiungiPage(HttpSession session, Model model) {
    		Long idUser = new Long((long) session.getAttribute("idUser"));
    		model.addAttribute("idUser", idUser);
    		return "attività-aggiungi";
    	}
    	
    	@GetMapping("app/attivita/aggiungi/success")
    	public String attivitàAggiungiSuccessPage(Model model) {
    		return "attività-aggiungi-success";
    	}
    	
    	@GetMapping("app/attivita/rimuovi/success")
    	public String attivitàRimuoviSuccessPage(Model model) {
    		return "attività-rimuovi-success";
    	}
    	
    	@GetMapping("app/attivita/modifica/{id}")
    	public String attivitàModifica(@PathVariable Long id, Model model) throws Exception {
    		Attività tmp = attivitàRepository.findById(id).orElseThrow(() -> new Exception());
    		model.addAttribute("idAttività", id);
    		model.addAttribute("esercizio", tmp.getEsercizio());
    		model.addAttribute("serie", tmp.getSerie());
    		model.addAttribute("ripetizioni", tmp.getRipetizioni());
    		return "attività-modifica";
    	}
    	
    	@GetMapping("app/attivita/modifica/success")
    	public String attivitàModificaSuccess() throws Exception {
    		return "attività-modifica-success";
    	}
    	
    	/*************************** END ATTIVITA' ************************************************/
    	
    	@GetMapping("/app/profilo")
    	public String profiloPage(HttpSession session, Model model) throws Exception {
    		Long idUser = new Long((Long)session.getAttribute("idUser"));
    		User user = userRepository.findById(idUser).orElseThrow(() -> new Exception());
    		model.addAttribute("nome", user.getNome());
    		model.addAttribute("cognome", user.getCognome());
    		model.addAttribute("email", user.getEmail());
    		model.addAttribute("dataNascita", user.getDataNascita());
    		return "profilo";
    	}
    	
    }
  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Non so cosa accade, uso STS, tu cosa usavi?
    Avevo anche io usato già questi metodi, basilari, forse mi conviene prendere un vecchio progetto funzionante e cercare di comparare.

    Non so se funzioneranno anche quelli oppure è l'aggiornamento STS...


    Stranissime alcune cose:

    Se io inserisco "index.html" all'interno di GET vede la pagina (in static) se inserisco "index" non la vede.

    Mentre vedo che tu usi "index".

    Secondo me c'è qualche configurazione di thymeleaf che non va bene. Dovrebbe vedere la pagina nel template.

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    26/07/2025 - dev-vico ha scritto:

    Non so cosa accade, uso STS, tu cosa usavi?
    Avevo anche io usato già questi metodi, basilari, forse mi conviene prendere un vecchio progetto funzionante e cercare di comparare.

    Non so se funzioneranno anche quelli oppure è l'aggiornamento STS...


    Stranissime alcune cose:

    Se io inserisco "index.html" all'interno di GET vede la pagina (in static) se inserisco "index" non la vede.

    Mentre vedo che tu usi "index".

    Secondo me c'è qualche configurazione di thymeleaf che non va bene. Dovrebbe vedere la pagina nel template.

    https://github.com/bezkoder/spring-boot-thymeleaf-example

    io i progetti spring boot li inizializzavo con intellij

    per rispondere al tuo quesito iniziale @Controller si usa per mostrare le viste in html mentre @RestController si usa per dare risposte (di solito in json) alle chiamate http

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Molto strano, in teoria dovrebbe vedere le pagine mettendo solo il nome della pagina nel return

    che versione di spring stai usando?

    stai seguendo questa struttura?

    @GetMapping("miaUrl")
    public String miaPagina() {
    return "miaPagina";
    }
    
    cartella static:
    static/miaPagina.html
  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Ciao si era quella la configurazione usata.

    Per eliminare dubbi di errate configurazioni a seguito dell' aggiunta di Spring Security al mio progetto l'ho ricreato come copia copiandone i files.

    Comunque ho capito i vari problemi che c'erano e li ho sistemati anche grazie a Chat Gpt, non mi aspettavo ti potesse aiutare a tal punto. Sembra una persona.

    I file HTML vanno in "template" in questo caso e non ci vuole estensione ".html" nel GET, che probabilmente invece accetta in "static".

    Uno degli errori più notevoli era la NON creazione del modello(model) impiegato nel metodo GET del Login per il binding del metodo POST che punta alla stessa pagina.

    Ora funziona bene e potrò studiare Spring Security.

  • Re: [Spring Boot] Annotazioni: @Controller Vs @RestController

    Si hai pienamente ragione, ho verificato i template erano nella cartella templates, errore mio scusami

    nella cartella static invece avevo messo i file js ed le immagini

Devi accedere o registrarti per scrivere nel forum
13 risposte