2016-11-11 3 views
8

私はStackoverflowで与えられた様々な方法を試しました。Springブートコントローラでイメージを返す方法とファイルシステムのように役立ちます

私は現在、このような画像になっている(そのコードが、私は変更することはできません)Androidのクライアントがあります。url画像(CDN上の静的リソース)の場所です

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

を。今では、私のSpring Boot APIエンドポイントは、同じコードがAPIからイメージを取得できるように、ファイルリソースのように動作する必要があります(Springブートバージョン1.3.3)。

は、だから私はこれを持っている:

ハンドラ[パブリック org.springframeworkから例外を解決:Androidのコードはhttp://someurl/image1.jpgが、私は私のログにこのエラーを取得する取得しようとする今、

@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://www.ResponseEntity com.myproject.MyController.getImage(java.lang.String)]: org.springframework.web.HttpMediaTypeNotAcceptableException:できませんでした 見つけやすい表現

http://someurl/image1.jpgをブラウザに接続すると、同じエラーが発生します。

奇妙なことに私のテストは、[OK]をチェックアウト:

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 

がどのように私は、これは通常の方法でアップサービスされている画像のように動作するのですか? (私は、Androidコードが送信されるContent-Typeヘッダを変更することはできません)

EDIT

コードの後に​​コメント(producesを取り出し、コンテンツタイプを設定する):

@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); 
} 

ブラウザでは、これはちょうど文字列化されたジャンク(私は推測する文字にバイト)を与えるようです。 Androidではエラーは発生しませんが、画像は表示されません。私は、これは動作するはずと信じて

@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

クライアントはAcceptヘッダーとして何を送信しますか?produce属性を削除してレスポンスにコンテンツタイプを指定するとどうなりますか? –

+0

@JBNizet AcceptヘッダーはHttpURLConnection(Android SDK)のデフォルト値です。間違いなく特に設定されていません。私は 'produce'を省略しようとしましたが、それは(ブラウザで)プレーンテキストを提供するようです。 content-typeの設定は、とにかく 'produce'と同じですか? –

+0

@JBNizetコンテンツタイプを明示的に設定しようとしましたが、ログに同じエラーが表示されます –

答えて

8

は最後に、私は私のWebMvcConfigurerAdapterサブクラスにByteArrayHttpMessageConverterを追加する必要がありました...これを固定

コンテンツタイプが設定されていることに注意し
@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であり、HttpServletResponseでは直接ではありません。

+0

この回答は不完全なようです。あなたは@ Romanの答えのような完全な解決策を持っていますか? –

6

+0

ありがとう、私は実際にこの順列を試しましたが、それは私のために働いていませんでした –

+0

@ user2393012私はチェックして、それは私のために働く奇妙です。私は 'consumes'、' produce'、 '@ ResponseBody'も削除したことに気付きましたか?そして、このコードではどんなエラーがありましたか? – Roman

+0

はい、省略に気付きました。私は実際には何もエラーが発生していないブラウザでは、それはちょうど空のフレームとして表示されました –

5

あなたがファイル/ MIMEタイプを知らない場合は、これを行うことができます....私はアップロードされたファイルを取って、ファイル名をGUIDと拡張子とブラウザ/スマート携帯電話はイメージをロードすることはできません問題。 2番目はダウンロードするファイルを提供することです。

@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

いくつかのファイル(apple pass/wallet)が正しく動作するためには、コンテンツの長さを含める必要があります。 – mavriksc

関連する問題