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

Duplication de RequestHeader dans le contrôleur Java Spring Boot

WBOY
Libérer: 2024-02-06 11:36:10
avant
627 Les gens l'ont consulté
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)));

}
Copier après la connexion

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)));

    }
Copier après la connexion

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
    }
    
    Copier après la connexion
  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);
        }
    }
    
    Copier après la connexion
  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;
        }
    }
    
    Copier après la connexion

    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));
    }
    
    Copier après la connexion

    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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal