Ich habe ein Servlet, das ein Bild als InputStreamResource
zurückgibt. Es gibt ca. 50 statische Bilder, die basierend auf einigen get query
Parametern zurückgegeben werden sollen.Wie man eine InputStreamResource in RestController zwischenspeichern?
Um nicht jedes dieser Bilder jedes Mal nachschlagen zu müssen (was sehr oft ist), möchte ich diese Bilder-Antworten zwischenspeichern.
@RestController
public class MyRestController {
//code is just example; may be any number of parameters
@RequestMapping("/{code}")
@Cachable("code.cache")
public ResponseEntity<InputStreamResource> getCodeLogo(@PathVariable("code") String code) {
FileSystemResource file = new FileSystemResource("d:/images/" + code + ".jpg");
return ResponseEntity.ok()
.contentType("image/jpg")
.lastModified(file.lastModified())
.contentLength(file.contentLength())
.body(new InputStreamResource(file.getInputStream()));
}
}
Bei Verwendung der @Cacheable
Annotation (egal ob direkt auf dem RestMapping
Verfahren oder an einen externen Dienstleister Refactoring), I_'m die folgende Ausnahme erhalten:
cause: java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times - error: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
org.springframework.core.io.InputStreamResource.getInputStream(InputStreamResource.java:96)
org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:100)
org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:47)
org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:195)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:238)
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:183)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
Frage: Wie kann Ich cache dann die ResponseEntity
vom Typ InputStreamResource
überhaupt?
Muss es nur einmal gelesen werden? Oder sollte die Datei auf dem Datenträger auf Änderungen überwacht werden? – Niels
Ich möchte '@ EvictCache' in festen Zeiträumen anrufen, zB nachts oder wöchentlich. Im Allgemeinen sollte es nur einmal vorbereitet und dann wiederverwendet werden, ohne dass die Datei lokal nachgeschlagen werden muss. – membersound
Löschen. Sonst könnte man die Datei während der Initialisierung des Controllers einmal gelesen haben und sie in eine ByteArrayResource laden ... – Niels