Gerar classe Java a partir de JSON?

215

Em um projeto Java Maven, como você gera arquivos de origem java a partir do JSON? Por exemplo, temos

{
  "firstName": "John",  
  "lastName": "Smith",  
  "address": {  
    "streetAddress": "21 2nd Street",  
     "city": "New York"
  }
}

Quando rodamos mvn generate-sources, queremos que ele gere algo como isto:

class Address  {
    JSONObject mInternalJSONObject;

    Address (JSONObject json){
        mInternalJSONObject = json;
    }

    String  getStreetAddress () {
        return mInternalJSONObject.getString("streetAddress");
    }

    String  getCity (){
        return mInternalJSONObject.getString("city");
    }
}

class Person {        
    JSONObject mInternalJSONObject;

    Person (JSONObject json){
        mInternalJSONObject = json;
    }

    String  getFirstName () {
        return mInternalJSONObject.getString("firstName");
    }

    String  getLastName (){
        return mInternalJSONObject.getString("lastName");
    }

    Address getAddress (){
        return Address(mInternalJSONObject.getString("address"));
    }
}

Como desenvolvedor Java, quais linhas de XML eu preciso escrever no meu pom.xmlpara que isso aconteça?

Denis Palnitsky
fonte
Atualizei a pergunta e a resposta para torná-las no tópico. Por favor, reabra.
Alex R

Respostas:

269

Experimente o plug-in jsonschema2pojo :

        <plugin>
            <groupId>org.jsonschema2pojo</groupId>
            <artifactId>jsonschema2pojo-maven-plugin</artifactId>
            <version>1.0.2</version>
            <configuration>
                <sourceDirectory>${basedir}/src/main/resources/schemas</sourceDirectory>
                <targetPackage>com.myproject.jsonschemas</targetPackage>
                <sourceType>json</sourceType>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

Ele <sourceType>json</sourceType>cobre o caso em que as fontes são json (como o OP). Se você tiver esquemas json reais , remova esta linha.

Atualizado em 2020. Duas coisas aconteceram desde dezembro de 2009, quando essa pergunta foi feita:

  • A especificação do esquema JSON mudou muito. Ainda está em rascunho (não finalizado), mas está próximo da conclusão e agora é uma ferramenta viável que especifica suas regras estruturais

  • Recentemente, iniciei um novo projeto de código aberto especificamente destinado a resolver seu problema: jsonschema2pojo . A ferramenta jsonschema2pojo pega um documento de esquema json e gera classes Java no estilo DTO (na forma de arquivos de origem .java). O projeto ainda não está maduro, mas já fornece cobertura das partes mais úteis do esquema json. Estou procurando mais feedback dos usuários para ajudar a impulsionar o desenvolvimento. No momento, você pode usar a ferramenta na linha de comando ou como um plugin do Maven.

Espero que isto ajude!

joelittlejohn
fonte
4
Alguém que usou sua ferramenta jsonschema2pojo não teria que escrever seu próprio arquivo de esquema? O OP pediu para começar com um arquivo Json, não um esquema. Existe uma ferramenta complementar para ir de Json -> Schema? Suponho que essa ferramenta, se existisse, poderia apenas fornecer um palpite.
21412 Jeff Jeffelelodod
3
A partir da versão 0.3.3, você pode usar JSON velho liso como entrada :)
joelittlejohn
14
... e agora também há um gerador on-line: jsonschema2pojo.org
joelittlejohn
2
Excelente ferramenta. O link fornecido contém uma ferramenta online na qual é possível colar a amostra JSON, clicar em um botão e obter a origem Java.
mbmast
1
@testerjoe Se você quer dizer o código-fonte Java, então sim jsonschema2pojo faz isso, e está disponível como um maven plugin, tarefa formiga, extensão Gradle, ferramenta CLI, biblioteca java, etc ...
joelittlejohn
21

Se você estiver usando Jackson (a biblioteca mais popular lá), tente

https://github.com/astav/JsonToJava

Seu código aberto e qualquer pessoa deve poder contribuir.

Resumo

Um gerador de arquivo de classe de origem JsonToJava que deduz o esquema com base nos dados json de amostra fornecidos e gera as estruturas de dados java necessárias.

Ele incentiva as equipes a pensar em Json primeiro, antes de escrever o código real.

