Atmosphere + Spring MVC 5 integration

139 Views Asked by At

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 ?

0

There are 0 best solutions below