Gson 使用补遗--adapter使用

本文介绍了在使用Gson时遇到的Map泛型转换问题,Gson将JSON字符串转换为Map时会将String变为Object。为了解决这个问题,文章提供了一个基于Gson封装org.json.JSONObject的例子,展示了如何创建自定义Adapter来处理JSONObject,包括数据区域和返回状态的字段。

由于gson在转换Map泛型时无法deserializer回来.比如Map<String,String>,它将json string重新转换为Map时会将里面的string变成父类对象Object,所以我们需要重新将adapter进行封装或者添加自己的adapter.

由于工作原因,我需要接受和发送JSONObject,所以我给出的是基于gson中封装org.json.JSONObject例子.有兴趣的可以看下JSONObject,他其实就是MAP的封装实现.

例子如下:

<Bean>

------------------------ 華麗的分割線------------------------------

package org.seay.bean;

 

import org.json.JSONObject;

 

/**

 * @author Sheng Yan

 *

 */

public class FirstEndBean{

 

    /**

     * Data area.The key is upper word.

     */

    private JSONObject data;

    /**

     * return status

     */

    private String successful;

 

    /**

     * return error code and message

     */

    private String error;

 

    public JSONObject getData() {

        return data;

    }

 

    public void setData(JSONObject data) {

        this.data = data;

    }

 

    public String getSuccessful() {

        return successful;

    }

 

    public void setSuccessful(String successful) {

        this.successful = successful;

    }

 

    @Override

    public String toString() {

        return "FirstEndBean [data=" + data + ", successful=" + successful + "]";

    }

}

 

<JSONConvert>
------------------------ 華麗的分割線------------------------------
package org.seaya.common;
import java.lang.reflect.Type;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
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.reflect.TypeToken;
public class JsonConvert {
    /**
     * FirstEndBean create logger object.
     */
    private static final Logger logger = Logger.getLogger(JsonConvert.class);
    /**
     * Covert Json String to {@code FirstEndBean}
     * 
     * @param json
     *            It's Json String
     * @return {@code FirstEndBean} Covert result
     */
    public static FirstEndBean convertJsonToFirstEndBean(String json) {
        Type type = new TypeToken<FirstEndBean>() {
        }.getType();
        Gson gson = getGson();
        try {
            FirstEndBean tBean = gson.fromJson(json, type);
            if (logger.isDebugEnabled()) {
                logger.debug("FirstEndBean is send string: " + json);
            }
            return tBean;
        } catch (JsonParseException ex) {
            logger.error("JsonParseException: " + ex.getMessage());
            ex.printStackTrace();
        }
        return null;
    }
    /**
     * Covert {@code FirstEndBean} to Json String
     * 
     * @param firstEndBean
     *            A FirstEndBean object
     * @return {@code String} Json String
     */
    public static String convertFirstEndBeanToJson(FirstEndBean firstEndBean) {
        Type type = new TypeToken<FirstEndBean>(){}.getType();
        Gson gson = getGson();
        String jsonString = gson.toJson(firstEndBean, type);
        if (logger.isDebugEnabled()) {
            logger.debug("FirstEndBean is send string: " + jsonString);
        }
        return jsonString;
    }
    /**
     * JSONObject Type Adapter will serializer JSONOjbect to String 
     * and deserializer String to JSONOjbect
     */
    static class JSONObjectTypeAdapter implements JsonSerializer<JSONObject>,
            JsonDeserializer<JSONObject>, InstanceCreator<JSONObject> {
        public JsonElement serialize(JSONObject src, Type typeOfSrc,
                JsonSerializationContext context) {
              return new JsonPrimitive(src.toString());
        }
        public JSONObject deserialize(JsonElement json, Type typeOfT,
                JsonDeserializationContext context) throws JsonParseException {
              try {
                return new JSONObject(json.getAsString());
            } catch (JSONException e) {
                return new JSONObject();
            }
        }
        public JSONObject createInstance(Type type) {
            return new JSONObject();
        }
        @Override
        public String toString() {
            return JSONObjectTypeAdapter.class.getSimpleName();
        }
    }
    
