设置自定义 HttpMessageConverter 后无法发送图像
Fail to send image after setting custom HttpMessageConverter
我用 Spring 构建了一个 REST API。大多数控制器 return JSON 响应。我还有一个用于获取图像的控制器(它们不能静态引用,因为我必须授权访问它们)。
这是我的控制器处理图像的方法:
@RequestMapping("/image/{id}")
@ResponseBody
@PreAuthorize("hasRole('USER')")
public ResponseEntity<byte[]> get(@PathVariable ObjectId id) throws IOException {
InputStream image = imageRepository.findOne(id);
if (image == null) {
throw new Http404Exception("Image not found.");
}
final HttpHeaders headers = new HttpHeaders();
byte[] imageBytes = IOUtils.toByteArray(image);
headers.setContentType(MediaType.IMAGE_JPEG);
headers.setContentLength(imageBytes.length);
return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
}
此方法一直有效,直到我需要将 Jackson 配置为特定格式的 return 日期。在我将以下配置添加为 suggested in the docs 后,图像未正确 returned。
@Configuration
@EnableWebMvc
public class WebappConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.simpleDateFormat("yyyy-MM-dd");
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
图像响应如下(浏览器告诉它return编辑了数据但无法显示图像)。
我用 Fiddler 检查了响应,这是结果。对于同一张图片,它们完全不同。
无效图像:
工作图像:
解决方案是添加一个 HttpConverter,它将在 Jackson 转换器获取图像之前适当地处理它们。幸好Spring提供了ByteArrayHttpMessageConverter
最终配置:
@Configuration
@EnableWebMvc
public class WebappConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.simpleDateFormat("yyyy-MM-dd");
converters.add(new ByteArrayHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
我用 Spring 构建了一个 REST API。大多数控制器 return JSON 响应。我还有一个用于获取图像的控制器(它们不能静态引用,因为我必须授权访问它们)。
这是我的控制器处理图像的方法:
@RequestMapping("/image/{id}")
@ResponseBody
@PreAuthorize("hasRole('USER')")
public ResponseEntity<byte[]> get(@PathVariable ObjectId id) throws IOException {
InputStream image = imageRepository.findOne(id);
if (image == null) {
throw new Http404Exception("Image not found.");
}
final HttpHeaders headers = new HttpHeaders();
byte[] imageBytes = IOUtils.toByteArray(image);
headers.setContentType(MediaType.IMAGE_JPEG);
headers.setContentLength(imageBytes.length);
return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
}
此方法一直有效,直到我需要将 Jackson 配置为特定格式的 return 日期。在我将以下配置添加为 suggested in the docs 后,图像未正确 returned。
@Configuration
@EnableWebMvc
public class WebappConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.simpleDateFormat("yyyy-MM-dd");
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
图像响应如下(浏览器告诉它return编辑了数据但无法显示图像)。
我用 Fiddler 检查了响应,这是结果。对于同一张图片,它们完全不同。
无效图像:
工作图像:
解决方案是添加一个 HttpConverter,它将在 Jackson 转换器获取图像之前适当地处理它们。幸好Spring提供了ByteArrayHttpMessageConverter
最终配置:
@Configuration
@EnableWebMvc
public class WebappConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.simpleDateFormat("yyyy-MM-dd");
converters.add(new ByteArrayHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}