Dave Syer opened SPR-15037 and commented

The samples in spring-secuirty-oauth2 suffer from this problem. I think it is probably platform/browser dependent because I couldn't reproduce it till today, and now I can (Ubuntu 14.04, Chrome 50.0.2661.86). The browser sends

[text/html, application/xhtml+xml, image/webp, application/xml;q=0.9, */*;q=0.8]

and the app sends back a response entity with Content-Type: image/jpeg. The converter comes in and claims that it can convert to

[image/vnd.wap.wbmp, image/png, image/x-png, image/jpeg, image/bmp, image/gif]

And then fails to do the conversion to the highest priority media type:

Dec 21, 2016 8:35:20 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/tonr2] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Only integral single-band bilevel image is supported.] with root cause
java.lang.IllegalArgumentException: Only integral single-band bilevel image is supported.
    at com.sun.imageio.plugins.wbmp.WBMPImageWriter.checkSampleModel(WBMPImageWriter.java:313)
    at com.sun.imageio.plugins.wbmp.WBMPImageWriter.write(WBMPImageWriter.java:171)
    at org.springframework.http.converter.BufferedImageHttpMessageConverter.write(BufferedImageHttpMessageConverter.java:225)
    at org.springframework.http.converter.BufferedImageHttpMessageConverter.write(BufferedImageHttpMessageConverter.java:67)
...

The sample is old and still uses Spring 4.0.9, but I tried with 4.3.4 (just add <spring.version>4.3.4.RELEASE</spring.version> to the properties in the tonr2 pom.xml) and the problem is the same.


Affects: 4.3.4

Reference URL: https://github.com/spring-projects/spring-security-oauth/issues/427

Issue Links: - #18985 Rendering of a Resource should try to derive the served media type

Comment From: spring-projects-issues

Rossen Stoyanchev commented

This looks like another variation of #18985 where an image needs to be rendered but we are not considering the actual image type. The main difference is that in #18985 the return value is a Resource. The root cause however is the same which is that content negotiation uses a generic list of producible media types (i.e. HttpMessageConverter#getSupportedMediaTypes) which is based on the return value type and does not consider the actual value instance.

We need some fix. Clearly rendering a JPEG as WBMP when the browser says it will accept anything isn't quite right and can cause failures.

As a workaround in the case of the Spring Security OAuth2 example the request mapping can explicitly influence the producible media type with @RequestMapping(producible="image/jpeg". That's not always the case though such as is the case of #18985 where the image to be rendered is not known ahead of time.