CodeGym /Cursos /JAVA 25 SELF /Validação de JSON: JSON Schema, erros de validação

Validação de JSON: JSON Schema, erros de validação

JAVA 25 SELF
Nível 46 , Lição 4
Disponível

1. Por que precisamos de validação de JSON

Vamos imaginar: você escreveu a classe User e espera que sempre chegue um JSON assim:

{
  "id": 42,
  "name": "Alice",
  "email": "alice@example.com"
}

Mas, de repente, chega isto:

{
  "id": "quarenta e dois",
  "name": 123,
  "email": null,
  "admin": true
}

Ou até:

{
  "username": "Alice"
}

No melhor cenário, Jackson ou Gson lançarão uma exceção ao tentar desserializar. No pior — atribuirão silenciosamente valores padrão aos campos, e sua regra de negócio começará a se comportar de forma incorreta. E se for a configuração do seu serviço — você pode acabar com bugs “divertidos” que toda a equipe terá de caçar depois.

Validação de JSON é o processo de verificar se a estrutura, os tipos e os valores dos dados em JSON atendem a regras definidas (um esquema). É como um controle de passaporte para dados: se não passar — não embarca!

2. JSON Schema: o que é e como se parece

No mundo do JSON existe um padrão oficial para descrever a estrutura dos dados — JSON Schema. É como um “checklist” para verificar se o JSON atende aos requisitos do seu programa.

JSON Schema também é JSON, só que com chaves especiais: type, properties, required e assim por diante.

Exemplo de esquema mais simples

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id":    { "type": "integer" },
    "name":  { "type": "string" },
    "email": { "type": "string", "format": "email" }
  },
  "required": ["id", "name"]
}

O que está acontecendo aqui:

  • Espera-se um objeto (type: "object").
  • O objeto pode ter os campos "id", "name", "email" (descritos em properties).
  • "id" — deve ser um número inteiro (type: "integer").
  • "name" — deve ser uma string (type: "string").
  • "email" — string que pareça um e-mail (chave format com valor "email").
  • required indica a lista de campos obrigatórios: "id" e "name".

Se o JSON não tiver "id" ou "name", ou se o tipo for incorreto — a validação falhará.

Resumo das capacidades do JSON Schema

  • Indicação do tipo (type: "string", "integer", "array", "object", "boolean", "null").
  • Descrição de objetos e arrays aninhados (properties, items).
  • Campos obrigatórios e opcionais (required).
  • Verificação do tamanho de strings, intervalo de números (minLength, maximum etc.).
  • Verificação de formato (format: "email", "date", "uri" etc.).
  • Enums (enum: lista de valores permitidos).
  • Expressões regulares para strings (pattern).
  • Condições avançadas: anyOf, oneOf, allOf (para casos avançados).

3. Validação de JSON em Java: visão geral de bibliotecas

A biblioteca padrão do Java não inclui validação de JSON por esquema. Mas existem bibliotecas de terceiros populares. Aqui estão as mais conhecidas:

  • everit-org/json-schema — simples, gratuita e popular.
  • networknt/json-schema-validator — rápida, suporta os padrões mais recentes.
  • Jackson-module-jsonSchema — extensão para Jackson (mas não oferece validação completa).
  • Justify, Java JSON Tools — há outras, mas são menos comuns.

Nesta aula, vamos ver everit-org/json-schema — ela é simples para iniciantes, bem documentada e não exige malabarismo.

Instalação do everit-org/json-schema

Adicione a dependência ao seu pom.xml (Maven):

<dependency>
  <groupId>org.everit.json</groupId>
  <artifactId>org.everit.json.schema</artifactId>
  <version>1.14.2</version>
</dependency>

Ou via Gradle:

implementation 'org.everit.json:org.everit.json.schema:1.14.2'

4. Exemplo: validar JSON com esquema (passo a passo)

Vamos validar JSON na prática. Para isso, precisamos do esquema, do JSON e de um pouco de código.

Exemplo de esquema (user-schema.json):

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id":    { "type": "integer" },
    "name":  { "type": "string", "minLength": 2, "maxLength": 30 },
    "email": { "type": "string", "format": "email" }
  },
  "required": ["id", "name"]
}

Exemplo de JSON válido (user.json):

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com"
}

Exemplo de JSON inválido:

{
  "id": "um",
  "name": "",
  "email": "not-an-email"
}

Código para validação

import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONException;
import org.json.JSONTokener;
import org.everit.json.schema.ValidationException;

