Heim  >  Artikel  >  Duplizierung von RequestHeader im Java Spring Boot-Controller

Duplizierung von RequestHeader im Java Spring Boot-Controller

WBOY
WBOYnach vorne
2024-02-06 11:36:10522Durchsuche
Frageninhalt

Ich habe eine Reihe von Rest-Controllern, die in Java geschrieben sind. Die ursprüngliche Anforderung bestand darin, einige Header für einige Endpunkte hinzuzufügen. Wir haben uns jedoch entschieden, diese Header-Felder in fast allen übrigen Controllern hinzuzufügen. Das Projekt enthält mittlerweile über 100 ähnliche APIs:

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

}

Aus dem Code geht hervor, dass die Tupel „Benutzer“, „Guid“, „Aufrufer“ und „Sprache“ überall im Quellcode vorhanden sind, aber wie man den Code umgestaltet und an „einer Stelle“ ablegt oder versucht, ihn reicher zu machen, ist nicht klar. Ist das offensichtlich? Wartbar. Wenn wir beispielsweise einen fünften Parameter hinzufügen müssen, müssen wir 100 APIs verwenden.

Was ist der kanonische Weg, dies in Java Spring Boot zu tun?

Idealerweise hätte ich gerne so etwas:

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

    }

Irgendwelche Ideen? Controller-Vorschläge? irgendetwas anderes?


Richtige Antwort


Um das Problem der Codeduplizierung zu lösen und den Code in einer Spring-Boot-Anwendung besser wartbar zu machen, können Sie einen benutzerdefinierten Filter erstellen, um die öffentlichen Header zu extrahieren und zu verarbeiten, bevor sie den Controller erreichen. Darüber hinaus können Sie Header-Parameter auch in Objekte kapseln, um die Lesbarkeit und Wartbarkeit des Codes zu verbessern.

Zusammengefasst: Zentralisieren Sie die Header-Verarbeitung, indem Sie requestheaders dto、实现 customheaderfilter 并将其注册到 filterregistrationbean erstellen, um gemeinsame Header in Spring-Boot-Controllern einheitlich anzuwenden.

Hier sind die empfohlenen Methoden:

  1. Header-dto (Datenübertragungsobjekt) erstellen:

    Definieren Sie eine Klasse, die die öffentlichen Header-Parameter darstellt. Diese Klasse enthält den aus dem Header extrahierten Wert.

    public class requestheaders {
        private string user;
        private string guid;
        private string caller;
        private string language;
    
        // getters and setters
    }
    
  2. Filter erstellen:

    Implementieren Sie Filter, um eingehende Anfragen abzufangen und öffentliche Header zu extrahieren, und speichern Sie sie dann in den Anfrageeigenschaften.

    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. Verwenden Sie filterregistrationbean, um den Filter zu registrieren:

    Verwenden Sie filterregistrationbean in der Hauptanwendungsklasse, um einen benutzerdefinierten Filter zu registrieren.

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

    Passen Sie die addurlpatterns-Methode an die URL an, auf die Sie den Filter anwenden möchten.

  4. Ändern Sie den Controller, um dto zu verwenden:

    Ändern Sie Ihren Controller so, dass er requestheaders dto anstelle separater Header-Parameter verwendet.

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

Wenn Sie jetzt neue Header-Parameter hinzufügen oder Änderungen vornehmen müssen, aktualisieren Sie einfach die requestheaders Klassen- und Filterlogik. Dieser Ansatz zentralisiert die Header-Verarbeitung und verbessert die Wartbarkeit.

Das obige ist der detaillierte Inhalt vonDuplizierung von RequestHeader im Java Spring Boot-Controller. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen