Domanda

Questo è l'esempio del codice da Spring 3.1 Blog della sorgente di primavera: da XML a @Configuration Sto cercando di implementare nella mia applicazione (che è stato fatto in primavera 2.0 non da me, quindi è un sacco di apprendimento).

@FeatureConfiguration
class MvcFeatures {

    @Feature
    public MvcAnnotationDriven annotationDriven(ConversionService conversionService) {
        return new MvcAnnotationDriven().conversionService(conversionService)
            .argumentResolvers(new CustomArgumentResolver());
    }

    // ...

}

Tuttavia, non riesco a capire il punto di .ArgumentResolvers (nuovo CustomArgumentResolver ()) E il loro CustomArgumentResolver sembra qui sotto. Qual è il punto?

public class CustomArgumentResolver implements WebArgumentResolver {

    @Override
    public Object resolveArgument(MethodParameter param, NativeWebRequest request) throws Exception {
        RequestAttribute attr = param.getParameterAnnotation(RequestAttribute.class);
        if (attr != null) {
            return request.getAttribute(attr.value(), WebRequest.SCOPE_REQUEST);
        } else {
            return WebArgumentResolver.UNRESOLVED;
        }
    }
}
È stato utile?

Soluzione

Per aggiungere alla risposta di @Garyf e per chiarire alcuni punti, Spring 2.5 ha introdotto controller annotati, che hanno sostituito i vecchi controller in stile interfaccia di Spring 2.0. Questi nuovi controller hanno metodi senza parametri fissi: il metodo dichiara i parametri di cui ha bisogno per fare il suo lavoro e niente di più.

Ad esempio, diciamo che un metodo del controller aveva bisogno di una cosa per svolgere il proprio lavoro: un parametro di richiesta che contiene l'ID di un oggetto dal database. In primavera 2.0, dovresti implementare qualcosa di simile AbstractController.handleRequestInternal(), per esempio

protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
   String id = request.getParameter("id");
   MyThing obj = getObjById(id);
   //... do stuff and return ModelAndView
}

La primavera 2.5 ha reso più semplice:

@RequestMapping
public ModelAndView handle(String id) {
   MyThing obj = getObjById(id);
   //... do stuff and return ModelAndView
}

Qui, dichiariamo solo parametri per le cose di cui abbiamo bisogno.

Fin qui tutto bene, ma è qui che WebArgumentResolver entra. Dì che voglio rimuovere il getObjById Dal mio controller del tutto, perché forse penso che ingragga il codice e forse è usato su molti altri metodi di controller. Invece, voglio farlo:

@RequestMapping
public ModelAndView handle(MyThing id) {
   //... do stuff and return ModelAndView
}

È ancora più semplice e ha un minimo indispensabile di codice caldaia. Un'usanza WebArgumentResolver può essere registrato con il contesto app che riconosce i parametri del tipo MyThing, e sa come estrarre le informazioni dalla richiesta. Spring invoca quel risolvere e passa il risultato al metodo del controller.

I risolutori personalizzati non sono comunemente usati, ma possono essere molto utili nella giusta situazione.

L'esempio nella tua domanda usa CustomArgumentResolver Per risolvere l'usanza dell'esempio RequestAttribute classe. Il resolver tira fuori gli attributi di richiesta e li lega RequestAttribute Oggetti, in modo che possano essere dichiarati come parametri del metodo del controller.

Altri suggerimenti

WebArgumentResolverS sono un modo per specificare come risolvere i parametri dei metodi mappati MVC. Se desideri utilizzare un oggetto personalizzato come parametro per un metodo mappato a MVC, Spring cerca di capire come dare un senso a modo suo. In genere ciò accadrebbe attraverso l'associazione, in cui alcuni parametri HTTP che inviati corrispondono con i campi dell'oggetto e Spring li abbinano e crea un nuovo oggetto per te.

Se hai mai una situazione in cui i parametri inviati non corrispondono in modo così ordinato ai parametri del metodo, WebArgumentResolvers è lì per colmare il gap: fornisci una logica personalizzata in modo che Spring non debba capirlo.

Nel tuo esempio, Param è uno di questi parametri da abbinare. Questo pezzo di codice personalizzato controlla prima se il parametro ha un'annotazione @Requestattribute. In tal caso, il codice personalizzato estrae il valore da quell'oggetto e lo cerca come un attributo sulla richiesta HTTP, restituendolo. Non ha tale annotazione, quindi il metodo restituisce il valore irrisolto, il che indica semplicemente che questo WebArgumentResolver non sa nulla di questo particolare parametro e Spring dovrebbe provare un metodo diverso (come l'associazione).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top