MockMvc HttpMediaTypeNotSupportedException:不支持内容类型 'application/json'
MockMvc HttpMediaTypeNotSupportedException: Content type 'application/json' not supported
我收到以下异常:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.readWithMessageConverters(HandlerMethodInvoker.java:653)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestBody(HandlerMethodInvoker.java:612)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:361)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:175)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
我的测试如下所示:
public class AvailabilityControllerTest extends BaseTest {
@Test
public void createAvailability() throws Exception {
final String createAvailabilityEndPoint = "/api/v4/companies/123/availabilities";
final String responseName = "availabilityResponseDTO";
AvailabilityDTO availabilityDTO = new AvailabilityDTO();
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.post(createAvailabilityEndPoint)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.accept(MediaType.APPLICATION_JSON_VALUE)
.content(new ObjectMapper().writeValueAsString(availabilityDTO)))
.andExpect(MockMvcResultMatchers.status().isCreated())
.andReturn();
}
BaseTest 为:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
@AutoConfigureMockMvc
public class BaseTest {
@Autowired
protected MockMvc mockMvc;
}
测试配置如下所示:
@Configuration
@ComponentScan(
basePackages = "com.app",
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = App.class)
}
)
public class TestConfiguration {
@Bean
public ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes();
}
}
AvailabilityController 看起来像这样:
@RestController
@RequestMapping("/api/v4/companies")
public class AvailabilityController {
public static final String ACCEPT_APP_JSON = "Accept=" + AcceptableMediaType.APPLICATION_JSON;
@Autowired
private AvailabilityFacade availabilityFacade;
@RequestMapping(value = "/{companyId}/employees/{employeeId}/availabilities", method = RequestMethod.GET)
public List<AvailabilityEventResponseDTO> getUserAvailabilities(@PathVariable String companyId,
@PathVariable String employeeId) {
return availabilityFacade.getUserAvailabilities(employeeId);
}
@RequestMapping(value = "/{companyId}/availabilities", method = RequestMethod.POST, headers = ACCEPT_APP_JSON, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<AvailabilityResponseDTO> createAvailability(@PathVariable String companyId,
@Valid @RequestBody AvailabilityDTO availabilityDTO) {
return new ResponseEntity<>(
availabilityFacade.createAvailability(companyId, availabilityDTO),
HttpStatus.CREATED
);
}
}
基本上 GET 请求适用于 MockMvc,但 POST 不适用并且 returns 此 HttpMediaTypeNotSupportedException。我尝试在请求和控制器中为接受和内容类型添加和删除 headers,但这似乎不起作用。
这个问题似乎与 有关,但在这种情况下删除 TestConfiguration 中的 excludeFilters 不允许 Spring 解释上下文。另外,我不确定 Karl R 所说的 "including a serverruntime on my classpath".
是什么意思
感谢任何帮助。
我认为您应该将 @EnableWebMvc 添加到您的 TestConfiguration。
@Configuration
@ComponentScan(
basePackages = "com.app",
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
classes = App.class)
}
)
@EnableWebMvc
public class TestConfiguration {
在我的情况下,问题是我没有设置 contentType
,所以将其设置为 JSON 类型解决了我的问题。
...
.contentType(MediaType.APPLICATION_JSON)
...
我收到以下异常:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.readWithMessageConverters(HandlerMethodInvoker.java:653)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestBody(HandlerMethodInvoker.java:612)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:361)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:175)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
我的测试如下所示:
public class AvailabilityControllerTest extends BaseTest {
@Test
public void createAvailability() throws Exception {
final String createAvailabilityEndPoint = "/api/v4/companies/123/availabilities";
final String responseName = "availabilityResponseDTO";
AvailabilityDTO availabilityDTO = new AvailabilityDTO();
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.post(createAvailabilityEndPoint)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.accept(MediaType.APPLICATION_JSON_VALUE)
.content(new ObjectMapper().writeValueAsString(availabilityDTO)))
.andExpect(MockMvcResultMatchers.status().isCreated())
.andReturn();
}
BaseTest 为:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
@AutoConfigureMockMvc
public class BaseTest {
@Autowired
protected MockMvc mockMvc;
}
测试配置如下所示:
@Configuration
@ComponentScan(
basePackages = "com.app",
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = App.class)
}
)
public class TestConfiguration {
@Bean
public ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes();
}
}
AvailabilityController 看起来像这样:
@RestController
@RequestMapping("/api/v4/companies")
public class AvailabilityController {
public static final String ACCEPT_APP_JSON = "Accept=" + AcceptableMediaType.APPLICATION_JSON;
@Autowired
private AvailabilityFacade availabilityFacade;
@RequestMapping(value = "/{companyId}/employees/{employeeId}/availabilities", method = RequestMethod.GET)
public List<AvailabilityEventResponseDTO> getUserAvailabilities(@PathVariable String companyId,
@PathVariable String employeeId) {
return availabilityFacade.getUserAvailabilities(employeeId);
}
@RequestMapping(value = "/{companyId}/availabilities", method = RequestMethod.POST, headers = ACCEPT_APP_JSON, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<AvailabilityResponseDTO> createAvailability(@PathVariable String companyId,
@Valid @RequestBody AvailabilityDTO availabilityDTO) {
return new ResponseEntity<>(
availabilityFacade.createAvailability(companyId, availabilityDTO),
HttpStatus.CREATED
);
}
}
基本上 GET 请求适用于 MockMvc,但 POST 不适用并且 returns 此 HttpMediaTypeNotSupportedException。我尝试在请求和控制器中为接受和内容类型添加和删除 headers,但这似乎不起作用。
这个问题似乎与
感谢任何帮助。
我认为您应该将 @EnableWebMvc 添加到您的 TestConfiguration。
@Configuration
@ComponentScan(
basePackages = "com.app",
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
classes = App.class)
}
)
@EnableWebMvc
public class TestConfiguration {
在我的情况下,问题是我没有设置 contentType
,所以将其设置为 JSON 类型解决了我的问题。
...
.contentType(MediaType.APPLICATION_JSON)
...