当前位置: 首页 > 知识库问答 >
问题:

Jackson-不要序列化懒惰对象

有权
2023-03-14

我有一个实体:

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column
    private String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
    private List<Genre> genre;

}

然后我有一个控制器,其目的是检索书籍,我的问题是,我的控制器的json响应中包含了流派字段。有没有办法排除jackson序列化对象时延迟加载的字段?

这是我的ObjectMapper的配置:

Hibernate4Module hm = new Hibernate4Module();
hm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false);
registerModule(hm);
configure(SerializationFeature.INDENT_OUTPUT, true);

谢谢

我不能将其标记为JsonIgnore,因为它将永远脱离序列化框。有时我需要检索书籍的体裁,到那时,我将在查询中使用“fetch join”,这样它就不会为空。

共有3个答案

索锐藻
2023-03-14

您可以使用Jackson的JSON过滤器功能:

@Entity
@JsonFilter("Book") 
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column
    private String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
    private List<Genre> genre;
} 

@Entity
@JsonFilter("Genre")
public class Genre {
   ...
}

然后在控制器中指定要过滤的内容:

@Controller
public class BookController {
      @Autowired
      private ObjectMapper objectMapper;

      @Autowird
      private BookRepository bookRepository;
      
       @RequestMapping(value = "/book", method = RequestMethod.GET, produces =  "application/json")
       @ResponseBody
       public ResponseEntity<String> getBooks() {

          final List<Book> books = booksRepository.findAll();
          final SimpleFilterProvider filter = new SimpleFilterProvider();
          filter.addFilter("Book", SimpleBeanPropertyFilter.serializeAllExcept("genre");
          return new ResponseEntity<>(objectMapper.writer(filter).writeValueAsString(books), HttpStatus.OK)
       }
      
}

这样,您可以控制何时要在运行时过滤惰性关系

朱起运
2023-03-14

默认情况下,您可以使用Spring配置禁用强制延迟加载!

@Configuration
public class JacksonConfig {
    
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        Hibernate5Module hibernate5Module = new Hibernate5Module();
        hibernate5Module.configure(Feature.FORCE_LAZY_LOADING, false);
        // Enable below line to switch lazy loaded json from null to a blank object!
        //hibernate5Module.configure(Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
        mapper.registerModule(hibernate5Module);
        return mapper;
    }
}
夔庆
2023-03-14

您可以使用Jackson注释来完成此操作。

根据最新版本的javadoc(现在是2.4),如果字段值为空或空,您可以使用简单的注释指定是否包含带注释的属性。

默认情况下,它是JsonInclude。包括总是,这意味着即使您的延迟未加载值为null,Jackson也会包含该属性。

指定不包含空值或空值可以显着减少JSON响应的大小,并包含所有好处。

如果要更改此行为,可以在类级别或单个属性/getterMethod级别添加注释。

如果为空,请尝试将以下批注添加到不希望包含的字段中:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private List<Genre> genre;
 类似资料:
  • 问题内容: 我有一个实体: 然后我有一个控制器,其目的是检索书籍,我的问题是,流派字段包含在控制器的json响应中。有什么办法可以排除杰克逊序列化对象时延迟加载的那些字段? 这是我的ObjectMapper的配置: 谢谢! 我无法将其标记为JsonIgnore,因为它将永远在序列化框中。有时候,我将需要随书一起检索体裁,到那时,我将在查询中使用“获取联接”,因此它不会为null。 问题答案: 你可

  • 问题内容: 我有一个实体: 然后我有一个控制器,其目的是检索书籍,我的问题是,流派字段包含在控制器的json响应中。有什么办法可以排除杰克逊序列化对象时延迟加载的那些字段? 这是我的ObjectMapper的配置: 谢谢! 我不能将其标记为JsonIgnore,因为它将永远在序列化框中。有时候,我将需要随书一起检索体裁,然后在查询中使用“获取联接”,因此它不会为null。 问题答案: 您可以使用J

  • 主要内容:1 编写核心类,2 运行测试本文讲解如何将一个Java对象序列化为一个json文件,然后读取该json文件读取回对象。在下面的示例中,我们创建Student类。使用Jackson存储到一个student.json文件,该文件拥有Student对象的JSON表示形式。 1 编写核心类 MainApp: 2 运行测试

  • 我有一个简单的控制器返回一个用户对象,这个用户有一个属性坐标,它具有hibernate属性FetchType.lazy。 当我尝试获取这个用户时,我总是必须加载所有坐标来获取用户对象,否则当Jackson尝试序列化用户时抛出异常: 和控制器: 有办法告诉Jackson不要连载未蚀刻的对象?我一直在寻找3年前发布的实现Jackson-Hibernate-Module的其他答案。但也许可以通过杰克逊的

  • 问题内容: 我想创建自己的集合,该集合具有python list的所有属性,并且还知道如何将自身保存到数据库中或从数据库中加载。我也想使负载隐式和惰性,因为在列表创建时它不会发生,而是等到第一次使用时才发生。 有没有一种单一的方法,我可以覆盖上加载任何列表属性(如第一次使用清单,,而不必重写他们… …等)? 问题答案: 不,没有。

  • 问题内容: 创建单例的模式似乎是这样的: 但是我的问题是,如果Singleton构造函数执行的不是单元测试友好的操作,例如如何调用外部服务,jndi查找等,您如何使用这样的类进行单元化? 我想我可以像这样重构它: 现在的问题是,仅出于单元可测试性,我已强制将getInstance同步,因此仅出于测试方面,它将对实际应用程序产生负面影响。有没有解决的办法,由于Java中双重锁定模式的破坏性,似乎其他