import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonValidationExample {
    public static void main(String[] args) throws Exception {
        // Carregando o esquema do arquivo
        String schemaString = new String(Files.readAllBytes(Paths.get("user-schema.json")));
        JSONObject rawSchema = new JSONObject(new JSONTokener(schemaString));
        Schema schema = SchemaLoader.load(rawSchema);

        // Carregando o JSON para verificação
        String jsonString = new String(Files.readAllBytes(Paths.get("user.json")));
        JSONObject json = new JSONObject(new JSONTokener(jsonString));

        // Validação
        try {
            schema.validate(json); // Se estiver tudo certo — nada acontecerá
            System.out.println("JSON é válido!");
        } catch (ValidationException e) {
            System.out.println("JSON NÃO é válido!");
            for (String msg : e.getAllMessages()) {
                System.out.println("Erro: " + msg);
            }
        }
    }
}

Comentários ao código:

  • Usa-se a classe Schema e o carregador SchemaLoader.load(...).
  • O método schema.validate(json) lança uma exceção se não corresponder ao esquema.
  • No bloco catch é possível obter todos os erros via getAllMessages().

Como integrar isso no aplicativo?

Normalmente, o esquema fica em recursos (por exemplo, na pasta resources). Você valida o JSON antes de desserializar para um objeto Java. Se estiver tudo certo — desserialize e prossiga.

5. Tratamento de erros de validação

Quando o JSON não passa na verificação, a biblioteca lança a exceção ValidationException. A mensagem contém uma lista de erros: o que exatamente não está de acordo com o esquema.

Exemplo de saída de erros

Para o JSON inválido acima, a saída será algo assim:

JSON NÃO é válido!
Erro: #: required key [id] not found
Erro: #/name: expected minLength: 2, actual: 0
Erro: #/email: String [not-an-email] is invalid against requested format [email]
Erro: #/id: expected type: Integer, found: String

Como interpretar os erros:

  • required key [id] not found — campo obrigatório ausente.
  • expected minLength: 2, actual: 0 — string curta demais.
  • String [...] is invalid against requested format [email] — e-mail inválido.
  • expected type: Integer, found: String — tipo não confere.

Importante! As mensagens podem estar em inglês, mas são bem claras.

Como mostrar os erros ao usuário?

Você pode reunir os erros em uma lista e retorná-los ao usuário, por exemplo, em um REST API ou GUI. Isso permite entender rapidamente o que há de errado com os dados de entrada.

6. Prática: validação de um array de objetos

É comum precisar validar não um único objeto, mas um array:

[
  { "id": 1, "name": "Alice", "email": "alice@example.com" },
  { "id": 2, "name": "Bob" },
  { "id": "o que é isso?", "name": 123, "email": "not-an-email" }
]

Esquema:

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id":    { "type": "integer" },
      "name":  { "type": "string", "minLength": 2, "maxLength": 30 },
      "email": { "type": "string", "format": "email" }
    },
    "required": ["id", "name"]
  }
}

A validação funciona da mesma forma, apenas passando um array como JSON. Os erros conterão os índices dos elementos onde algo está errado (por exemplo, [#/2/id]).

7. Erros típicos na validação de JSON

Erro nº 1: tipo de dado incompatível. Muito frequentemente chega uma string em vez de número ("id": "123"), enquanto o esquema espera um integer. A validação falhará. Se você não controla a fonte de dados — ajuste o esquema ou converta os dados antes.

Erro nº 2: ausência de campos obrigatórios. Se no esquema o campo for obrigatório ("required": ["id","name"]) e ele não existir no JSON — você terá um erro. Às vezes isso surpreende: o front-end esqueceu de enviar o campo ou a API mudou.

Erro nº 3: campos extra no JSON. Por padrão, o JSON Schema permite campos extras. Se você quer um esquema estrito, não esqueça de adicionar "additionalProperties": false. Sem isso, o JSON pode conter quaisquer campos “sobrando”.

Erro nº 4: versão do esquema ou sintaxe incorretas. Se você usar chaves que não existem na versão do esquema que escolheu ou cometer typos, o validador não conseguirá carregar o esquema. Verifique o esquema em https://www.jsonschemavalidator.net/ ou serviços semelhantes.

Erro nº 5: tratamento de erros ruim. Se você apenas capturar a primeira exceção e não mostrar detalhes ao usuário, será difícil entender o que há de errado com o JSON. Use getAllMessages() para exibir todos os erros.

Erro nº 6: formatos rígidos demais. A verificação de "format": "email" ou "date" pode ser bastante superficial. Se você precisa de validação estrita, use verificações adicionais no código.

1
Pesquisa/teste
Serialização de JSON, nível 46, lição 4
Indisponível
Serialização de JSON
Serialização de JSON
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION