Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
291 views
in Technique[技术] by (71.8m points)

java - How to return an image in Spring Boot controller and serve like a file system

I've tried the various ways given in Stackoverflow, maybe I missed something.

I have an Android client (whose code I can't change) which is currently getting an image like this:

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

Where url is the location of the image (static resource on CDN). Now my Spring Boot API endpoint needs to behave like a file resource in the same way so that the same code can get images from the API (Spring boot version 1.3.3).

So I have this:

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

Now when the Android code tries to get http://someurl/image1.jpg I get this error in my logs:

Resolving exception from handler [public org.springframework.http.ResponseEntity com.myproject.MyController.getImage(java.lang.String)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

Same error happens when I plug http://someurl/image1.jpg into a browser.

Oddly enough my tests check out 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

How do I get this to behave like an image being served up in the normal way? (Note I can't change the content-type header that the android code is sending)

EDIT

Code after comments (set content type, take out 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);
}

In a browser this just seems to give a stringified junk (byte to chars i guess). In Android it doesn't error, but the image doesn't show.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I believe this should work:

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

Notice that the content-type is set for ResponseEntity, not for HttpServletResponse directly.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...