Add a workaround for DATACMNS-776
Spring Data’s web support includes a handler method argument resolver, ProxyingHandlerMethodArgumentResolver, that inaccurately claims that it can handle all interface handler method arguments. This causes problems for handler methods that take Spring Mobile’s Device as an argument as the proxied Device instance does not behave correctly. This commit works around the problem by assigning an order to the WebMvcConfigurerAdapter that registers Spring Mobile’s argument resolver with Spring MVC. This ordering ensures that Spring Mobile’s resolver takes precedence over Spring Data’s for Device arguments. Closes gh-4163
This commit is contained in:
parent
c7c685f65f
commit
037a27e257
|
|
@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
|
|||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver;
|
||||
import org.springframework.mobile.device.DeviceResolver;
|
||||
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
|
||||
|
|
@ -48,6 +49,7 @@ public class DeviceResolverAutoConfiguration {
|
|||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication
|
||||
@Order(0)
|
||||
protected static class DeviceResolverMvcConfiguration
|
||||
extends WebMvcConfigurerAdapter {
|
||||
|
||||
|
|
|
|||
|
|
@ -20,15 +20,23 @@ import org.junit.After;
|
|||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.test.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.mobile.device.Device;
|
||||
import org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver;
|
||||
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
|
@ -38,6 +46,8 @@ import static org.hamcrest.Matchers.hasItemInArray;
|
|||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* Tests for {@link DeviceResolverAutoConfiguration}.
|
||||
|
|
@ -76,10 +86,7 @@ public class DeviceResolverAutoConfigurationTests {
|
|||
public void deviceResolverHandlerInterceptorRegistered() throws Exception {
|
||||
this.context = new AnnotationConfigWebApplicationContext();
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
this.context.register(Config.class, WebMvcAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class,
|
||||
DeviceResolverAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.register(Config.class);
|
||||
this.context.refresh();
|
||||
RequestMappingHandlerMapping mapping = this.context
|
||||
.getBean(RequestMappingHandlerMapping.class);
|
||||
|
|
@ -89,7 +96,23 @@ public class DeviceResolverAutoConfigurationTests {
|
|||
hasItemInArray(instanceOf(DeviceResolverHandlerInterceptor.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deviceHandlerMethodArgumentWorksWithSpringData() throws Exception {
|
||||
this.context = new AnnotationConfigWebApplicationContext();
|
||||
this.context.register(Config.class);
|
||||
this.context.setServletContext(new MockServletContext());
|
||||
this.context.refresh();
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||
mockMvc.perform(get("/")).andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ImportAutoConfiguration({ WebMvcAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class,
|
||||
DeviceResolverAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
SpringDataWebAutoConfiguration.class,
|
||||
RepositoryRestMvcAutoConfiguration.class })
|
||||
protected static class Config {
|
||||
|
||||
@Bean
|
||||
|
|
@ -103,8 +126,11 @@ public class DeviceResolverAutoConfigurationTests {
|
|||
protected static class MyController {
|
||||
|
||||
@RequestMapping("/")
|
||||
public void test() {
|
||||
|
||||
public ResponseEntity<Void> test(Device device) {
|
||||
if (device.getDevicePlatform() != null) {
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue