Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Como Fazer uma Deserialização JSON Personalizada Usando o Vraptor

Tenho uma Dúvida Desafiadora!

No curso de REST com JAX-RS e Jersey aprendemos a Serializar e Deserializar um objeto em JSON da seguinte forma (Usando a biblioteca GSON da google)

Serialização

Gson gson = new Gson();
String stringJson = gson.toJson(objeto);

Deserialização

Gson gson = new Gson();
Objeto objeto = gson.fromJson(conteudoJson, Objeto.class);

Baseado Nisso criei um uma configuração para fazer uma Serialização e Deserialização personalizada, seguindo a documentação da google GSON em uma classe chamada, JsonConfig segue a classe:

import java.io.Writer;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.core.JsonParser;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.stream.JsonWriter;

import br.com.olimpoapi.modelo.Usuario;

public class JsonConfig {

    private static final SimpleDateFormat DATA_FORMATADA = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

    public static <T> GsonBuilder getGsonBuilder() {

        GsonBuilder builder = new GsonBuilder();

        //Define Comportamento Ao Deserializar uma Data
        builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {

            //Deserializa o Seguinte formato 07/03/2017 17:26:01 em java.util.Date
            //Exemplo de Uso: Gson gson = JsonConfig.getGsonBuilder().create(); Usuario usuario = gson.fromJson(stringJson, Usuario.class);
            @Override
            public Date deserialize(JsonElement json, Type typeOfT,
                    JsonDeserializationContext context) throws JsonParseException {

                try {
                    return DATA_FORMATADA.parse(json.getAsString()); //Retorna um Date com a data formatada
                } catch (ParseException e) {
                    return null;
                }
            }
        });

        //Define o Comportamento ao Serializar uma Data
        builder.registerTypeAdapter(Date.class, new JsonSerializer<Date>() {

            //Serializa o Formato de java.util.Date para 07/03/2017 17:26:01
            // Exemplo de Uso: Gson gson = JsonConfig.getGsonBuilder().create(); String usuariojson = gson.toJson(objetoUsuario);
            @Override
            public JsonElement serialize(Date data, Type typeOft, JsonSerializationContext context) {
                try {    
                    String datajson = DATA_FORMATADA.format(data); // converte a data em string no formato adequado            
                    return new JsonPrimitive(datajson); //tranforma a string em um tipo Json primitivo
                }catch (Exception e) {
                    return null;
                }

            }
        });

        return builder;
    }
}

Perfeito! para usar esta classe no lá no REST - JAX-RS e Jersey eu faço o seguinte

Serialização

Gson gson = JsonConfig.getGsonBuilder().create();
String stringJson = gson.toJson(objeto);

Deserialização

Gson gson = JsonConfig.getGsonBuilder().create();
Objeto objeto = gson.fromJson(conteudoJson, Objeto.class);

O problema é que com o Vraptor quando eu faço

    @Path("/")
    @Post
    @Consumes("application/json")
    public void adiciona(Objeto objeto) {

    }

Ao postar o Json O VRaptor Deserializa automaticamente o meu texto em um tipo objeto, Bom isso é Perfeito!!Porém Preciso usar minha serialização e deserialização personalizada.

como eu consigo usar o meu

Gson gson = JsonConfig.getGsonBuilder().create();

no lugar do gson default?

Pesquisei algumas coisas porém ainda não obtive êxito. Por Favor ajudem o pequeno gafanhoto aqui. Se conseguirem um exemplo de código por mais simples que seja já dá uma grande ajuda! Abraço a Todos

2 respostas
solução!

oi Thiago, tudo bem?

basta fazer com que essa usa classe que [de]serializa implemente o JsonSerializer e JsonDeserializer, passando o seu Objeto como argumento genérico.

exemplo:

@Dependent
public class ObjetoGsonConverter 
        implements JsonDeserializer<Objeto>, JsonSerializer<Objeto>{

    //...
}

você pode usar como base essa impleemntação que ensina o Gson serializar e deserializar um Calendar:

https://github.com/caelum/vraptor4/blob/60bdbaaeb9282f30f303a4e7be41b1c4bd56c64a/vraptor-core/src/main/java/br/com/caelum/vraptor/serialization/gson/CalendarGsonConverter.java

faz sentido?

Perfeito Consegui resolver criando uma classe

CustomDateGsonConverter

import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.enterprise.context.Dependent;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;

@Dependent
public class CustomDateGsonConverter implements JsonDeserializer<Date>, JsonSerializer<Date> {

    @Override public JsonElement serialize(Date date, Type typeOfSrc, JsonSerializationContext context) { 
        String dateString = getFormat().format(date); return new JsonPrimitive(dateString); 

    }

    @Override public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
        try { 
            return getFormat().parse(json.getAsString()); 
        } catch (ParseException e) { throw new JsonSyntaxException(json.getAsString(), e); } 

    }

    protected DateFormat getFormat(){ 
        return new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); 
    }

}

Muito Obrigado e um Abraço a Todos!