I was trying to run Atmosphere (2.5.12) + Spring MVC (5.2.8) but encountered a certain problem.
Since some Spring release an AbstractMessageConverterMethodProcessor class, writeWithMessageConverters method has started to check response header 'Content-Type' rather then 'Accept' header of a request in order to find appropriate message converter.
See:
MediaType selectedMediaType = null;
MediaType contentType = outputMessage.getHeaders().getContentType();
boolean isContentTypePreset = contentType != null && contentType.isConcrete();
if (isContentTypePreset) {
if (logger.isDebugEnabled()) {
logger.debug("Found 'Content-Type:" + contentType + "' in response");
}
selectedMediaType = contentType;
}
else {
HttpServletRequest request = inputMessage.getServletRequest();
List<MediaType> acceptableTypes = getAcceptableMediaTypes(request);
List<MediaType> producibleTypes = getProducibleMediaTypes(request, valueType, targetType);
Problem is that Atmosphere Framework set Content-Type header as well. And it always 'text/plain', it is set in AtmosphereFramework configureRequestResponse method.
see: https://github.com/Atmosphere/atmosphere/issues/2312
Even if the header is not set there, it is default contentType within AtmosphereResponseImpl, which is text/html...
In this case, Spring can never find a correct converter and exception is thrown:
DefaultHandlerExceptionResolver]: Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.Connection] with preset Content-Type 'text/plain;charset=utf-8']
I am using a current configuration in web.xml:
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.atmosphere.cpr.MeteorServlet</servlet-class>
<init-param>
<param-name>org.atmosphere.servlet</param-name>
<param-value>org.springframework.web.servlet.DispatcherServlet</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.CometSupport.maxInactiveActivity</param-name>
<param-value>3600000000</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.useStream</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.useWebSocket</param-name>
<param-value>true</param-value>
</init-param>
<!-- <init-param> -->
<!-- <param-name>org.atmosphere.useNative</param-name> -->
<!-- <param-value>true</param-value> -->
<!-- </init-param> -->
<init-param>
<param-name>org.atmosphere.cpr.supportSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.filter</param-name>
<param-value>org.springframework.web.filter.DelegatingFilterProxy</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.filter.name</param-name>
<param-value>springSecurityFilterChain</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.websocket.suppressJSR356</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
<param-value>org.atmosphere.client.TrackMessageSizeFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
...........
Is my configuration correct ? Do all requests have to go through public AtmosphereFramework configureRequestResponse(AtmosphereRequest req, AtmosphereResponse res) method ? Is there any way to make Spring ignore Content-Type header in AtmosphereResponseImpl ?