2012-12-15 13 views
9

Po uaktualnieniu mojej aplikacji MVC wiosny do wiosny 3.2 Dostaję następujący wyjątek podczas uzyskiwania dostępu do niektórych z moich adresów URL:HttpMediaTypeNotAcceptableException po uaktualnieniu do Wiosna 3.2

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation 
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:203) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:272) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:212) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:55) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1091) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1076) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:896) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915) [spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE] 
(...) 

wyników Ten wyjątek HTTP 406 nie do przyjęcia.

udało mi się stworzyć uproszczoną kontrolera z adresu URL nie mogę dostępu:

@RequestMapping(value = "/resources/foo.js", produces = "text/javascript") 
@ResponseBody 
public String foo() throws Exception { 
    return ""; 
} 

Ponieważ używam zwykłej przeglądarki, która ma */* w Accept -header, nie widzę dlaczego Powinienem otrzymać HTTP 406. Jeszcze dziwniejsze jest to, że ten kod działa ze Spring 3.1.2, ale nie ze Spring 3.2. Dlaczego?

Odpowiedz

10

Było kilka zmian związanych z tym, jak Spring does content-negotiations in 3.2. Jedna z tych zmian polega na tym, że negocjacje treści można teraz przeprowadzić na podstawie sufiksu pliku w adresie URL. Ta funkcja jest domyślnie włączona. W wersjach wiosennych sprzed wersji 3.2 nagłówek akceptujący HTTP był używany do negocjacji treści. Gdy przeglądarki uzyskują dostęp do adresów URL, negocjowanie treści rzadko stanowiło problem, ponieważ przeglądarka zawsze wysyła Accept:(...)*/*.

Wiosna ma mapę sufiksu => Typ medium. W przypadku ".js" domyślnym typem nośnika jest "application/x-javascript". Kiedy Spring próbuje wyszukać odwzorowanie programu obsługi na żądanie do /resources/foo.js, nie będzie ono pasować do metody foo(), ponieważ generuje niewłaściwy typ multimediów.

Nie jestem pewien, czy zespół Spring zastanawiał się nad tą sprawą. To jest co najmniej trochę dziwne, że pozwala utworzyć @RequestMapping, do którego nie można uzyskać dostępu (z powodu niezgodności między typem nośnika .js a ustawionym w polu produkuje).

Istnieje kilka sposobów rozwiązania tego problemu. Jednym z nich jest zmiana parametru produkcyjnego na "application/x-javascript". Inną metodą jest zmiana typu mediów ".js" na "text/javascript" (see the docs of how to do that). Trzecią możliwością jest wyłączenie negocjacji treści na podstawie przyrostków (ponownie, see the docs of how to do it).

2

Mam teraz działa poprzez wyłączenie pobierania typu mediów w oparciu o rozszerzenie żądanej ścieżki. Można to zrobić przez:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/> 
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> 
    <!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers --> 
    <property name="favorPathExtension" value="false" /> 
</bean> 

I podaj wersję 3.2 dla wszystkich lokalizacji schematu xsd.

+0

W przypadku korzystania WebMvcConfigurerAdapter spróbować @Override public void configureContentNegotiation (ContentNegotiationConfigurer configurer) { \t super.configureContentNegotiation (configurer); \t configurer.favorPathExtension (fałsz); } –

0

Musisz dodać odpowiednią MessageConverter do swojej konfiguracji, razem z taką, którą możesz już mieć dla Jacksona.

np. w podklasie WebMvcConfigurerAdapter:

@Override 
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) { 
    converters.add(new StringHttpMessageConverter()); 
} 

Jeśli nadal zachować opcja favorPathExtension włączony, nie będzie wymagać parametru produces jak również, kontroler powróci application/javascript.

Wskazówki w odpowiedzi Aleksandra nie pomogły mi pozbyć się 406, gdy miałem ten sam problem.

0

Mam podobny problem, gdy reszta wywołanie do kontrolera ma zmienną ścieżki, która zawiera .au w wartości ścieżki. Wiosna czyta.au jako rozbudowa plik ze względu na wiosenne negocjacji zawartości

REST GET wywołanie jest http://localhost:8080/api/forgot-password/[email protected] powodu .au w ścieżce zmiennej wiosną rzuca org.springframework.web.HttpMediaTypeNotAcceptableException

Mamy rozwiązane poprzez wyłączenie na podstawie zawartości negocjacja

@Configuration 
public class ContentNegotiationConfig extends WebMvcConfigurerAdapter{ 
    @Override 
    public void configureContentNegotiation(final 
    ContentNegotiationConfigurer configurer) { 
     // Turn off suffix-based content negotiation 
     configurer.favorPathExtension(false); 
    } 

} 
Powiązane problemy