Completado 406 NOT_ACCEPTABLE - Prueba de WebLayer en SpringBoot

Dec 07 2020

Tengo este método en una aplicación Spring Boot v2.1.0.RELEASE.

@GetMapping(value = "/wildProject", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<WildProject>> getList(HttpServletRequest request,
        HttpServletResponse response)
        throws Exception {

    List<WildProject> list = authorisationService.getList();

    System.out.println("-----------------");
    System.out.println(list);
    System.out.println("-----------------");

    return ok().body(list);


} 

y esta prueba:

 this.mockMvc.perform(get("/wildProject")
  //.accept(MediaType.APPLICATION_JSON_UTF8_VALUE))
  // .andDo(print())
  .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
  .andExpect(status().isOk());

y este es el resultado de la prueba:

20:03:38.253 [main] DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Using 'application/json', given [*/*] and supported [application/json]
20:03:38.255 [main] WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]
20:03:38.256 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Completed 406 NOT_ACCEPTABLE

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /wildProject
       Parameters = {}
          Headers = {Content-Type=[application/json;charset=UTF-8]}
             Body = null
    Session Attrs = {}

Handler:
             Type = com.bonansa.controller.AuthorisationController
           Method = public org.springframework.http.ResponseEntity<java.util.List<com.bonansa.WildProject>> com.bonansa.controller.AuthorisationController.getList() throws java.lang.Exception

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.web.HttpMediaTypeNotAcceptableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 406
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

y

@JsonSerialize(as = IWildProject.class)
public interface IWildProject {
..
}

Respuestas

s7vr Dec 19 2020 at 04:59

Su problema parece doble.

El problema subyacente es que no ha registrado el conversor de mensajes correcto para poder escribir la respuesta json. Esto está oculto debido al error en el que el servidor debería devolver 500 en lugar de 406 por una configuración incorrecta, ya que el controlador ha especificado la anotación produce y el cliente ha aceptado el encabezado de todos.

Más detalles - https://github.com/spring-projects/spring-framework/issues/23287

Esto ya no es un problema en la última versión solo con la versión 2.1.x de arranque de primavera.

2 x80486 Dec 08 2020 at 00:48

No es necesario que establezca el Content-Typeencabezado para las GETsolicitudes, ya que no envía nada, sino que solicita algo. El Acceptencabezado es lo que se busca en este caso.

Además, MediaType.APPLICATION_JSON_VALUEno coincidirá MediaType.APPLICATION_JSON_UTF8_VALUE.

Recomendaría refactorizar ese fragmento de código en:

this.mockMvc.perform(get("/wildProject")
  .accept(MediaType.APPLICATION_JSON_VALUE))
  // .andDo(print())
  .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
  .andExpect(status().isOk());