代码之家  ›  专栏  ›  技术社区  ›  GrooveRage

jackson反序列化,2个字段自引用同一类(自引用循环)

  •  0
  • GrooveRage  · 技术社区  · 6 年前

    我有以下类引用自身:

    @Entity
    @Inheritance(strategy = TABLE_PER_CLASS)
    //@JsonIdentityInfo(property="rowId", generator = ObjectIdGenerators.PropertyGenerator.class)
    public abstract class AbstractEntity implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 568799551343430329L;
    
        @OneToOne(optional=false, fetch=FetchType.EAGER)
        @JoinColumn(name="createdBy")
        protected User createdBy;
        @OneToOne(optional=false, fetch=FetchType.EAGER)
        @JoinColumn(name="lastUpdatedBy")
        protected User lastUpdatedBy;
    
        @Id
        @GeneratedValue(strategy = GenerationType.TABLE)
        @Column(unique = true, nullable = false, updatable = false, length = 7)
        private Integer rowId;
    
        public User getCreatedBy() {
            return this.createdBy;
        }
    
        public void setCreatedBy(User createdBy) {
            this.createdBy = createdBy;
        }
    
        public User getLastUpdatedBy() {
            return this.lastUpdatedBy;
        }
    
        public void setLastUpdatedBy(User lastUpdatedBy) {
            this.lastUpdatedBy = lastUpdatedBy;
        }
    
        public Integer getRowId() {
            return this.rowId;
        }
    
        public void setRowId(Integer RowId) {
            this.rowId = RowId;
        }
    
        public String toString() {
            return "[Id]:" + this.rowId + " - [CreatedBy]:" + this.createdBy;
        }
    }
    

    然后我有一节课 User 扩展此类和RepositoryUser界面:

    public interface RepositoryUser extends CrudRepository<User, Integer> {
    
    }
    

    和控制器:

    @Controller
    @RequestMapping(path = "/user")
    public class ServiceUser {
        @Autowired
        private RepositoryUser repositoryUser;
    
        @GetMapping(path="/all", produces = "application/json; charset=UTF-8", headers = "Accept=application/json")
        public @ResponseBody Iterable<User> getAllUsers() {
            return repositoryUser.findAll();
        }
    
        @PostMapping(path="/add", consumes="application/json")
        public @ResponseBody User createOneUser(@RequestBody User user) {
            System.out.println(user);
            return repositoryUser.save(user);
        }
    }
    

    我的问题是,我在同一个类中两次引用用户(createdby和lastupdedby),要么我尝试了JSonIdentityInfo、Jsonmanaged和jsonback,但什么都不起作用。正确地

    我需要能够 { 用户1数据,包括创建人和上次更新人 用户2数据,包括创建人和上次更新人 }

    当我添加时,我需要设置创建记录的用户。

    你能帮帮我吗?

    谢谢!

    1 回复  |  直到 6 年前
        1
  •  2
  •   Tinus Jackson    6 年前

    您可以使用StdSerializer编写/尝试自定义序列化程序。

    CustomJsonSerializer示例。注意:没有运行代码。

    public class CustomJsonSerializer extends StdSerializer<AbstractEntity> {
    
      public CustomJsonSerializer() {
        this(null);
      }
    
      public CustomJsonSerializer(Class<AbstractEntity> t) {
        super(t);
      }
    
      @Override
      public void serialize(AbstractEntity value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
        Field[] fields = value.getClass().getDeclaredFields();
        jgen.writeStartObject();
    
        for (Field field : fields) {
            field.setAccessible(true);
    
           try {
               // Do the proper field mapping for field types . Object type example
               jgen.writeObjectField(field.getName(), field.get(value));
    
            } catch (Exception e) {
              // catch error
            }
        }
    
        jgen.writeEndObject();
      }
    }
    

    然后在Rest方法中使用@JsonSerialize

    @JsonSerialize(using = CustomJsonSerializer.class)
    @GetMapping(path="/all", produces = "application/json; charset=UTF-8", headers = "Accept=application/json")
    public @ResponseBody Iterable<User> getAllUsers() {
        return repositoryUser.findAll();
    }
    

    请看 Custom Serializer StdSerializer

    可能的不同解决方案 jackson-bidirectional infinite-recursion