yunlian0621 阅读(207) 评论(0)

开发环境:Struts2+Hibernate4+Spring4+MySQL5+Tomcat7+JDK1.8+Maven

在实现关系映射的时候,我采用的是注解形式实现的,但是,我想在写json数据的时候忽略某些映射出来的数据,完整的代码如下:

 

package com.value.yun.modules.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.value.yun.common.base.BaseDataEntity;
import org.hibernate.annotations.*;
import org.hibernate.annotations.Cache;

import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.Date;
import java.util.List;

/**
 * Created by 丽 on 2015/4/14.
 */
@Entity
@Table(name = "user")
@DynamicInsert
@DynamicUpdate
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@JsonIgnoreProperties(value ={"role","menuList"})
public class User extends BaseDataEntity<User>{
    /**
     * 密码
     */
    private String password;
    /**
     * 工号、学号
     */
    private String number;
    /**
     * 真实姓名
     */
    private String realName;
    /**
     * 手机
     */
    private String mobile;
    /**
     * 邮箱
     */
    private String email;
    /**
     * qq
     */
    private String qq;
    /**
     * 登陆的ip
     */
    private String loginIp;
    /**
     * 登录时间
     */
    private Date loginTime;
    /**
     * 登陆名
     */
    private String loginName;
    /**
     * 角色、类型
     */
    @JsonManagedReference
    private Role role;
	 @JsonManagedReference
    private List<Menu> menuList;
    /**
     * 验证码
     */
    @Transient
    private String verification;

    public User() {
    }

    public User(String id, String remark, int delFlag, Date createDate, Date updateDate, User createBy, User updateBy,
                String password, String number, String realName, String mobile, String email, String qq, String loginIp,
                Date loginTime, String loginName, Role role) {
        super(id, remark, delFlag, createDate, updateDate, createBy, updateBy);
        this.password = password;
        this.number = number;
        this.realName = realName;
        this.mobile = mobile;
        this.email = email;
        this.qq = qq;
        this.loginIp = loginIp;
        this.loginTime = loginTime;
        this.loginName = loginName;
        this.role = role;
    }
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }
    @Column(name = "real_name")
    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getQq() {
        return qq;
    }

    public void setQq(String qq) {
        this.qq = qq;
    }
    @Column(name = "login_ip")
    public String getLoginIp() {
        return loginIp;
    }

    public void setLoginIp(String loginIp) {
        this.loginIp = loginIp;
    }
    @Column(name = "login_time")
    public Date getLoginTime() {
        return loginTime;
    }

    public void setLoginTime(Date loginTime) {
        this.loginTime = loginTime;
    }
    @Column(name = "login_name")
    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @NotFound(action = NotFoundAction.IGNORE)
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    @ManyToMany(fetch = FetchType.EAGER)
    @Fetch(value=FetchMode.SUBSELECT)
    @NotFound(action = NotFoundAction.IGNORE)
//    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @JoinTable(name = "user_menu",joinColumns = {@JoinColumn(name = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "menu_id")})
    public List<Menu> getMenuList() {
        return menuList;
    }

    public void setMenuList(List<Menu> menuList) {
        this.menuList = menuList;
    }

    @Transient
    public boolean isAdmin(){
        return isAdmin(this.id);
    }

    @Override
    public String toString() {
        return "User{" +
                "password='" + password + '\'' +
                ", number='" + number + '\'' +
                ", realName='" + realName + '\'' +
                ", mobile='" + mobile + '\'' +
                ", email='" + email + '\'' +
                ", qq='" + qq + '\'' +
                ", loginIp='" + loginIp + '\'' +
                ", loginTime=" + loginTime +
                ", loginName='" + loginName + '\'' +
                '}';
    }

    @Transient
    public static boolean isAdmin(String id){
        return id != null && id.equals("1");
    }
    @Transient
    public String getVerification() {
        return verification;
    }
    @Transient
    public void setVerification(String verification) {
        this.verification = verification;
    }
}

 

 在上面的代码中,对于json需要忽略的属性,必须要在@JsonIgnoreProperties中指定,否则不会有有效果;

关于另外两个注解@JsonManagedReference、@JsonBackReference,具体作用如下:

(see Jira entry JACKSON-235 for more details)

Before Jackson 1.5, back references such as "parent" links from child objects, previous sibling for doubly-linked lists, and general bi-directional references for ORM-managed beans (iBatis, Hibernate) would cause serialization to failure since they are cyclic dependencies.

In Jackson 1.6 there are 2 new annotations that allow specifying relationship between 2 properties that form such bi-directional dependency so that Jackson can properly omit cycle during serialization, and re-construct during serialization.

 

New annotations

Annotations are:

  • @JsonManagedReference is the "forward" part of reference: one that gets serialized normally, and handling of which triggers back-linkage for the other reference

    • Annotated property can be a bean, array, Collection (List, Set) or Map type, and it must be a bean property (handled by a property of type serialized using BeanSerializer

  • @JsonBackReference is the "back" part of reference: it will be omitted from serialization, and re-constructed during deserialization of forward reference.

    • Annotated property must be of bean type

These annotations can be used for:

* Methods (getters and setters) * Fields

but not for types (classes) or constructor arguments.

 

Annotations take optional "name" parameter; if omitted default name is used. Name is needed to allow multiple reference pairs for one bean type.

 

上面的这段话说明,@JsonManagedReference、@JsonBackReference这两个注解是JDK1.6开始才有的,而且是针对于父子关系映射的,当然非父子关系,即普通属性也行的,但是,有这两个注解的属性,必须要在@JsonIgnoreProperties中指定才会有效。

@JsonManagedReference只适合bean 类型的属性;

@JsonManagedReference的适用范围较广:bean, array, Collection (List, Set) or Map 类型,但是,集合中的实体对象必须是实现了序列化接口的。

 @JsonManagedReference、@JsonBackReference这两个注解可以用在getters和setters方法上,也可以用在某个属性上,但是不能用在某个类上或者某个构造方法上。