Ich habe eine Spring 3.0-Anwendung mit einer Web-Controller-Methode. Diese Methode gibt normalerweise eine Datei in der HTTP-Antwort zurück, daher habe ich den Rückgabetyp org.springframework.http.HttpEntity
verwendet. Aber jetzt gibt es eine zweite Anforderung: Wenn die Datei größer als 1 MB ist und es nach 10 Uhr ist, sollte eine HTML-Seite angezeigt werden.
Mein Problem ist also, dass die Methode manchmal eine HttpEntity<byte[]>
und manchmal eine ModelAndView
zurückgibt. Aber wie kann man diese zwei verschiedenen Arten eines Rückgabetyps haben?
( Ok, die Anforderung ist nicht 10 Uhr, es ist viel komplizierter, aber der Punkt ist, dass diese Beschreibung nur im Controller gemacht werden kann. )
(Diese Anwendung verwendet klassisches JSPX zum Rendern von HTML-Seiten.)
Es ist zu einfach (Entschuldigung für die Frage): man könnte die Methode mit dem Rückgabetyp Object
definieren, also könnte man Instanzen von ModelAndView
oder HttpEntity
zurückgeben.
Dies funktioniert, weil die AnnotationMethodHandlerAdapter#getModelAndView
den Rückgabewert als Object
nimmt und dann eine if-then-else-Kaskade mit vielen inncstanceof
-Anweisungen hat, um den Concreate-Instanztyp zu bestimmen.
Wenn der Return-Typ Object
zu allgemein ist, könnte man eine eigene Klasse (compound-class) definieren, die in zwei verschiedenen Feldern ein ModelAndView
oder HttpEntity
enthält. Und dann muss man eine benutzerdefinierte ModelAndViewResolver
schreiben.
Diese benutzerdefinierte ModelAndViewResolver
nimmt das zusammengesetzte Objekt und
ModelAndView
oder webRequest
like AnnotationMethodHandlerAdapter#handleHttpEntityResponse
und gibt dann null Ich denke, dass die bessere Lösung hier ein regulärer HTTP-Filter ist, der die Bedingungen überprüft und entweder die Anfrage an den "normalen" Fluss oder an die HTML-Seite weiterleitet.
Damit können Sie Ihre Logik entkoppeln. Wahrscheinlich werden Sie in Zukunft eine weitere Anforderung erhalten, die die Anfrage an einen anderen Pfad weiterleitet. Sie können dies in einem weiteren Filter implementieren.
Die Filter können den gleichen Spring-Kontext verwenden und daher die gleichen Beans, DB usw. verwenden.
BEARBEITEN. Denken Sie auch an den Spring Interceptor. Ich persönlich habe diese Technik nicht benutzt, aber es kann auch hier helfen.