JsonMappingException: no se encontró ningún constructor adecuado para el tipo [tipo simple, clase]: no se puede crear una instancia a partir del objeto JSON

Resuelto Lucky Murari asked hace 12 años • 14 respuestas

Recibo el siguiente error al intentar obtener una solicitud JSON y procesarla:

org.codehaus.jackson.map.JsonMappingException: no se encontró un constructor adecuado para el tipo [tipo simple, clase com.myweb.ApplesDO]: no se puede crear una instancia a partir del objeto JSON (¿es necesario agregar/habilitar información de tipo?)

Aquí está el JSON que estoy intentando enviar:

{
  "applesDO" : [
    {
      "apple" : "Green Apple"
    },
    {
      "apple" : "Red Apple"
    }
  ]
}

En Controlador, tengo la siguiente firma de método:

@RequestMapping("showApples.do")
public String getApples(@RequestBody final AllApplesDO applesRequest){
    // Method Code
}

AllApplesDO es un envoltorio de ApplesDO:

public class AllApplesDO {

    private List<ApplesDO> applesDO;

    public List<ApplesDO> getApplesDO() {
        return applesDO;
    }

    public void setApplesDO(List<ApplesDO> applesDO) {
        this.applesDO = applesDO;
    }
}

ManzanasHACER:

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String appl) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom){
        //constructor Code
    }
}

Creo que Jackson no puede convertir JSON en objetos Java para subclases. Ayúdenos con los parámetros de configuración de Jackson para convertir JSON en objetos Java. Estoy usando Spring Framework.

EDITAR: Se incluye el error principal que está causando este problema en la clase de muestra anterior. Busque la respuesta aceptada para obtener una solución.

Lucky Murari avatar Oct 02 '11 17:10 Lucky Murari
Aceptado

Entonces, finalmente me di cuenta de cuál es el problema. No es un problema de configuración de Jackson como dudaba.

En realidad, el problema estaba en la clase ApplesDO :

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String apple) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom) {
        //constructor Code
    }
}

Había un constructor personalizado definido para la clase, lo que la convertía en el constructor predeterminado. La introducción de un constructor ficticio ha provocado que el error desaparezca:

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String apple) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom) {
        //constructor Code
    }

    //Introducing the dummy constructor
    public ApplesDO() {
    }

}
Lucky Murari avatar Oct 02 '2011 14:10 Lucky Murari

Esto sucede por estas razones:

  1. su clase interna debe definirse como estática

    private static class Condition {  //jackson specific    
    }
    
  2. Puede ser que no tengas ningún constructor predeterminado en tu clase ( ACTUALIZACIÓN: Este parece no ser el caso)

    private static class Condition {
        private Long id;
    
        public Condition() {
        }
    
        // Setters and Getters
    }
    
  3. Podría ser que sus Definidores no estén definidos correctamente o no sean visibles (por ejemplo, definidores privados).

azerafati avatar Sep 14 '2014 09:09 azerafati

Me gustaría agregar otra solución a esto que no requiera un constructor ficticio. Dado que los constructores ficticios son un poco complicados y posteriormente confusos. Podemos proporcionar un constructor seguro y, al anotar los argumentos del constructor, permitimos a Jackson determinar la asignación entre el parámetro del constructor y el campo.

entonces lo siguiente también funcionará. Tenga en cuenta que la cadena dentro de la anotación debe coincidir con el nombre del campo.

import com.fasterxml.jackson.annotation.JsonProperty;
public class ApplesDO {

        private String apple;

        public String getApple() {
            return apple;
        }

        public void setApple(String apple) {
            this.apple = apple;
        }

        public ApplesDO(CustomType custom){
            //constructor Code
        }

        public ApplesDO(@JsonProperty("apple")String apple) {
        }

}
PiersyP avatar Nov 26 '2014 12:11 PiersyP