2016-11-11 16 views
8

Stackoverflow'ta verilen çeşitli yöntemleri denedim, belki bir şeyleri özledim. Bahar Önyükleme denetleyicisinde bir görüntüyü döndürme ve bir dosya sistemi gibi hizmet verme

Şu anda böyle bir görüntü elde ediyor (kimin kod ı değiştiremezsiniz) bir Android istemcisi vardır: url resmin konumunu (CDN üzerinde statik kaynak) 'dir

HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
connection.setRequestMethod("GET"); 
connection.connect(); 

. Şimdi Spring Boot API son noktamızın aynı kaynakta olduğu gibi bir dosya kaynağı gibi davranması gerekiyor, böylece aynı kodlar API'den görüntüler alabilir (Spring boot version 1.3.3).

Yani bu var:

işleyicisi [kamu org.springframework gelen istisnaları çözme: Android kod http://someurl/image1.jpg benim günlüklerinde bu hatayı olsun elde etmeye çalışır Şimdi

@ResponseBody 
@RequestMapping(value = "/Image/{id:.+}", method = RequestMethod.GET, consumes = MediaType.ALL_VALUE, produces = MediaType.IMAGE_JPEG_VALUE) 
public ResponseEntity<byte[]> getImage(@PathVariable("id")String id) { 
    byte[] image = imageService.getImage(id); //this just gets the data from a database 
    return ResponseEntity.ok(image); 
} 

. http.ResponseEntity com.myproject.MyController.getImage (java.lang.String)]: org.springframework.web.HttpMediaTypeNotAcceptableException: kabul edilebilir gösterimi bulunamıyor

Bir tarayıcıya http://someurl/image1.jpg'u bağladığımda aynı hata meydana gelir.

Garip benim testler Tamam check out:

Response response = given() 
      .pathParam("id", "image1.jpg") 
      .when() 
      .get("MyController/Image/{id}"); 

assertEquals(HttpStatus.OK.value(), response.getStatusCode()); 
byte[] array = response.asByteArray(); //byte array is identical to test image 

Nasıl bu bir görüntü normal şekilde sunulmakta gibi davranmaya alabilirim? (Ben android kod gönderiyor içerik tipi başlığını değiştiremezsiniz Not)

DÜZENLEME

Kod sonra yapılan yorumlar (produces çıkar, içerik türünü ayarlayın):

@RequestMapping(value = "/Image/{id:.+}", method = RequestMethod.GET, consumes = MediaType.ALL_VALUE) 
public ResponseEntity<byte[]> getImage(@PathVariable("id")String id, HttpServletResponse response) { 
    byte[] image = imageService.getImage(id); //this just gets the data from a database 
    response.setContentType(MediaType.IMAGE_JPEG_VALUE); 
    return ResponseEntity.ok(image); 
} 

Bir tarayıcıda bu sadece bir dizili hurda (sanırım chars bayt) vermek gibi görünüyor. Android'de hata yapmıyor, ancak resim gösterilmiyor. Bu işe gerektiğine inanıyoruz

@Override 
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
    final ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter(); 
    final List<MediaType> list = new ArrayList<>(); 
    list.add(MediaType.IMAGE_JPEG); 
    list.add(MediaType.APPLICATION_OCTET_STREAM); 
    arrayHttpMessageConverter.setSupportedMediaTypes(list); 
    converters.add(arrayHttpMessageConverter); 

    super.configureMessageConverters(converters); 
} 
+0

İstemci Accept üstbilgisi olarak ne gönderiyor?Üretme özelliğini kaldırdığınızda ne olur ve yalnızca yanıtta içerik türünü belirtin? –

+0

@JBNizet Accept üstbilgisi, HttpURLConnection (Android SDK) için varsayılan değerdir. Kesinlikle özel olarak ayarlanmadı. Üretimi ihmal etmeyi denedim, ancak bu düz metin (tarayıcıda) veriyor gibi görünüyor. İçerik türünü ayarlamak zaten "üretir" ile aynıdır, değil mi? –

+0

@JBNizet İçerik türünü de açık bir şekilde ayarlamayı denedim, aynı hatayı –

cevap

8

Son olarak benim WebMvcConfigurerAdapter alt sınıfa bir ByteArrayHttpMessageConverter eklemek zorunda ... Bu sabit

içerik türü için ayarlanmış Bildirimi o
@RequestMapping(value = "/Image/{id:.+}", method = RequestMethod.GET) 
public ResponseEntity<byte[]> getImage(@PathVariable("id") String id) { 
    byte[] image = imageService.getImage(id); 
    return ResponseEntity.ok().contentType(MediaType.IMAGE_JPEG).body(image); 
} 

ResponseEntity, doğrudan HttpServletResponse için değil.

+0

günlüğüne aldım bu yanıt eksik görünüyor. @ Roman'ın cevabı gibi görünen eksiksiz bir çözümünüz var mı? –

6

:

+0

Teşekkürler, aslında bu permütasyonu yaptım ama benim için çalışmadı –

+0

@ user2393012 Garip, çünkü kontrol ettim ve benim için çalışıyor. Tüketimi, "üretir" ve "ResponseBody" yi de kaldırdığımı fark ettiniz mi? Ve bu kodla hangi hatayı aldın? – Roman

+0

evet, eksiklikleri fark ettim. Aslında hiç bir hata almadım, tarayıcıda sadece boş bir çerçeve olarak belirdi –

5

Dosyayı/MIME türünü bilmiyorsanız bunu yapabilirsiniz .... Yüklenmiş bir dosyayı aldığım ve dosya adını bir kılavuz ve uzantı ve tarayıcı/smart ile değiştirdiğim için bunu yaptım Telefonlar görüntüyü herhangi bir sorun yükleyebilir. ikincisi, indirilecek bir dosyaya hizmet etmektir.

@RestController 
@RequestMapping("img") 
public class ImageController { 

@GetMapping("showme") 
public ResponseEntity<byte[]> getImage() throws IOException{ 
    File img = new File("src/main/resources/static/test.jpg"); 
    return ResponseEntity.ok().contentType(MediaType.valueOf(FileTypeMap.getDefaultFileTypeMap().getContentType(img))).body(Files.readAllBytes(img.toPath())); 
} 
@GetMapping("thing") 
public ResponseEntity<byte[]> what() throws IOException{ 
    File file = new File("src/main/resources/static/thing.pdf"); 
    return ResponseEntity.ok() 
      .header("Content-Disposition", "attachment; filename=" +file.getName()) 
      .contentType(MediaType.valueOf(FileTypeMap.getDefaultFileTypeMap().getContentType(file))) 
      .body(Files.readAllBytes(file.toPath())); 
} 


} 
+0

Bazı dosyalar (apple pass/cüzdan) düzgün çalışması için içerik uzunluğunu eklemelisiniz. – mavriksc

İlgili konular