JsonMappingException: Nenhum construtor adequado encontrado para o tipo [tipo simples, classe ]: não pode instanciar a partir do objeto JSON

Estou a receber o seguinte erro ao tentar obter um pedido do JSON e processá-lo:

org.codehaus.jackson.map.JsonMappingException: Nenhum construtor adequado encontrado para o tipo [tipo simples, classe com.myweb.ApplesDO]: não se pode instanciar a partir do objecto JSON (necessidade de adicionar/activar informação do tipo?)

Aqui está o JSON que estou a tentar enviar:

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

No Controller, eu tenho a seguinte assinatura do método:

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

AllApplesDO é um invólucro de ApplesDO :

public class AllApplesDO {

    private List<ApplesDO> applesDO;

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

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

MaçãsDO:

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
    }
}

Eu acho que o Jackson não consegue converter o JSON em objectos Java para subclasses. Por favor, ajude com os parâmetros de configuração para que Jackson converta JSON em objetos Java. Eu estou usando o Spring Framework.

EDITAR: Incluído o maior bug que está causando este problema na classe de amostra acima - Por favor, procure a resposta aceita para a solução.

Solução

Então, finalmente percebi qual é o problema. Não é um problema de configuração do Jackson, como eu duvidava.

Na verdade, o problema estava na classe **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
    }
}

Havia um construtor personalizado definido para a classe, tornando-a o construtor padrão. A introdução de um construtor dummy fez com que o erro desaparecesse:

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() {
    }

}
Comentários (13)

Isto acontece por estas razões:

  1. A sua classe interna deve ser definida como **estática***.

    classe estática privada Condição { // específica de Jackson
    }
  2. Pode ser que você não tenha um construtor padrão na sua classe (UPDATE: Este parece não ser o caso)

    classe estática privada Condição {
        identificação privada longa;
    
        condição pública() {
        }
    
        // Setters e Getters
    }
  3. Pode ser que seus Setters não estejam definidos corretamente ou não sejam visíveis (por exemplo, setter privado).

Comentários (14)

Pode testar esta estrutura, por favor? Se eu me lembro bem, pode usá-la desta forma:

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

Em segundo lugar, por favor adicione construtor padrão a cada classe que também pode ajudar.

Comentários (4)