jackson - do not serialize lazy objects
我有一个实体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
然后我有一个控制器,其目的是检索书籍,我的问题是,类型字段被包含在我的控制器的json响应中。 任何方式我可以排除那些杰克逊序列化对象时延迟加载的字段?
这是我的ObjectMapper的配置:
1 2 3 4 | Hibernate4Module hm = new Hibernate4Module(); hm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false); registerModule(hm); configure(SerializationFeature.INDENT_OUTPUT, true); |
谢谢!
我无法将其标记为JsonIgnore,因为它将永远不在序列化框中。 有时候我需要随书检索这些类型,然后我会在查询中使用"fetch join",因此它不会为null。
您可以使用Jackson
根据最新版本的javadoc(现在为2.4),如果字段值为null或为空,则可以使用简单注释指定是否包含带注释的属性。
默认情况下,它是
指定不包含空值或空值可以显着减小JSON响应的大小,包括所有好处..
如果要更改此行为,可以在类级别或单个属性/ getterMethod级别添加注释。
如果为空,请尝试将以下注释添加到您不想包含的字段中:
1 2 3 | @JsonInclude(JsonInclude.Include.NON_EMPTY) @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL) private List<Genre> genre; |
您可以使用Jackson的JSON过滤器功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @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中指定要过滤的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @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", SimpleFilterProvider.serializeAllExcept("Genre"); return new ResponseEntity<>(objectMapper.writer(filter).writeValueAsString(books), HttpStatus.OK) } } |
通过这种方式,您可以控制何时在运行时过滤延迟关系
也许这与延迟加载的已知问题有关。
我不使用jackson-datatype-hibernate,但是我为解决同样的问题所做的是通过使用DTO而不是直接序列化Hibernate对象来获取图片中的持久集合。像Dozer这样的工具可以帮助你解决这个问题。或者,我写了一个小实用程序来做这样的映射。
如果您只想试验DTO的外观,可以使用常规的空集合替换已卸载的持久集合,例如books.setGenre(new ArrayList <>());不幸的是,我不知道是否有一种方法来判断是否已加载延迟加载的对象,因此您无法自动进行此重新分配。您需要根据具体情况确定替换持久性集合的位置。