Recursos

  • Pode gerar classes para uma hierarquia arbitrariamente complexa (recursivamente)
  • Pode ler suas classes Java existentes e, se puder desserializar essas estruturas, fará isso
  • Solicitará a entrada do usuário quando existirem casos ambíguos
Astav
fonte
13

Aqui está uma ferramenta on - line que utiliza o JSON, incluindo objetos aninhados ou matrizes aninhadas de objetos e gera uma fonte Java com anotações de Jackson.

Tim Boudreau
fonte
1
Isso funcionou muito bem para mim na primeira tentativa. Eu tinha aninhado profundamente o JSON e funcionou bem, embora eu tivesse que cortar partes redundantes para obter o tamanho geral abaixo de 2k. Permitiu-me escrever: MyClass c = new MyClass (); c = gson.fromJson (c.getHTML (someURLthatReturnsJSON), MyClass.class); e os dados resultantes fluíram perfeitamente. Eu tive que remover todas essas anotações de Jackson, mas, caso contrário, funcionou bem para o gson. Obrigado.
noogrub
Obrigado, funciona. Quando alimentei um JSON com campos que diferenciam maiúsculas de minúsculas, este site retornou um resultado, enquanto www.jsonschema2pojo.org relatou um erro.
CoolMind
6

Respondendo a essa pergunta antiga com o projeto recente ;-).

No momento, a melhor solução é provavelmente o JsonSchema2Pojo :

Ele faz o trabalho do esquema Json raramente usado, mas também com o Json comum. Ele fornece o plug-in Ant e Maven e um aplicativo de teste on - line pode fornecer uma idéia da ferramenta. Coloquei um Tweet Json e gerou toda a classe que contém (Tweet, Usuário, Local, etc.).

Vamos usá-lo no projeto Agorava para gerar o mapeamento de mídia social e acompanhar a evolução do conteúdo em sua API.

Antoine Sabot-Durand
fonte
Essa também é a minha impressão, mas ainda não testei o plug-in Maven, no entanto, a versão online é muito lenta e morre por algo que não seja a classe Person habitual ... Portanto, para uma rápida conversão online, a ferramenta do @ tim-boudreau funcionou melhor para mim.
Gregor
Eu tentei o JsonSchema2Pojo, mas pressionar o botão Visualizar exibe a visualização em branco.
AndroidDev
5

