MockMvc HttpMediaTypeNotSupportedException: тип содержимого '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;

}

TestConfiguration выглядит так:

@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 не работает и возвращает это исключение HttpMediaTypeNotSupportedException. Я попытался добавить и удалить заголовки для подтверждения и типа содержимого как в запросе, так и в контроллере, и это, похоже, не работает.

Эта проблема, похоже, связана с тестом интеграции Spring с mockmvc выбрасывает org.springframework.web.HttpMediaTypeNotSupportedException: тип содержимого application / json не поддерживается, но удаление excludeFilters в TestConfiguration в этом случае не позволяет интерпретировать контекст Spring. Кроме того, я не уверен, что имел в виду Карл R, говоря «включение времени выполнения сервера в мой путь к классам».

Любая помощь приветствуется.


person dinamix    schedule 14.06.2017    source источник


Ответы (2)


Я думаю, вам следует добавить @EnableWebMvc в свой TestConfiguration.

@Configuration
@ComponentScan(
     basePackages = "com.app",
    excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, 
              classes = App.class)
    }
)
@EnableWebMvc
public class TestConfiguration {
person walv    schedule 14.06.2017
comment
Одна из самых неприятных ошибок без правильного сообщения об ошибке. Спасибо! - person Marcin T.P. Łuczyński; 10.03.2020

В моем случае проблема заключалась в том, что я не установил contentType, поэтому установка типа JSON решила проблему для меня.

...
.contentType(MediaType.APPLICATION_JSON)
...
person Harsh Gundecha    schedule 28.06.2021