Zusammenfassung
SpringMVC verwendet den Message Converter, um die automatische Konvertierung zwischen Anforderungsnachrichten und Objekten, Objekten und Antwortnachrichten zu realisieren.
In SpringMVC können Sie die beiden Anmerkungen @RequestBody und @ResponseBody verwenden, um die Konvertierung von Anforderungsnachrichten in Objekte und Objekte in Antwortmeldungen zu vervollständigen. Der zugrunde liegende Mechanismus für flexible Nachrichtenkonvertierung ist der neu eingeführte httpMessageConverter, der Messger -Mechanismus, der neu eingeführte httpMessageConverter in Spring 3.x.
Die Abstraktion der #HTTP-Anfrage besteht weiterhin darin, zur Anfrage zu reagieren, dh die Anfrage zu analysieren und dann die Antwortnachricht zurückzugeben. Dies ist der grundlegendste HTTP -Anfrageprozess. Wir wissen, dass im Servlet -Standard die folgenden Methoden in der Schnittstelle von javax.servlet.servletRequest verwendet werden können:
public servletInputStream GetInputStream () löscht IOException aus;
um einen servletinputstream zu bekommen. In diesem ServletInputStream können alle Inhalte einer RAW -Anforderungsnachricht gelesen werden. In ähnlicher Weise können in der Schnittstelle zwischen javax.servlet.servletResponse die folgenden Methoden verwendet werden:
public servletoutputStream GetOutputStream () löst IOException aus;
Um einen ServletoutputStream zu erhalten, können Sie mit diesem von OutputStream in Java geerbten ServletoutputSteam den Inhalt des HTTP -Antwortpakets ausgeben.
Versuchen wir, wie der Designer von SpringMVC zu denken. Wir wissen, dass HTTP -Anfrage- und Antwortpakete im Wesentlichen eine Zeichenfolge von Strings sind. Wenn das Anfragepaket in die Java -Welt kommt, wird es in einen ServletInputStream -Eingangsstrom eingekapselt, damit wir Pakete lesen können. Die Antwortmeldung wird über den Ausgabestream eines ServletoutputStream ausgegeben.
Wir können die ursprüngliche String -Nachricht nur aus dem Stream lesen und in ähnlicher Weise können wir die Originalzeichen nur in den Ausgabestream schreiben. In der Java-Welt basiert die Verarbeitung der Geschäftslogik auf geschäftsspezifischen Objekten als Verarbeitungsabmessungen. Wenn dann die Nachricht in SpringMVC ankommt und aus SpringMVC ausgeht, besteht ein Impedanzproblem zwischen Saiten und Java -Objekten. Dieser Prozess kann vom Entwickler nicht manuell konvertiert werden. Wir wissen, dass OGNL in Struts2 verwendet wird, um mit diesem Problem umzugehen, während es in SpringMVC der HttpMessageConverter -Mechanismus ist. Schauen wir uns zuerst die beiden Schnittstellen an.
#HttpInputMessage Diese Klasse ist eine Abstraktion einer HTTP -Anforderungsnachricht in SpringMVC. In der Read () -Methode von httpMessageConverter gibt es einen formalen Parameter von httpinputMessage, der die interne Abstraktion des Rezeptors "Anforderungsnachricht" ist, der vom Nachrichtenkonverter von SpringMVC verwendet wird. Der Nachrichtenkonverter extrahiert Nachrichten aus der "Anforderungsnachricht" gemäß den Regeln und konvertiert sie in Objekte, die im formalen Parameter der Methode deklariert sind.
Paket org.springframework.http; import Java.io.ioxception; importieren java.io.inputStream; öffentliche Schnittstelle httpInputMessage erweitert HttpMessage {InputStream GetBody () Ausläufe IOException;}#HttpoutputMessage Diese Klasse ist eine Abstraktion der HTTP -Antwortnachricht in SpringMVC. In der Write () -Methode von httpMessageConverter gibt es einen formalen Parameter von httpoutputMessage, der die interne Abstraktion der Rezeptor -Antwortmeldung "Antwort" ist, die vom Nachrichtenkonverter von SpringMVC verwendet wird. Der Nachrichtenkonverter schreibt die "Antwortnachricht" gemäß bestimmten Regeln in die Antwortnachricht.
Paket org.springframework.http; importieren java.io.ioxception; import Java.io.outputStream; öffentliche Schnittstelle httpoutputMessage erweitert HttpMessage {outputStream GetBody () Ausläufe IOException;}#HttpMessageConverter Die Abstraktion des Meldungswandlers auf höchster Ebene beschreibt die allgemeinen Merkmale eines Nachrichtenkonverters. Wir können den Denkprozess von Spring3.x -Designern auf diesem Mechanismus aus den in dieser Schnittstelle definierten Methoden verstehen.
Paket org.springFramework.http.Converter; import Java.io.ioException; import Java.util.List; org.springframework.http.httpinputMessage; HttpMessageConverter <T> {boolean canread (Klasse <?> Clazz, minyType mediType); Boolean Canwrite (Klasse <?> Clazz, mediType mediType); Liste <MediasType> getSupportedMediTypes (); T Read (Klasse <? Erweitert T> Clazz, httpinputMessage InputMessage) löst IOException, httpMessagenotreadableException aus; void write (t t, minytype contentType, httpoutputMessage outputMessage) löst ioException, httpMessagenotwritable -Exception aus;}Die Definition der HTTPMessArverter -Schnittstelle hat Canread (), Read () und Canwrite (), Write () -Methoden gepaart. MediaType ist die Kapselung des angeforderten Medientypattributs. Zum Beispiel, wenn wir die folgende Verarbeitungsmethode deklarieren.
@RequestMapping (value = "/string", method = requestMethod.post) public @RespondeBody String readString (@RequestBody String) {return "Lesestring '" + String + "'";}Bevor SpringMVC die ReadString -Methode eingibt, wird die entsprechende httpMessageConverter -Implementierungsklasse gemäß der @RequestBody -Annotation ausgewählt, um die Anforderungsparameter in die Zeichenfolgevariable zu analysieren. Insbesondere wird die StringHttpMessageConverter -Klasse verwendet. Die Methode canread () gibt true zurück, und dann wird die Read () -Methode die Anforderungsparameter aus der Anforderung gelesen und an die String -Variable der ReadString () -Methode binden.
Wenn SpringMVC die ReadString -Methode ausführt, verwendet SpringMVC, da der Rückgabewert @ResponseBody identifiziert, die Schreibmethode von StringHttpMessArverter und schreibt das Ergebnis als String -Wert in die Antwortmeldung. Natürlich gibt die Canwrite () -Methode zu diesem Zeitpunkt wahr zurück.
Wir können die folgende Abbildung verwenden, um diesen Prozess kurz zu beschreiben.
#RequestResponseBodyMethodProcessor Eine im obigen Prozesssatz beschriebene Klasse ist org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodethodProcessor. Diese Klasse implementiert sowohl die HandleMethodargumentResolver- als auch die HandleMethodreturnValueHandler -Schnittstellen. Ersteres ist eine Richtlinienschnittstelle, die die Anforderungsnachricht an die formalen Parameter der Verarbeitungsmethode bindet, und letzteres ist eine Richtlinienschnittstelle, die den Rückgabewert der Verarbeitungsmethode verarbeitet. Die Quellcodes der beiden Schnittstellen sind wie folgt:
Paket org.springframework.web.method.Support; import org.springframework.core.methodParameter; Import org.springframework.web.bind.Webdatabinder; Import org.springFramework.Web.Bind.Support.Webdatabinders org.springframework.web.context.request.NativeWebRequest; HandleMethodarGumentResolver der öffentlichen Schnittstelle (methodParameter); Object ResolVearGument (Methodparameter Parameter, modelandViewContainer Mavcontainer, natives WebRequest WebRequest, WebDatabinderFactory Bindfactory) löst Ausnahme aus;} Paket org.springframework.web.Method.Support; org.springframework.web.context.request.NativeWebRequest; HandleMethodreturnValueHandler der öffentlichen Schnittstelle (boolean SupportSreturnType (MethodParameter ReturnTyPe); void HandlereturnValue (Object ReturnValue, MethodParameter ReturnType, ModelAndViewContainer Mavcontainer, nativeWebRequest WebRequest) löst Ausnahme aus;}
Die RequestResponseBodyMethodProcessor -Klasse dient auch als zwei Rollen: Methodenparameteranalyse und Rückgabewertverarbeitung. Aus seinem Quellcode finden wir die Methodenimplementierung der beiden oben genannten Schnittstellen.
Implementierung der HandleMethodargumentResolver -Schnittstelle:
public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(RequestBody.class);}public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory bindFactory) throws Exception { Object argument = ReadWithmessageConverters (WebRequest, Parameter, Parameter.GetgenericParameterType ()); String name = Conventions.getVariBablEnameForParameter (Parameter); WebDatabinder binder = bindfactory.createbinder (WebRequest, Argument, Name); if (argument! = null) {validate (binder, parameter); } mavcontainer.addAttribute (BindingResult.model_key_prefix + Name, binder.getBindingResult ()); Rückgabeargument;}Implementierung der HandleMethodreturnValueHandler -Schnittstelle
public boolean SupportSreturnType (MethodParameter ReturnTyPe) {return returnType.getMethodannotation (ResponseBody.Class)! HttpMediTypenotacceptableException {mavcontainer.setRequesthandled (true); if (returnValue! }}Nach dem Lesen des oben genannten Codes ist der gesamte HTTPMessageConverter -Nachrichtenkontext bereits sehr klar. Denn die Implementierung der beiden Schnittstellen basiert darauf, ob @RequestBody und @ResponseBody als Bedingung vorhanden sind, und dann wird httpMessageConverter aufgerufen, um Nachrichten zu lesen und zu schreiben.
Wenn Sie fragen möchten, wie Sie den RequestResponseBodyMethodProcessor verfolgen möchten, folgen Sie bitte den Ideen der vorherigen Blog-Beiträge und gehen Sie zu Spring-MVC-Showcase, um den Quellcode herunterzuladen und die httpMessArverter-bezogenen Beispiele zu debuggen. Solange Sie bereit sind, hart zu arbeiten, glaube ich, dass Sie definitiv Ihre eigenen gewinnen werden.
#Watching Zhang Xiaolong, als er über die Essenz von WeChat sprach, sagte er: "Wechat ist nur eine Plattform, und Nachrichten zirkulieren." In unserem Prozess der Analyse von SpringMVC -Quellcode können wir ähnliche Wahrheiten aus dem HttpMessageConverter -Mechanismus verstehen. In den Augen der SpringMVC -Designer werden eine Anforderungsnachricht und eine Antwortmeldung in eine Anforderungsnachricht httpInputMessage und eine Antwortnachricht httpoutputMessage abstrahiert.
Bei der Bearbeitung einer Anforderung bindet der entsprechende Nachrichtenkonverter die Anforderungsnachricht an ein formales Parameterobjekt in der Methode. Hier kann es mehrere verschiedene Nachrichtenformulare für dasselbe Objekt wie JSON und XML geben. In ähnlicher Weise kann bei der Beantwortung einer Anfrage auch der Rückgabewert der Methode an verschiedene Nachrichtenformulare wie JSON und XML zurückgegeben werden.
In SpringMVC haben wir unterschiedliche HTTPMessageConverter -Implementierungsklassen, um verschiedene Nachrichtenformulare für verschiedene Nachrichtenformulare zu verarbeiten. Solange die in diesen Nachrichten enthaltenen "gültigen Informationen" konsistent sind, generieren verschiedene Nachrichtenkonverter das gleiche Konvertierungsergebnis. In Bezug auf die Unterschiede in den Parsingdetails zwischen verschiedenen Nachrichten sind sie in verschiedenen HTTPMessArverter -Implementierungsklassen blockiert.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.