Java >> Java Tutorial >  >> Tag >> Spring

Aus den Gräben springen:Erstellen eines benutzerdefinierten HandlerMethodArgumentResolver

Vor einigen Wochen haben wir gelernt, den Wert eines einzelnen Anforderungsparameters mithilfe von Spring-Typkonvertern in ein Objekt umzuwandeln, das als Methodenparameter an unsere Controller-Methode übergeben wird.

Die Verwendung von Typkonvertern ist eine gute Wahl, wenn wir "einfache" Wertobjekte erstellen und diese Objekte in unsere Controller-Methoden einfügen möchten.

Manchmal möchten wir jedoch Objekte einfügen, die diese Anforderungen erfüllen:

  • Das eingefügte Objekt hat mehr als ein Feld und die Werte dieser Felder müssen aus verschiedenen Quellen gelesen werden.
  • Das eingefügte Objekt ist kein Formularobjekt.
  • Das eingefügte Objekt wird nicht aus dem Anforderungstext gelesen.

Wenn wir diese Anforderungen erfüllen wollen, müssen wir einen benutzerdefinierten HandlerMethodArgumentResolver erstellen , und dieser Blogbeitrag beschreibt, wie wir das tun können.

Beginnen wir mit der Erstellung eines benutzerdefinierten HandlerMethodArgumentResolver die FooBar erstellen kann Objekte.

Erstellen eines benutzerdefinierten HandlerMethodArgumentResolver

Die FooBar class ist eine einfache Klasse mit zwei final Felder:Leiste und foo . Sein Quellcode sieht wie folgt aus:

public class FooBar {

    private final String bar;
    private final String foo;

    FooBar(String bar, String foo) {
        this.bar = bar;
        this.foo = foo;
    }

    public String getBar() {
        return bar;
    }

    public String getFoo() {
        return foo;
    }
}

Wir können einen benutzerdefinierten HandlerMethodArgumentResolver erstellen Klasse, die FooBar erstellen kann Objekte, indem Sie diesen Schritten folgen:

  1. Implementieren Sie den HandlerMethodArgumentResolver Schnittstelle.
  2. Implementieren Sie den supportsParameter(MethodParameter methodParameter) Methode. Diese Methode muss true zurückgeben wenn der Typ des Methodenparameters FooBar ist und falsch ansonsten.
  3. Implementieren Sie das resolveArgument() Methode, indem Sie die folgenden Schritte ausführen:
    1. Erhalten Sie den Wert des Anforderungsparameters "bar".
    2. Erhalten Sie den Wert des Anforderungsparameters „foo“.
    3. Wenn der Anforderungsparameter „bar“ in der Anforderung nicht gefunden wird, verwenden Sie den Standardwert.
    4. Wenn der Anforderungsparameter „foo“ in der Anforderung nicht gefunden wird, verwenden Sie den Standardwert.
    5. Erstellen Sie eine neue FooBar Objekt und gibt das erstellte Objekt zurück.

Der Quellcode des FooBarHandlerMethodArgumentResolver Klasse sieht wie folgt aus:

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public final class FooBarHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(FooBar.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {
        String bar = nativeWebRequest.getParameter("bar");
        String foo = nativeWebRequest.getParameter("foo");

        if (isNotSet(bar)) {
            bar = "defaultBar";
        }

        if (isNotSet(foo)) {
            foo = "defaultFoo";
        }

        return new FooBar(bar, foo);
    }

    private boolean isNotSet(String value) {
        return value == null;
    }
}

Bevor wir unseren neuen HandlerMethodArgumentResolver verwenden können Klasse müssen wir den Anwendungskontext unserer Webanwendung konfigurieren.

Konfigurieren des Anwendungskontextes unserer Webanwendung

Bevor wir FooBar injizieren können Objekte in unsere Controller-Methoden, müssen wir den FooBarHandlerMethodArgumentResolver registrieren als Methodenargumentauflöser. In diesem Abschnitt wird beschrieben, wie wir den Anwendungskontext unserer Webanwendung konfigurieren können, die entweder Spring oder Spring Boot verwendet.

Konfigurieren einer Spring-Webanwendung

