résumé
SpringMVC utilise le convertisseur de messages pour réaliser la conversion automatique entre les messages de demande et les objets, les objets et les messages de réponse.
Dans SpringMVC, vous pouvez utiliser les deux annotations @Requestbody et @ResponseBody pour compléter respectivement la conversion des messages de demande en objets et des objets aux messages de réponse. Le mécanisme de conversion des messages flexible sous-jacent est le HTTPMessageConverter nouvellement introduit, le mécanisme de convertisseur de message, qui est le HTTPMessageConverter nouvellement introduit au printemps 3.x.
L'abstraction de la demande #HTTP est toujours de retourner à la demande de demande, c'est-à-dire pour analyser le corps de la demande, puis retourner le message de réponse. Il s'agit du processus de demande HTTP le plus fondamental. Nous savons que dans la norme de servlet, les méthodes suivantes dans l'interface javax.servlet.servletRequest peuvent être utilisées:
public servleTinputStream getInputStream () lève ioException;
Pour obtenir un servletinputStream. Dans ce servletInputStream, tous les contenus d'un message de demande bru peuvent être lus. De même, dans l'interface javax.servlet.servletResponse, les méthodes suivantes peuvent être utilisées:
public servletOutputStream getOutputStream () lève ioException;
Pour obtenir un servletOutputStream, ce servletOutputSteam, hérité de OutputStream en Java, vous permet de sortir le contenu du paquet de réponse HTTP.
Essayons de penser comme le designer de SpringMVC. Nous savons que les paquets de demande et de réponse HTTP sont essentiellement une chaîne de chaînes. Lorsque le paquet de demande arrive dans le monde Java, il sera encapsulé dans un flux d'entrée ServleTinputStream pour nous à lire des paquets. Le message de réponse est sorti via le flux de sortie d'un servletOutputStream.
Nous ne pouvons lire que le message de chaîne d'origine du flux, et de même, nous ne pouvons écrire les caractères d'origine que dans le flux de sortie. Dans le monde Java, le traitement de la logique métier est basé sur des objets spécifiques aux entreprises comme dimensions de traitement. Ensuite, lorsque le message arrive à SpringMVC et sort de SpringMVC, il y a un problème d'impédance entre les chaînes et les objets Java. Ce processus ne peut pas être converti manuellement par le développeur. Nous savons que dans Struts2, OGNL est utilisé pour traiter ce problème, tandis que dans SpringMVC, c'est le mécanisme HTTPMessageConverter. Regardons d'abord les deux interfaces.
#HTTPInputMessage Cette classe est une abstraction d'un message de demande HTTP dans Springmvc. Dans la méthode read () de HttpMessageConverter, il existe un paramètre formel de HttpinputMessage, qui est l'abstraction interne du récepteur "Message de demande" utilisé par le convertisseur de message de SpringMVC. Le convertisseur de message extrait les messages du "message de demande" en fonction des règles et les convertit en objets déclarés dans le paramètre formel de la méthode.
package org.springframework.http; import java.io.ioexception; import java.io.inputStream; interface publique httpinputMessage étend httpMessage {inputStream getBody () lance ioException;}#HTTPOutputMessage Cette classe est une abstraction du message de réponse HTTP dans Springmvc. Dans la méthode écrite () de HttpMessageConverter, il existe un paramètre formel de HttpOutputMessage, qui est l'abstraction interne du récepteur "Message de réponse" utilisé par le convertisseur de message de SpringMVC. Le convertisseur de message écrit le "message de réponse" dans le message de réponse selon certaines règles.
package org.springframework.http; import java.io.ioexception; import java.io.outputStream; interface publique httpOutputMessage étend httpMessage {outputStream getBody () lance ioException;}#HTTPMessageConverter L'abstraction d'interface le plus élevé du convertisseur de messages décrit les caractéristiques générales d'un convertisseur de message. Nous pouvons comprendre le processus de réflexion des concepteurs Spring3.x sur ce mécanisme à partir des méthodes définies dans cette interface.
package org.springframework.http.converter; import java.io.ioexception; import java.util.list; import org.springframework.http.httpinputMessage; import org.springframework.http.httppoutputmesage; HttpMessageConverter <T> {boolean canread (class <?> Clazz, mediaType mediaType); Boolean CanWrite (classe <?> Clazz, MediaType MediaType); List <diasyType> GetSupportedMeAyPes (); T Lead (classe <? Étend T> Clazz, httpinputMessage InputMessage) lève IOException, httpMessageNotReadableException; Void Write (T T, MediaType ContentType, HttpOutputMessage OutputMessage) lève IOException, httpMessagenotWitableException;}La définition de l'interface HttpMessageConverter a apparié les méthodes CanRead (), Read () et CanWrite (), Write (). MediaType est l'encapsulation de l'attribut de type multimédia demandé. Par exemple, lorsque nous déclarons la méthode de traitement suivante.
@RequestMapping (value = "/ string", méthode = requestMethod.post) public @ResponseBody String readString (@Requestbody String) {return "read string '" + string + "'";}Avant que Springmvc entre dans la méthode ReadString, il sélectionnera la classe d'implémentation HTTPMessageConverter appropriée en fonction de l'annotation @Requestbody pour analyser les paramètres de demande dans la variable de chaîne. Plus précisément, la classe StringHttpMessageConverter est utilisée. Sa méthode CanRead () renvoie true, puis sa méthode read () lira les paramètres de demande de la demande et se lient à la variable de chaîne de la méthode readString ().
Lorsque Springmvc exécute la méthode ReadString, puisque la valeur de retour identifie @ResponseBody, Springmvc utilisera la méthode écrite () de StringHttpMessageConverter et écrira le résultat sous forme de valeur de chaîne dans le message de réponse. Bien sûr, la méthode CanWrite () renvoie vrai pour le moment.
Nous pouvons utiliser le chiffre suivant pour décrire brièvement ce processus.
#RequestResponseBodyMethodProcessor Une classe décrite dans l'ensemble de processus ci-dessus est org.springframework.web.servlet.mvc.method.annotation.requestResponseBodyMethodProcessor. Cette classe implémente à la fois les interfaces HandLerMethodargumentResolver et HandLerMethodreturnValueHandler. Le premier est une interface de stratégie qui lie le message de demande aux paramètres formels de la méthode de traitement, et le second est une interface de stratégie qui traite la valeur de retour de la méthode de traitement. Les codes source des deux interfaces sont les suivants:
package org.springframework.web.method.support; import org.springframework.core.methodParameter; import org.springframework.web.bind.webdatabinder org.springframework.web.context.request.nativewebRequest; interface publique HandlerMethodargumentResolver {boolean supportSparAmètre (paramètre méthodyParamètre); Object ResolVeargument (Paramètre MethodParameter, ModelAndViewContainer MavContainer, nativewebRequest webRequest, webDatabinderFactory bindFactory) lève une exception;} package org.springframework.web.methodport; org.springframework.web.context.request.nativewebRequest; interface publique HandlerMethoDreTurnValueHandler {boolean supportSreturnType (méthodeParameter returnType); void handlereTurnValue (objet returnValue, méthodeParameter returnType, ModelandViewContainer mavContainer, indigène webrequest) lève une exception;}La classe de demandeResponseBodyMethodProcessor sert également de deux rôles: analyse des paramètres de la méthode et traitement de la valeur de retour. À partir de son code source, nous pouvons trouver l'implémentation de la méthode des deux interfaces ci-dessus.
Implémentation de l'interface HandlerMethodargumentResolver:
Public Boolean SupportSParameter (paramètre méthodeParameter) {return Parameter.HasParameterannotation (requestbody.class);} Objet public Resolveargument (paramètre méthodeParameter, ModelAndViewContainer MavContainer, nativewebrequest webrequest readwithMessageConverters (webRequest, Paramètre, paramètre.getGenericParameterType ()); String name = Conventions.getVariabbleNameForParAmètre (paramètre); WebDataBinder Binder = bindFactory.CreateBinder (WebRequest, argument, nom); if (argument! = null) {valider (linder, paramètre); } mavContainer.addattribute (bindingResult.model_key_prefix + name, binder.getBindingResult ()); Retour argument;}Implémentation de l'interface HandLerMethoDreturnValueHandler
Public Boolean SupportSreTurnType (méthodyParameter returnType) {return returnType.getMethodannotation (réponse. HttpmediaTyPenotaCceptableException {mavContainer.setRequestHandled (true); if (returnValue! = null) {writeWithMessageConverters (returnValue, returnType, webRequest); }}Après avoir lu le code ci-dessus, l'ensemble du contexte de conversion de message HttpMessageConverter est déjà très clair. Parce que l'implémentation des deux interfaces est basée sur la question de savoir s'il existe @Requestbody et @ResponseBody comme condition, puis HttpMessageConverter est appelé respectivement pour lire et écrire des messages.
Si vous souhaitez vous demander comment suivre les demandes de surface de service de laMethodProcessor, veuillez suivre les idées des articles de blog précédents, puis allez sur Spring-MVC-Showcase pour télécharger le code source et déboguer les exemples liés à HttpMessageConverter. Tant que vous êtes prêt à travailler dur, je crois que vous gagnerez certainement le vôtre.
#Watching Zhang Xiaolong en parlant de l'essence de WeChat, il a déclaré: "WeChat n'est qu'une plate-forme, et les messages y circulent." Dans notre processus d'analyse du code source SpringMVC, nous pouvons comprendre des vérités similaires du mécanisme HTTPMessageConverter. Aux yeux des concepteurs de SpringMVC, un message de demande et un message de réponse sont abstraits en un message de demande httpinputMessage et un message de réponse httpoutputMessage, respectivement.
Lors du traitement d'une demande, le convertisseur de message approprié lie le message de demande à un objet de paramètre formel dans la méthode. Ici, il peut y avoir plusieurs formulaires de message différents pour le même objet, tels que JSON et XML. De même, lors de la réponse à une demande, la valeur de retour de la méthode peut également être renvoyée à différents formulaires de message, tels que JSON et XML.
Dans SpringMVC, nous avons différentes classes d'implémentation HTTPMessageConverter pour gérer divers formulaires de message pour différentes formulaires de message. Cependant, tant que les "informations valides" contenues dans ces messages sont cohérentes, divers convertisseurs de messages généreront le même résultat de conversion. Quant aux différences de détails d'analyse entre divers messages, ils sont bloqués dans différentes classes d'implémentation HTTPMessageConverter.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.