Retornar propriedade de um objeto JSON

Boa noite!

Estou necessitando utilizar a classe JsonObject para buscar os dados retornados de uma consulta Json "https://tdn.totvs.com/display/tec/JsonObject%3AGetJsonText", o retorno da classe FWRest é nesse modelo:

"[{"id":30,"ativo":true,"codigo":"000001","nome_comercial":"BEBEDOURO ROSCAVEL"}]"

Utilizando o método fromJson, o retorno é nulo, se eu manipular a String de retorno retirando as chaves de inicio e fim, ficando assim:

"{"id":30,"ativo":true,"codigo":"000001","nome_comercial":"BEBEDOURO ROSCAVEL"}"

o método funciona corretamente.

Alguém saberia como que eu poderia usar esse método sem que tenha que fazer "gambiarras" para retirar as chaves da string para poder usa-la?

Neu,

Quando você faz o comando cRet := oObjJson:fromJson(cBody) ele cria um objeto, já tentou acessar deste modo: oObjJson[1]['id']?

Acabei de fazer o teste aqui e funcionou corretamente acessando desta maneira

Bom dia,

Acredito que você esteja enganado quanto a utilização dessa classe do binário, o retorno nulo (nil) do método fromJSON significa que o parser do JSON foi efetuado com sucesso, logo os valores do JSON ficam no objeto do JSONObject:

https://tdn.totvs.com/display/tec/Classe+JsonObject

Veja um exemplo de como utiliza essa classe com o seu JSON:


#include "protheus.ch"

user function JsonObj()
local cJSON as char
local cError as char
local nLoop as numeric
local jJSON

//JSON que será utilizado, ainda em formato string
cJSON := '[{"id":30,"ativo":true,"codigo":"000001","nome_comercial":"BEBEDOURO ROSCAVEL"}]'

//Cria o objeto de parser do JSON
jJSON := JSONObject():New()

//Efetuar o parser do JSON
jJSON:fromJSON(cJSON)

//Se vazio, significa que o parser ocorreu sem erros
if Empty(cError)
    ConOut("Leitura do JSON:")

    //Como o JSON é um array, criado um laço para a exibição de valores
    for nLoop := 1 to Len(jJSON)
        ConOut("", Replicate("=", 15) + Space(2) + cValToChar(nLoop) + Space(2) + Replicate("=", 15))

        //Valores do JSON
        ConOut("id = " + cValToChar(jJSON[nLoop]["id"]))
        ConOut("ativo = " + cValToChar(jJSON[nLoop]["ativo"]))
        ConOut("codigo = " + jJSON[nLoop]["codigo"])
        ConOut("nome_comercial = " + jJSON[nLoop]["nome_comercial"])
    next
else
    //Em caso de erros do parser, exibe os mesmos no console
    ConOut("Erro no parser do JSON:", cError)
endif

return nil

Boa noite! Obrigado pelos retornos, mas nem um dos dois funcionou para mim, olha qual foi o retorno:

… cRetorno := oRestClient:GetResult()
ConOut(cRetorno)
jJSON:FromJson(cRetorno)
ConOut(jJSON)
If Empty(cError)
for nLoop := 1 to Len(jJSON) …

O meu “ConOut(cRetorno)” = [{“id”:30,“ativo”:true,“codigo”:“000001”,“nome_comercial”:“BEBEDOURO ROSCAVEL”}]

e o “ConOut(jJSON)” = J

Ai me pergunto, poderia ser alguma coisa com a versão do meu binário?

  • TOTVS - Build 7.00.131227A - Oct 8 2019 - 19:37:11 NG
  • SVN Revision: 11258 - 24470 - 2213
  • Build Version: 13.2.3.48

Boa noite novamente! Realmente acredito ser algo com o meu ambiente, pois usando o exemplo acima, ou os meus fontes, após o fromJSON o objeto tem o valor de J, achei esse fórum aqui, Depuração de Objetos JsonObject · Issue #86 · totvs/advpl-vscode · GitHub, mas não mais que isso sobre esse “problema”.

Obs. tentei com o binário 13.2.3.48 e o 13.2.3.36, e nos dois acontece a mesma coisa.

Bom dia, eu não utilizo o binário NG já há alguns meses, recomendo fortemente a utilização do Lobo Guará, você terá um bom ganho de performance, redução do tamanho do RPO entre outros benefícios.

neu_daniel, depois de executar o jJSON:fromJSON(cJSON) tente executar um varinfo(“jJSON”, jJSON) e veja o que o sistema imprime no console para saber se a montagem do objeto json está conforme você espera.

neu_daniel, conseguiu resolver o seu problema? Estou com a mesma dificuldade. Se tiro as ele consegue executar, porem meu retorno sempre manda com as e não gostaria de fazer gambiarra para retirar elas. Obrigada

Alterando um pouco a resposta do @Daniel Mendes, acredito que ficaria assim:


#include "protheus.ch"

user function JsonObj()
local cJSON as char
local cError as char
local nLoop as numeric
local jJSON

//JSON que será utilizado, ainda em formato string
cJSON := '[{"id":30,"ativo":true,"codigo":"000001","nome_comercial":"BEBEDOURO ROSCAVEL"}]'

//Cria o objeto de parser do JSON
jJSON := JSONObject():New()

//Efetuar o parser do JSON
cError := jJSON:fromJSON(cJSON)

//Se vazio, significa que o parser ocorreu sem erros
if Empty(cError)
    ConOut("Leitura do JSON:")

    // ****************************************
    // Essa é a parte importante. Neste ponto, 
    // você precisa listar as propriedades
    // existentes no seu objeto JSON ao invés
    // de simplesmente utilizar a função Len
    // no objeto JSON.
    // ****************************************

    aNames := jJSON:GetNames()

    //Como o JSON é um array, criado um laço para a exibição de valores
    for nLoop := 1 to Len(aNames)

        cIndice := aNames[nLoop]

        ConOut("", Replicate("=", 15) + Space(2) + cValToChar(nLoop) + Space(2) + Replicate("=", 15))

        //Valores do JSON
        ConOut("id = " + cValToChar(jJSON[cIndice]["id"]))
        ConOut("ativo = " + cValToChar(jJSON[cIndice]["ativo"]))
        ConOut("codigo = " + jJSON[cIndice]["codigo"])
        ConOut("nome_comercial = " + jJSON[cIndice]["nome_comercial"])
    next
else
    //Em caso de erros do parser, exibe os mesmos no console
    ConOut("Erro no parser do JSON:", cError)
endif

return nil

Faça um teste! Com certeza funcionará para você!

O método GetNames() está disponível apenas no binário do lobo guará, então não funcionará para ele, pois ele informou que está no binário NG ainda.

Olá tudo bem ? Estava com o mesmo problema, o link abaixo detalha melhor essa situação e a solução.

https://centraldeatendimento.totvs.com/hc/pt-br/articles/360037138634-Cross-Segmento-TOTVS-Backoffice-Linha-Protheus-ADVPL-Classe-JsonObject-