Obrigado a todos que tentaram ajudar.
Para mim, esse script foi útil. Ele processa apenas JSON simples e não cuida de tipos, mas automatiza algumas rotinas

  String str = 
        "{"
            + "'title': 'Computing and Information systems',"
            + "'id' : 1,"
            + "'children' : 'true',"
            + "'groups' : [{"
                + "'title' : 'Level one CIS',"
                + "'id' : 2,"
                + "'children' : 'true',"
                + "'groups' : [{"
                    + "'title' : 'Intro To Computing and Internet',"
                    + "'id' : 3,"
                    + "'children': 'false',"
                    + "'groups':[]"
                + "}]" 
            + "}]"
        + "}";



    JSONObject json = new JSONObject(str);
    Iterator<String> iterator =  json.keys();

    System.out.println("Fields:");
    while (iterator.hasNext() ){
       System.out.println(String.format("public String %s;", iterator.next()));
    }

    System.out.println("public void Parse (String str){");
    System.out.println("JSONObject json = new JSONObject(str);");

    iterator  = json.keys();
    while (iterator.hasNext() ){
       String key = iterator.next();
       System.out.println(String.format("this.%s = json.getString(\"%s\");",key,key ));

    System.out.println("}");
Denis Palnitsky
fonte
5

Estou ciente de que essa é uma pergunta antiga, mas me deparei com ela enquanto tentava encontrar uma resposta.

A resposta que menciona o gerador json-pojo online (jsongen) é boa, mas eu precisava de algo que pudesse executar na linha de comando e ajustar mais.

Então, eu escrevi um script ruby ​​muito hacky para pegar um arquivo JSON de amostra e gerar POJOs a partir dele. Ele tem várias limitações (por exemplo, não trata de campos que correspondem a palavras-chave reservadas em java), mas faz o suficiente para muitos casos.

O código gerado, por padrão, faz anotações para uso com Jackson, mas isso pode ser desativado com um comutador.

Você pode encontrar o código no github: https://github.com/wotifgroup/json2pojo

Chris R
fonte
2

Até onde eu sei, não existe essa ferramenta. Ainda.

O principal motivo é, suspeito, que, diferentemente do XML (que possui Esquema XML e, em seguida, ferramentas como 'xjc' para fazer o que você pede, entre definições XML e POJO), não existe uma linguagem de esquema com recursos completos. Existe o esquema JSON, mas ele tem muito pouco suporte para definições de tipos reais (enfoca as estruturas JSON), portanto, seria complicado gerar classes Java. Mas provavelmente ainda é possível, esp. se algumas convenções de nomenclatura foram definidas e usadas para dar suporte à geração.

No entanto: isso é algo que tem sido solicitado com bastante frequência (nas listas de discussão dos projetos de ferramentas JSON que eu sigo), então acho que alguém escreverá essa ferramenta em um futuro próximo.

Portanto, não acho que seja uma má ideia em si (também: não é uma boa ideia para todos os casos de uso, depende do que você deseja fazer).

StaxMan
fonte
2

Eu tinha o mesmo problema, então decidi começar a escrever uma pequena ferramenta para me ajudar com isso. Vou compartilhar e abrir a fonte.

https://github.com/BrunoAlexandreMendesMartins/CleverModels

Ele suporta JAVA, C # e Objective-c de JSON.

Sinta-se livre para contribuir!

ehanoc
fonte
2

Você também pode tentar a biblioteca GSON. É bastante poderoso, ele pode criar JSON a partir de coleções, objetos personalizados e funciona também vice-versa. É lançado sob a Licença Apache 2.0, para que você possa usá-lo também comercialmente.

http://code.google.com/p/google-gson/

MB.One
fonte
13
não cria definições java
necromante
3
Não é disso que se trata a questão
hop
0

Para adicionar à postagem de @ japher. Se você não está particularmente ligado ao JSON, vale a pena conferir os Buffers de Protocolo .

dgorissen
fonte
1
Os buffers de protocolo nem sequer estão perto de uma resposta sobre como criar objetos Java a partir do JSON. No mínimo, você deve ter recomendado uma ferramenta para criar objetos Java a partir de buffers de protocolo.
James.garriss
0

Experimente minha solução

http://htmlpreview.github.io/?https://raw.githubusercontent.com/foobnix/android-universal-utils/master/json/generator.html

{
    "auctionHouse": "sample string 1",
    "bidDate": "2014-05-30T08:20:38.5426521-04:00 ",
    "bidPrice": 3,
    "bidPrice1": 3.1,
    "isYear":true
}

Classe Java de resultado

private String  auctionHouse;
private Date  bidDate;
private int  bidPrice;
private double  bidPrice1;
private boolean  isYear;

JSONObject get

auctionHouse = obj.getString("auctionHouse");
bidDate = obj.opt("bidDate");
bidPrice = obj.getInt("bidPrice");
bidPrice1 = obj.getDouble("bidPrice1");
isYear = obj.getBoolean("isYear");

JSONObject put

obj.put("auctionHouse",auctionHouse);
obj.put("bidDate",bidDate);
obj.put("bidPrice",bidPrice);
obj.put("bidPrice1",bidPrice1);
obj.put("isYear",isYear);
Foobnix
fonte
essa resposta parece tão trivial. Não há maneira automática para gerar pojo de json
Rafael Ruiz Tabares
0

Deixe-me mostrar como desenvolver a ferramenta. Você pode fazer isso:

  1. função javascript do usuário Json.parse (), faça string como-json trans no objeto js
  2. use esse objeto para gerar o formato javabean.
  3. algo: você deve se importar. (1) o mapeamento do tipo de valor, por exemplo, como descobrir a sequência, é o tipo de data. (2) loweser_case to camelCase

Eu desenvolvo uma ferramenta para resolver o problema. É um projeto bem rápido e mais. pegue o código do meu github .

aproveite daqui, eu implantei no servidor web .

Eu tento a sugestão das 2 principais respostas. Uma web não pode abrir. Uma é mais lenta que a minha ferramenta. Espero que você goste da minha ferramenta.

lizeyang
fonte
Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada.
achrome