Wir können das FoobarHandlerMethodArgument registrieren -Klasse als Methodenargumentlöser, indem Sie die folgenden Änderungen an der Konfigurationsklasse vornehmen, die die Webschicht unserer Spring-Webanwendung konfiguriert:

  1. Erweitern Sie den WebMvcConfigurerAdapter Klasse.
  2. Überschreiben Sie die addArgumentResolvers(List argumentResolvers) -Methode des WebMvcConfigurerAdapter Klasse.
  3. Registrieren Sie einen benutzerdefinierten Methodenargumentauflöser, indem Sie einen neuen FooBarHandlerMethodArgumentResolver erstellen Objekt und Hinzufügen des erstellenden Objekts zur Liste als Methodenparameter angegeben.

Der Quellcode der WebMvcContext-Klasse sieht wie folgt aus:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;
 
@Configuration
@EnableWebMvc
class WebMvcContext extends WebMvcConfigurerAdapter {
 
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new FooBarHandlerMethodArgumentResolver());
    }
}

Lassen Sie uns weitermachen und herausfinden, wie wir den Anwendungskontext unserer Spring Boot-Webanwendung konfigurieren können.

Konfigurieren einer Spring Boot-Webanwendung

Wir können das FoobarHandlerMethodArgument registrieren -Klasse als Methodenargumentauflöser, indem Sie die folgenden Änderungen an der "Anwendungsklasse" unserer Spring Boot-Webanwendung vornehmen:

  1. Erweitern Sie den WebMvcConfigurerAdapter Klasse.
  2. Überschreiben Sie die addArgumentResolvers(List argumentResolvers) -Methode des WebMvcConfigurerAdapter Klasse.
  3. Registrieren Sie einen benutzerdefinierten Methodenargumentauflöser, indem Sie einen neuen FooBarHandlerMethodArgumentResolver erstellen Objekt und Hinzufügen des erstellenden Objekts zur Liste als Methodenparameter angegeben.

Der Quellcode der SpringBootExampleApplication Klasse sieht wie folgt aus:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SpringBootExampleApplication extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new FooBarHandlerMethodArgumentResolver());
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringBootExampleApplication.class, args);
    }
}

Wir sind fertig. Lassen Sie uns herausfinden, wie wir unseren neuen Methoden-Argument-Resolver verwenden können.

Verwenden des benutzerdefinierten HandlerMethodArgumentResolver

Nachdem wir den Anwendungskontext unserer Webanwendung konfiguriert haben, können wir einfach eine neue FooBar hinzufügen Methodenparameter in unsere Controller-Methode. Der Quellcode unserer Controller-Klasse sieht wie folgt aus:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
final class FooBarController {

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public void processFooBar(FooBar fooBar) {
        //Do stuff
    }
}

Wir können jetzt die Informationen der FooBar einstellen Objekt, indem Sie die Werte der folgenden Anforderungsparameter festlegen:

  • Der Wert des Anforderungsparameters 'bar' wird als Wert des bar gesetzt Feld.
  • Der Wert des Anforderungsparameters 'foo' wird als der Wert von foo gesetzt Feld.

Die folgenden Beispiele zeigen, wie wir neue FooBar erstellen können Objekt, legen Sie die Werte seiner Leiste fest und foo Felder und füge es in unsere Controller-Methode ein.

Beispiel 1:

Wir müssen eine FooBar erstellen Objekt, das die folgenden Anforderungen erfüllt:

  • Der Wert des Balkens Feld ist 'bar'.
  • Der Wert von foo Feld ist 'foo'.

Wir können dieses Objekt erstellen, indem wir ein GET senden Anfrage an folgende URL:'/test?bar=bar&foo=foo'.

Beispiel 2:

Wenn wir eine FooBar erstellen wollen und legen Sie die Standardwerte in seiner Leiste fest und foo Felder müssen wir ein GET senden Anfrage an folgende URL:'/test'.

Fahren wir fort und fassen zusammen, was wir aus diesem Blogbeitrag gelernt haben.

Zusammenfassung

Dieser Blogbeitrag hat uns drei Dinge gelehrt:

  • Wenn wir "komplexe" Objekte in unsere Controller-Methoden einfügen wollen und diese Objekte keine Formularobjekte sind oder aus dem Anforderungstext gelesen werden, sollten wir einen benutzerdefinierten Methodenargumentlöser erstellen.
  • Wir können einen neuen Methodenargumentauflöser erstellen, indem wir den HandlerMethodArgumentResolver implementieren Schnittstelle.
  • Bevor wir einen benutzerdefinierten HandlerMethodArgumentResolver verwenden können , müssen wir es als Methodenargumentlöser registrieren.

P.S. Sie können die Beispielanwendung dieses Blogbeitrags von Github herunterladen.


Java-Tag