【问题标题】:Jackson and GSON unusable with Google App EngineJackson 和 GSON 无法与 Google App Engine 一起使用
【发布时间】:2013-12-20 19:34:59
【问题描述】:

一段时间以来,我一直在寻找解决此问题的答案/解决方法。

问题是在将 Json 字符串转换为 Java 对象时,会抛出异常,如“在私有 java.lang.Throwable java.lang.Throwable.cause 上不允许反射”。

我知道 GAE 是一个沙盒环境,因此我无法尽可能多地突破界限,但我希望不必求助于编写自己的反序列化器。

原因是我使用的数据类型非常复杂,因此编写自己的反序列化器不仅会耗费时间,而且会破坏使用 Jackson 和 GSON 等框架的意义。

以下是 Jackson 和 GSON 的代码示例,这两种实现都在本地工作(未经过沙箱处理),而在部署到 GAE 时则不工作。 杰克逊:

public class JsonConverterJackson {

    private static final ObjectMapper mapper = new ObjectMapper().setVisibility(PropertyAccessor.FIELD, Visibility.NON_PRIVATE);

    /** This method deserializes the specified Json into an object of the specified class.
     * @throws IOException 
     * @throws JsonMappingException 
     * @throws JsonParseException 
     *
     */
    public static <T> T convertFromJson(String toConvert, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException{
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper.readValue(toConvert, clazz);
    }


    /**
     * This method serializes the specified object into its equivalent Json representation.
     * @throws JsonProcessingException 
     */
    public static String convertToJson(Object toConvert) throws JsonProcessingException{
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper.writeValueAsString(toConvert);
    }

GSON:

public class JsonConverter {
private static final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
//private static final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PRIVATE).setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();

/** This method deserializes the specified Json into an object of the specified class.
 *
 */
public static <T> T convertFromJson(String toConvert, Class<T> clazz){
    return gson.fromJson(toConvert, clazz);
}

/**
 * This method serializes the specified object into its equivalent Json representation.
 */
public static String convertToJson(Object toConvert){
    return gson.toJson(toConvert);
}

Jackson 的异常详情: 以下是 Jackson 的异常日志:

com.fasterxml.jackson.databind.JsonMappingException: Can not access private java.lang.Throwable java.lang.Throwable.cause (from class java.lang.Throwable; failed to set access: java.lang.IllegalAccessException: Reflection is not allowed on private java.lang.Throwable java.lang.Throwable.cause

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not access private java.lang.Throwable java.lang.Throwable.cause (from class java.lang.Throwable; failed to set access: java.lang.IllegalAccessException: Reflection is not allowed on private java.lang.Throwable java.lang.Throwable.cause
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:272)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:247)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:146)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:

欢迎提出任何建议。

【问题讨论】:

  • 请发布确切的异常及其堆栈跟踪。
  • 该错误消息很奇怪..据我所知,它说“无法写入Throwable 的私有字段cause”。您是否不小心在 POJO 中有 Throwable/Exception 字段?
  • 您是否要序列化Throwable?为什么?
  • 我的 POJO 中返回的对象之一实际上是自定义异常。您认为这会导致问题吗?该字段在所有情况下都为空,除非在第三方来源的 Json 字符串中返回异常。
  • 也许我上面的评论解释了我在这里遇到问题的原因。如果是这种情况,则意味着您可以序列化 Throwable,而不是在 GAE 上。

标签: java google-app-engine reflection jackson gson


【解决方案1】:

从 POJO 中删除 Custom Exception 字段起到了作用。 序列化为 Throwable 似乎是使用 GAE 安全管理器的限制。 您无法访问除您自己之外的任何对象的私有字段。

【讨论】:

    猜你喜欢
    • 2021-11-06
    • 2011-11-15
    • 2011-08-15
    • 2013-10-27
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    相关资源
    最近更新 更多