    /**
     * Get Gson Object
     */
    public static Gson getGson() {
        GsonBuilder builder = new GsonBuilder();
        Type type = new TypeToken<JSONObject>(){}.getType();
        return builder.registerTypeAdapter(type, new JSONObjectTypeAdapter()).create();
    }
    public static void main(String[] args) throws JSONException {
        JsonConvert convert = new JsonConvert();
        FirstEndBean sendbean = Simulate.register();
        convert.test(sendbean);
    }
    
    private void test(final FirstEndBean sendbean) {
        String jsonString = JsonConvert.convertFirstEndBeanToJson(sendbean);
//      System.out.println("sendbean: " + sendbean);
        System.out.println("sendbean jsonString: " + jsonString);
//      FirstEndBean resultbean =
//      JsonConvert.convertJsonToFirstEndBean(jsonString);
//      System.out.println("resultbean: " + resultbean);
    }
}
你也可以参看 http://www.javaeye.com/problems/34908.里面也提到了该问题.

 

包含以下java源文件: com.google.gson.DefaultDateTypeAdapter.class com.google.gson.ExclusionStrategy.class com.google.gson.FieldAttributes.class com.google.gson.FieldNamingPolicy.class com.google.gson.FieldNamingStrategy.class com.google.gson.Gson.class com.google.gson.GsonBuilder.class com.google.gson.InstanceCreator.class com.google.gson.JsonArray.class com.google.gson.JsonDeserializationContext.class com.google.gson.JsonDeserializer.class com.google.gson.JsonElement.class com.google.gson.JsonIOException.class com.google.gson.JsonNull.class com.google.gson.JsonObject.class com.google.gson.JsonParseException.class com.google.gson.JsonParser.class com.google.gson.JsonPrimitive.class com.google.gson.JsonSerializationContext.class com.google.gson.JsonSerializer.class com.google.gson.JsonStreamParser.class com.google.gson.JsonSyntaxException.class com.google.gson.LongSerializationPolicy.class com.google.gson.TreeTypeAdapter.class com.google.gson.TypeAdapter.class com.google.gson.TypeAdapterFactory.class com.google.gson.annotations.Expose.class com.google.gson.annotations.SerializedName.class com.google.gson.annotations.Since.class com.google.gson.annotations.Until.class com.google.gson.internal.ConstructorConstructor.class com.google.gson.internal.Excluder.class com.google.gson.internal.JsonReaderInternalAccess.class com.google.gson.internal.LazilyParsedNumber.class com.google.gson.internal.LinkedTreeMap.class com.google.gson.internal.ObjectConstructor.class com.google.gson.internal.Primitives.class com.google.gson.internal.Streams.class com.google.gson.internal.UnsafeAllocator.class com.google.gson.internal.bind.ArrayTypeAdapter.class com.google.gson.internal.bind.CollectionTypeAdapterFactory.class com.google.gson.internal.bind.DateTypeAdapter.class com.google.gson.internal.bind.JsonTreeReader.class com.google.gson.internal.bind.JsonTreeWriter.class com.google.gson.internal.bind.MapTypeAdapterFactory.class com.google.gson.internal.bind.ObjectTypeAdapter.class com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.class com.google.gson.internal.bind.SqlDateTypeAdapter.class com.google.gson.internal.bind.TimeTypeAdapter.class com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.class com.google.gson.internal.bind.TypeAdapters.class com.google.gson.reflect.TypeToken.class com.google.gson.stream.JsonReader.class com.google.gson.stream.JsonScope.class com.google.gson.stream.JsonToken.class com.google.gson.stream.JsonWriter.class com.google.gson.stream.MalformedJsonException.class
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值