Gestione dei dati dei moduli con codifica URL in Spring REST

REST Top

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO

1. Panoramica

Per un utente finale, il processo di invio del modulo è comodo e, in una certa misura, equivalente alla semplice immissione dei dati e al clic su un pulsante di invio. Tuttavia, da un punto di vista ingegneristico, è necessario un meccanismo di codifica per inviare e ricevere in modo affidabile questi dati dal lato client al lato server per l'elaborazione back-end.

Per lo scopo di questo tutorial, ci concentreremo sulla creazione di un modulo che invia i suoi dati come tipo di contenuto application / x-www-form-urlencoded in un'applicazione web Spring.

2. Codifica dei dati dei moduli

Il metodo HTTP più comunemente utilizzato per l'invio di moduli è POST. Tuttavia, per l'invio di moduli idempotenti, possiamo anche utilizzare il metodo HTTP GET. E il modo per specificare il metodo è tramite l'attributo del metodo del modulo.

Per i moduli che utilizzano il metodo GET, i dati dell'intero modulo vengono inviati come parte della stringa di query. Tuttavia, se stiamo utilizzando il metodo POST, i suoi dati vengono inviati come parte del corpo della richiesta HTTP.

Inoltre, in quest'ultimo caso, possiamo anche specificare la codifica dei dati con l' attributo enctype del form , che può assumere due valori, ovvero application / x-www-form-urlencoded e multipart / form-data .

2.1. Tipo di supporto application / x-www-form-urlencoded

I moduli HTML hanno un valore predefinito di application / x-www-form-urlencoded per l' attributo enctype poiché questo si occupa dei casi d'uso di base in cui i dati sono interamente di testo. Tuttavia, se il nostro caso d'uso prevede il supporto dei dati del file, dovremo sovrascriverlo con un valore di multipart / form-data .

In sostanza, invia i dati del modulo come coppie chiave-valore separate da un carattere e commerciale (&). Inoltre, la chiave e il valore rispettivi sono separati dal segno di uguale (=). Inoltre, tutti i caratteri riservati e non alfanumerici vengono codificati utilizzando la codifica percentuale.

3. Invio del modulo nel browser

Ora che abbiamo coperto le nostre nozioni di base, andiamo avanti e vediamo come possiamo gestire i dati dei moduli con codifica URL per un semplice caso d'uso di invio di feedback in un'app Web Spring.

3.1. Modello di dominio

Per il nostro modulo di feedback, dobbiamo acquisire l'identificativo e-mail del mittente insieme al commento. Quindi, creiamo il nostro modello di dominio in una classe Feedback :

public class Feedback { private String emailId; private String comment; }

3.2. Crea modulo

Per utilizzare un semplice modello HTML per creare il nostro modulo web dinamico, dovremo configurare Thymeleaf nel nostro progetto. Dopodiché, siamo pronti per aggiungere un endpoint / feedback GET che servirà la visualizzazione di feedback per il modulo :

@GetMapping(path = "/feedback") public String getFeedbackForm(Model model) { Feedback feedback = new Feedback(); model.addAttribute("feedback", feedback); return "feedback"; }

Tieni presente che stiamo utilizzando il feedback come attributo del modello per acquisire l'input dell'utente. Successivamente, creiamo la visualizzazione feedback nel modello feedback.html :

Ovviamente, non è necessario specificare esplicitamente l' attributo enctype poiché sceglierà il valore predefinito di application / x-www-form-urlencoded .

3.3. PRG Flow

Poiché accettiamo l'input dell'utente tramite il modulo di feedback del browser, dobbiamo implementare il flusso di lavoro di invio POST / REDIRECT / GET (PRG) per evitare invii duplicati .

Innanzitutto, implementiamo l'endpoint / web / feedback POST che fungerà da gestore dell'azione per il modulo di feedback:

@PostMapping( path = "/web/feedback", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) public String handleBrowserSubmissions(Feedback feedback) throws Exception { // Save feedback data return "redirect:/feedback/success"; }

Successivamente, possiamo implementare l'endpoint di reindirizzamento / feedback / successo che serve una richiesta GET:

@GetMapping("/feedback/success") public ResponseEntity getSuccess() { return new ResponseEntity("Thank you for submitting feedback.", HttpStatus.OK); }

Per convalidare la funzionalità del flusso di lavoro di invio di moduli in un browser, visitiamo localhost: 8080 / feedback :

Infine, possiamo anche controllare che i dati del modulo vengano inviati nel modulo con codifica URL:

emailId=abc%40example.com&comment=Sample+Feedback

4. Richieste senza browser

A volte, potremmo non avere un client HTTP basato su browser. Invece, il nostro client potrebbe essere un'utilità come cURL o Postman. In tal caso, non abbiamo bisogno del modulo web HTML. Invece, possiamo implementare un endpoint / feedback che serve la richiesta POST:

@PostMapping( path = "/feedback", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) public ResponseEntity handleNonBrowserSubmissions(@RequestBody Feedback feedback) throws Exception { // Save feedback data return new ResponseEntity("Thank you for submitting feedback", HttpStatus.OK); }

In assenza del modulo HTML nel nostro flusso di dati, non abbiamo necessariamente bisogno di implementare il pattern PRG. Tuttavia, dobbiamo specificare che la risorsa accetta il tipo di supporto APPLICATION_FORM_URLENCODED_VALUE .

Infine, possiamo testarlo con una richiesta cURL:

curl -X POST \ //localhost:8080/feedback \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'emailId=abc%40example.com&comment=Sample%20Feedback'

4.1. Nozioni di base su FormHttpMessageConverter

Una richiesta HTTP che invia dati application / x-www-form-urlencoded deve specificarlo nell'intestazione Content-Type . Internamente, Spring usa la classe FormHttpMessageConverter per leggere questi dati e associarli al parametro del metodo.

In cases where our method parameter is of a type MultiValueMap, we can use either the @RequestParam or @RequestBody annotation to bind it appropriately with the body of the HTTP request. That's because the Servlet API combines the query parameters and form data into a single map called parameters, and that includes automatic parsing of the request body:

@PostMapping( path = "/feedback", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) public ResponseEntity handleNonBrowserSubmissions( @RequestParam MultiValueMap paramMap) throws Exception { // Save feedback data return new ResponseEntity("Thank you for submitting feedback", HttpStatus.OK); }

However, for a method parameter of type other than MultiValueMap, such as our Feedback domain object, we must use only the @RequestBody annotation.

5. Conclusion

In questo tutorial, abbiamo brevemente imparato la codifica dei dati dei moduli nei moduli web. Abbiamo anche esplorato come gestire i dati con codifica URL per le richieste HTTP del browser e non del browser implementando un modulo di feedback in un'app Web Spring Boot.

Come sempre, il codice sorgente completo del tutorial è disponibile su GitHub.

REST fondo

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO