Заменяя AnnotationMethodHandlerAdapter с помощью RequestMappingHandlerAdapter issue

Недавно я обновился до spring 3.2 и заметил, что AnnotationMethodHandlerAdapter устарел в пользу RequestMappingHandlerAdapter. Поэтому я переконфигурировал использование нового класса, в комплекте с пользовательским MessageConverter мне нужно. Все хорошо и хорошо.

Однако при попытке нажать URL-адрес, поддерживаемый аннотированным Controller, я получаю сообщение об ошибке:

 [java] javax.servlet.ServletException: No adapter for handler [[email protected]]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
 [java]     at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1128)
 [java]     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:903)
 [java]     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)

При отладке диспетчера и, в частности, метода Dispatcher.getHandlerAdapter(), он находит мой HandlerAdapter, но вызываемый AbstractHandlerMethodAdapter.supports() хочет a MethodHandler:

public final boolean supports(Object handler) {
  return handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler);
}

и контроллер не является HandlerMethod. Метод поддержки AnnotatedMethodHandlerAdapter... ну, другой (и работает все еще!)

public boolean supports(Object handler) {
  return getMethodResolver(handler).hasHandlerMethods();
}

Поэтому я, по-видимому, не могу просто перейти на новый класс... Мне не хватает некоторой дополнительной настройки, но документация на самом деле не помогает мне. Любые идеи?

Спасибо.

Ответ 1

Используйте "<mvc:annotation-driven/>" в конфигурационном файле spring вместо того, чтобы писать собственную реализацию WebMvcConfigurationSupport

Пример

    <mvc:annotation-driven/>
<context:component-scan base-package="com.springapp.mvc"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            </list>
        </property>

    </bean>

Ответ 2

Итак, как оказалось, простое переключение определения bean не работает из-за того, что RequestMappingHandlerAdapter зависит от целого узла создаваемых и настроенных объектов. Spring по умолчанию использует объект WebMvcConfigurationSupport для выполнения всей этой конфигурации по умолчанию, но просто создание моей собственной версии bean не помогает, потому что spring создает свой собственный.

Мой подход оказался чем-то вроде строк ниже, где я оставил в основном всю конфигурацию до spring по умолчанию, но затем добавил мой собственный конвертер. Единственным недостатком является то, что он переключает конфигурацию xml на javaconfig, но в моем случае это нормально. Здесь есть статья , которая описывает нечто подобное.

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {

  @Bean
  public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
    RequestMappingHandlerAdapter handlerAdapter = super.requestMappingHandlerAdapter();
    handlerAdapter.getMessageConverters().add(0, getProtobufJsonMessageConverter());
    return handlerAdapter;
  }

Ответ 3

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
  @Override
  protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
    return new XXXXRequestMappingHandlerAdapter();
  }
}