es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Convertir lista de objetos a un arreglo JSON en Java – Pruebas de API con Spring Boot

Cuando intento hacer una solicitud POST con MockMvc, tengo que pasar una lista de objetos en la etiqueta de contenido, el problema es que cada vez que intento pasarla con este método:

public static String asJsonString(final Object obj) {
        try {
            final ObjectMapper mapper = new ObjectMapper();
            final String jsonContent = mapper.writeValueAsString(obj);
            return jsonContent;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Recibo este error:

{"status":"NOT_ACCEPTABLE","errors":{"timestamp":"2021-11-29T11:53:11.2020882Z","message":"Formato de mensaje incorrecto","details":"Error de análisis JSON: No se puede deserializar la instancia de `java.util.ArrayList<Compania>` del token START_OBJECT; la excepción anidada es com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList<Compania>` del token START_OBJECT\n en [Origen: (PushbackInputStream); línea: 1, columna: 1]"}}

La prueba que hice para guardar solo un objeto funciona bien, pero cada vez que intento agregar una lista falla, aquí tienes mi código de prueba.

@Test
    void successSavePostCompaniaLista() throws Exception {
        Compania c1 = new Compania("Compania1 lista",
            "nombre1",
            "---",
            "---",
            null,
            null);
        Compania c2 = new Compania("Compania2 lista",
            "nombre2",
            "---",
            "---",
            null,
            null);

        List<Compania> companias = List.of(c1,c2);
        when(companiaRepository.save(any(Compania.class))).then(returnsFirstArg());

        this.mockMvc.perform(
                post("/companias/lista")
                    .header("authorization", "Bearer " + token)
                    .content(asJsonString(companias)) //<-- Aquí me da errores
                    .contentType(MediaType.APPLICATION_JSON))
            .andDo(print())
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.result[0].success[0]").isNotEmpty())
            .andExpect(jsonPath("$.result[0].success[0].nombre").value(c1.getNombre()))
            .andExpect(jsonPath("$.result[0].success[1].nombre").value(c2.getNombre()));

    }

El que funciona es similar a este, pero usando solo un objeto.

La dirección http y el resto están bien.

¡Gracias!

Edit. Aquí está el servicio que estoy intentando probar

public Map<String, Object> postListCompanias(List<Compania> companias) {
        for (int i = 0; i < companias.size(); i++) {
            Compania companiaN = companias.get(i);
            companiaN.setId(null);

            companiaRepository.save(companias.get(i));
            System.out.println(companias.get(i));
        }

        Map<String, Object> mappedResult = Collections.singletonMap(
            "result",
            List.of(
                Collections.singletonMap(
                    "success",
                    companias
                )
            )
        );
        return mappedResult;
    }

Y aquí el controlador:

@ResponseStatus(HttpStatus.CREATED)
    @PostMapping("/lista")
    public Map<String, Object> createCompanias(@RequestBody List<Compania> companias) {

        return companiaService.postListCompanias(companias);
    }
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error sugiere que hay un problema con el formato JSON. Parece que la entrada JSON no está siendo analizada correctamente como una lista de objetos Compania.

    Un problema podría ser que la entrada JSON no esté formateada correctamente como una lista. El método asJsonString en el código de prueba convierte la lista en una cadena JSON utilizando la clase ObjectMapper del paquete com.fasterxml.jackson.databind. El resultado JSON debería ser una matriz de objetos, donde cada objeto representa una instancia de Compania. Aquí hay un ejemplo de cómo debería verse el formato JSON:

    [
      {
        "name": "Compania1 list",
        "property1": "name1",
        "property2": "---",
        ...
      },
      {
        "name": "Compania2 list",
        "property1": "name2",
        "property2": "---",
        ...
      }
    ]
    

    Asegúrese de que la cadena JSON generada por el método asJsonString se parezca a esto.

    Otro problema podría estar en la propia clase Compania. El mensaje de error menciona una excepción MismatchedInputException, lo que sugiere que el analizador JSON tiene problemas para mapear la entrada JSON a la clase Compania. Asegúrese de que la clase Compania tenga un constructor predeterminado y getters/setters para todas las propiedades que necesitan ser mapeadas a JSON.

    Además, asegúrese de que la clase Compania esté anotada con las anotaciones adecuadas del paquete com.fasterxml.jackson.annotation, como @JsonProperty o @JsonIgnore. Estas anotaciones ayudan al analizador JSON a mapear correctamente la entrada JSON a la clase.

    Por último, puede intentar agregar algunas declaraciones de depuración al código de prueba para ver si la cadena JSON generada por el método asJsonString parece correcta. También puede intentar establecer un punto de interrupción dentro del método postListCompanias en la clase de servicio para ver si la entrada JSON se está analizando correctamente como una lista de objetos Compania.

Comments are closed.