【问题标题】:Jackson 2 and Spring Autowired beanJackson 2 和 Spring Autowired bean
【发布时间】:2015-03-31 15:00:56
【问题描述】:

我遇到了我的 User 对象的 Jackson 序列化问题。 有一些带有 getter 和 setter 的私有字段。当我做这样的事情时一切正常:

public String json() {
   MyUser user = new MyUser();
   user.setUsername("myName");

   return mapper.writeValueAsString(user); // Valid JSON
}

但我想用 Spring Framework 自动装配 User 对象:

@Autowired
private MyUser user;

public String json() {
    System.out.println(user.getUsername()); // Property set before and it works
    return mapper.writeValueAsString(user); // Error
}

这行不通。我有一个错误:

com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.apache.juli.OneLineFormatter and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.piggymetrics.classes.PiggyUser$$EnhancerBySpringCGLIB$$5f23855e["targetSource"]->org.springframework.aop.target.SimpleBeanTargetSource["beanFactory"]->org.springframework.beans.factory.support.DefaultListableBeanFactory["parentBeanFactory"]->org.springframework.beans.factory.support.DefaultListableBeanFactory["beanClassLoader"]->org.apache.catalina.loader.WebappClassLoader["resources"]->org.apache.catalina.webresources.StandardRoot["context"]->org.apache.catalina.core.StandardContext["logger"]->org.apache.juli.logging.DirectJDKLog["logger"]->java.util.logging.Logger["parent"]->java.util.logging.Logger["handlers"]->org.apache.juli.AsyncFileHandler["formatter"])
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:26)

当我试图忽略这些未知错误时

mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

我得到了一个无限递归:

com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: org.apache.catalina.core.StandardEngineValve["container"]->org.apache.catalina.core.StandardEngine["pipeline"]->org.apache.catalina.core.StandardPipeline["basic"]->org.apache.catalina.core.StandardEngineValve["container"]
...

看起来 Spring 对自动装配的 MyUser 实例做错了什么,因此 Jackson 无法对其进行序列化。

有办法解决吗?

更新

MyUser 类非常简单:

package com.metrics.classes;

import com.metrics.classes.interfaces.User;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyUser implements User {

    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

【问题讨论】:

  • 您的用户是否包含引用该用户的字段?
  • 请分享您的MyUser 课程
  • 我已经用 MyUser 类更新了我的问题。谢谢。

标签: java json spring spring-mvc jackson


【解决方案1】:

由于您使用 MyUser 作为 Spring 托管 bean,因此 Spring 将您的对象包装到代理中 - 因此,当您调用 mapper.writeValueAsString(user); 时,您实际上是在传递代理作为参数。所述代理包含一些属性,映射器无法序列化。

您可以尝试在序列化之前应用过滤器以仅包含您需要的属性:

ObjectMapper mapper = new ObjectMapper();
SimpleFilterProvider simpleFilterProvider = new SimpleFilterProvider()
    .addFilter("myUser", simpleBeanPropertyFilter.filterOutAllExcept("username"));

mapper.setFilters(filterProvider);
return mapper.writeValueAsString(user);

【讨论】:

  • 但是,如果我在 MyUser 类中有 20 个字段怎么办?这些字段可能会在以后修改。是否有另一种方法来序列化 Autowired POJO?
  • @silent-box 可能有其他方法 - 但我还没有遇到这种情况,所以我不能确定。可能有一些方法可以告诉映射器将传递的对象视为超类 - 即MyUser,或一些具有类似含义的@Json...注释。
  • Ок. Спасибо еще раз :)
  • @silent-box не за что)
【解决方案2】:

UnknownSerializer 类中抛出此异常。这是引发异常的确切代码:

throw new JsonMappingException("No serializer found for class "+value.getClass().getName()
   +" and no properties discovered to create BeanSerializer 
   (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )");

错误消息附加了它无法序列化的类的名称。在您的情况下,根据错误消息,问题出在org.apache.juli.OneLineFormatter 类。因此,MyUser 类没有问题。

现在开始出现此错误的原因是,在序列化具有所有字段私有的实体时会引发此错误。在org.apache.juli.OneLineFormatter 类中,所有字段都是私有的,没有任何公共的 getter 和 setter 方法。

【讨论】:

  • 我认为从他的描述中可以清楚地看出他的领域有公共的 getter 和 setter。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 1970-01-01
  • 2012-11-03
  • 2020-11-04
  • 2017-05-23
  • 1970-01-01
相关资源
最近更新 更多