Maison  >  Article  >  Duplication de RequestHeader dans le contrôleur Java Spring Boot

Duplication de RequestHeader dans le contrôleur Java Spring Boot

WBOY
WBOYavant
2024-02-06 11:36:10569parcourir
Contenu de la question

J'ai un ensemble de contrôleurs de repos écrits en Java. L'exigence initiale était d'ajouter des en-têtes pour certains points de terminaison, mais nous avons décidé d'ajouter ces champs d'en-tête dans presque tous les contrôleurs de repos. Le projet contient désormais plus de 100 API similaires :

@getmapping("/products/{comp}")
public responseentity<list<product>> getallproducts(
        @requestheader(user_hdr) string user,
        @requestheader(guid_hdr) string guid,
        @requestheader(value = caller_hdr, required = false) string caller,
        @requestheader(value = lang_hdr, required = false) string language,
        @pathvariable @notnull integer comp
) {

    return responseentity.ok(service.get(comp, productutils.processheaders(user,guid,caller,language)));

}

@getmapping("/products")
public responseentity<list<product>> getallproducts(
        @requestheader(user_hdr) string user,
        @requestheader(guid_hdr) string guid,
        @requestheader(value = caller_hdr, required = false) string caller,
        @requestheader(value = lang_hdr, required = false) string language
) {

   return responseentity.ok(service.getallrecords(productutils.processheaders(user,guid,caller,language)));

}

Il ressort clairement du code que les tuples utilisateur, guid, appelant et langue sont partout dans le code source, mais comment refactoriser et mettre le code à "un seul endroit" ou essayer de le rendre plus riche, ce n'est pas évident ? Maintenable. Par exemple, si nous devons ajouter un 5ème paramètre, nous devons utiliser 100 API.

Quelle est la manière canonique de faire cela dans Java Spring Boot ?

Idéalement, j'aimerais quelque chose comme ceci :

@GetMapping("/products/{comp}")
    public ResponseEntity<List<Product>> getAllProducts(
            "common handling"
            @PathVariable @NotNull Integer comp
    ) {

        return ResponseEntity.ok(service.get(comp, ProductUtils.processHeaders(user,guid,caller,language)));

    }

    @GetMapping("/products")
    public ResponseEntity<List<Product>> getAllProducts(
            "common handling"
    ) {

       return ResponseEntity.ok(service.getAllRecords(ProductUtils.processHeaders(user,guid,caller,language)));

    }

Des idées ? Des suggestions de contrôleurs ? rien d'autre?


Bonne réponse


Pour résoudre le problème de duplication de code et rendre le code plus maintenable dans une application Spring Boot, vous pouvez créer un filtre personnalisé pour extraire et traiter les en-têtes publics avant qu'ils n'atteignent le contrôleur. De plus, vous pouvez également encapsuler les paramètres d'en-tête dans des objets pour améliorer la lisibilité et la maintenabilité du code.

En résumé, centralisez le traitement des en-têtes en créant requestheaders dto、实现 customheaderfilter 并将其注册到 filterregistrationbean pour appliquer uniformément les en-têtes communs dans les contrôleurs Spring Boot.

Voici les méthodes suggérées :

  1. Créer un en-tête dto (objet de transfert de données) :

    Définissez une classe qui représente les paramètres de l'en-tête public. Cette classe contiendra la valeur extraite de l’en-tête.

    public class requestheaders {
        private string user;
        private string guid;
        private string caller;
        private string language;
    
        // getters and setters
    }
    
  2. Créer un filtre :

    Implémentez des filtres pour intercepter les requêtes entrantes et extraire les en-têtes publics, puis stockez-les dans les propriétés de la requête.

    import org.springframework.web.filter.onceperrequestfilter;
    import javax.servlet.filterchain;
    import javax.servlet.servletexception;
    import javax.servlet.http.httpservletrequest;
    import javax.servlet.http.httpservletresponse;
    import java.io.ioexception;
    
    public class customheaderfilter extends onceperrequestfilter {
        @override
        protected void dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain filterchain)
                throws servletexception, ioexception {
    
            requestheaders headers = new requestheaders();
            headers.setuser(request.getheader("user"));
            headers.setguid(request.getheader("guid"));
            headers.setcaller(request.getheader("caller"));
            headers.setlanguage(request.getheader("language"));
    
            request.setattribute("requestheaders", headers);
    
            filterchain.dofilter(request, response);
        }
    }
    
  3. Utilisez filterregistrationbean pour enregistrer le filtre :

    Utilisez filterregistrationbean dans la classe d'application principale pour enregistrer un filtre personnalisé.

    import org.springframework.boot.web.servlet.filterregistrationbean;
    import org.springframework.context.annotation.bean;
    import org.springframework.context.annotation.configuration;
    
    @configuration
    public class webconfig {
        @bean
        public filterregistrationbean<customheaderfilter> customheaderfilter() {
            filterregistrationbean<customheaderfilter> registrationbean = new filterregistrationbean<>();
            registrationbean.setfilter(new customheaderfilter());
            registrationbean.addurlpatterns("/api/*"); // adjust the url pattern as needed
            return registrationbean;
        }
    }
    

    Personnalisez la méthode addurlpatterns en fonction de l'URL à laquelle vous souhaitez appliquer le filtre.

  4. Modifier le contrôleur pour utiliser dto :

    Modifiez votre contrôleur pour utiliser requestheaders dto au lieu de paramètres d'en-tête séparés.

    @GetMapping("/products/{comp}")
    public ResponseEntity<List<Product>> getAllProducts(@PathVariable @NotNull Integer comp,
                                                        @ModelAttribute("requestHeaders") RequestHeaders headers) {
        return ResponseEntity.ok(service.get(comp, headers));
    }
    
    @GetMapping("/products")
    public ResponseEntity<List<Product>> getAllProducts(@ModelAttribute("requestHeaders") RequestHeaders headers) {
        return ResponseEntity.ok(service.getAllRecords(headers));
    }
    

Maintenant, si vous devez ajouter de nouveaux paramètres d'en-tête ou apporter des modifications, il vous suffit de mettre à jour la logique de classe et de filtre requestheaders. Cette approche centralise le traitement des en-têtes et améliore la maintenabilité.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer