2014-06-07 14 views
5

Tôi gặp một số rắc rối trong servlet trong đó mọi lúc tôi thay đổi tùy chọn trong menu thả xuống, một giá trị khác sẽ được chuyển tới servlet và sau đó kết quả thành vòng lặp vô hạn. Khi tôi không thay đổi tùy chọn (không thay đổi giá trị) trong danh sách thả xuống, không có lỗi.Servlet Gson(). ToJson loop vô hạn

Đây là MyCode:

My Javascript:

<script> 

function loadStaff(){ 
//dropdown 
var positionDropDown = document.getElementById("positionsDropdown"); 
//value of the drop down 
var positionID = positionDropDown.options[positionDropDown.selectedIndex].value; 

    $.getJSON('loadStaff?positionID=' + positionID, function(data) { 
      -- no populate code yet 
}); 
} 
</script> 

AjaxServlet của tôi:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

     String userPath = request.getServletPath(); 

    if (userPath.equals("/loadStaff")) { 

     String positionID = request.getParameter("positionID"); 
     Position position = positionFacade.find(Integer.parseInt(positionID)); 
     Collection staffCollection = position.getStaffCollection(); 
     List<Staff> staffList = new ArrayList(staffCollection); 

     String staffListJson = new Gson().toJson(staffList); 
     response.setContentType("application/json"); 
     response.setCharacterEncoding("UTF-8"); 
     response.getWriter().write(staffListJson); 

    } 

} 

Khi debuggig. Các lỗi đi kèm với dòng:

String staffListJson = new Gson().toJson(staffList); 

lỗi Output:

> INFO: WebModule[null] ServletContext.log(): The server side 
> component of the HTTP Monitor has detected a 
> java.lang.StackOverflowError. This happens when there is an infinite 
> loop in the web module. Correct the cause of the infinite loop before 
> running the web module again. 
> 
> INFO: The server side component of the HTTP Monitor has detected a 
> java.lang.StackOverflowError. This happens when there is an infinite 
> loop in the web module. Correct the cause of the infinite loop before 
> running the web module again. WARNING: 
> StandardWrapperValve[AjaxServlet]: Servlet.service() for servlet 
> AjaxServlet threw exception java.lang.StackOverflowError 

> WARNING: StandardWrapperValve[AjaxServlet]: Servlet.service() for 
> servlet AjaxServlet threw exception java.lang.StackOverflowError at 
> sun.util.calendar.ZoneInfo.getOffsets(ZoneInfo.java:248) at 
> java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2276) 
> at 
> java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2248) 
> at java.util.Calendar.setTimeInMillis(Calendar.java:1140) at 
> java.util.Calendar.setTime(Calendar.java:1106) at 
> java.text.SimpleDateFormat.format(SimpleDateFormat.java:955) at 
> java.text.SimpleDateFormat.format(SimpleDateFormat.java:948) at 
> java.text.DateFormat.format(DateFormat.java:336) at 
> com.google.gson.internal.bind.DateTypeAdapter.write(DateTypeAdapter.java:90) 
> at 
> com.google.gson.internal.bind.DateTypeAdapter.write(DateTypeAdapter.java:41) 
> at 
> com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
> at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:892) at 
> com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
> at 
> com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
> at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:892) at 
> com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
> at 
> com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
> at 
> com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
> at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:892) 

Tôi cũng nhận thấy rằng dấu vết này được lặp đi lặp lại chỉ đầu ra của stacktrace;

EDIT: Nhân viên lớp

@Entity 
public class Staff implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id") 
    private Integer id; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 45) 
    @Column(name = "last_name") 
    private String lastName; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 45) 
    @Column(name = "first_name") 
    private String firstName; 
    @Size(max = 45) 
    @Column(name = "middle_name") 
    private String middleName; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 6) 
    @Column(name = "gender") 
    private String gender; 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "date_of_birth") 
    @Temporal(TemporalType.DATE) 
    private Date dateOfBirth; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 45) 
    @Column(name = "nationality") 
    private String nationality; 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "date_hired") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date dateHired; 
    @Size(max = 20) 
    @Column(name = "status") 
    private String status; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "staff") 
    private Collection<StaffApointments> staffApointmentsCollection; 
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "staff") 
    private StaffContact staffContact; 
    @JoinColumn(name = "account_id", referencedColumnName = "id") 
    @ManyToOne(optional = false) 
    private Account accountId; 
    @JoinColumn(name = "position_id", referencedColumnName = "id") 
    @ManyToOne(optional = false) 
    private Position positionId; 

    public Staff() { 
    } 

    public Staff(Integer id) { 
     this.id = id; 
    } 

    public Staff(Integer id, String lastName, String firstName, String gender, Date dateOfBirth, String nationality, Date dateHired) { 
     this.id = id; 
     this.lastName = lastName; 
     this.firstName = firstName; 
     this.gender = gender; 
     this.dateOfBirth = dateOfBirth; 
     this.nationality = nationality; 
     this.dateHired = dateHired; 
    } 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getMiddleName() { 
     return middleName; 
    } 

    public void setMiddleName(String middleName) { 
     this.middleName = middleName; 
    } 

    public String getGender() { 
     return gender; 
    } 

    public void setGender(String gender) { 
     this.gender = gender; 
    } 

    public Date getDateOfBirth() { 
     return dateOfBirth; 
    } 

    public void setDateOfBirth(Date dateOfBirth) { 
     this.dateOfBirth = dateOfBirth; 
    } 

    public String getNationality() { 
     return nationality; 
    } 

    public void setNationality(String nationality) { 
     this.nationality = nationality; 
    } 

    public Date getDateHired() { 
     return dateHired; 
    } 

    public void setDateHired(Date dateHired) { 
     this.dateHired = dateHired; 
    } 

    public String getStatus() { 
     return status; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 

    @XmlTransient 
    public Collection<StaffApointments> getStaffApointmentsCollection() { 
     return staffApointmentsCollection; 
    } 

    public void setStaffApointmentsCollection(Collection<StaffApointments> staffApointmentsCollection) { 
     this.staffApointmentsCollection = staffApointmentsCollection; 
    } 

    public StaffContact getStaffContact() { 
     return staffContact; 
    } 

    public void setStaffContact(StaffContact staffContact) { 
     this.staffContact = staffContact; 
    } 

    public Account getAccountId() { 
     return accountId; 
    } 

    public void setAccountId(Account accountId) { 
     this.accountId = accountId; 
    } 

    public Position getPositionId() { 
     return positionId; 
    } 

    public void setPositionId(Position positionId) { 
     this.positionId = positionId; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     // TODO: Warning - this method won't work in the case the id fields are not set 
     if (!(object instanceof Staff)) { 
      return false; 
     } 
     Staff other = (Staff) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "entity.Staff[ id=" + id + " ]"; 
    } 

} 

Đây là lớp Chức vụ cũng như:

@Entity 
public class Position implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id") 
    private Integer id; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 45) 
    @Column(name = "name") 
    private String name; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "positionId") 
    private Collection<Staff> staffCollection; 

    public Position() { 
    } 

    public Position(Integer id) { 
     this.id = id; 
    } 

    public Position(Integer id, String name) { 
     this.id = id; 
     this.name = name; 
    } 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @XmlTransient 
    public Collection<Staff> getStaffCollection() { 
     return staffCollection; 
    } 

    public void setStaffCollection(Collection<Staff> staffCollection) { 
     this.staffCollection = staffCollection; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     // TODO: Warning - this method won't work in the case the id fields are not set 
     if (!(object instanceof Position)) { 
      return false; 
     } 
     Position other = (Position) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "entity.Position[ id=" + id + " ]"; 
    } 

} 

EDIT 2:

tôi thêm @expose đến các thuộc tính trong lớp nhân viên của tôi ngoại trừ staffCollection. Nhưng tôi vẫn có 1 vấn đề. Mỗi lần giá trị thứ nhất trong danh sách thả xuống được chọn (giá trị = 1) nó vẫn cung cấp lỗi vòng lặp vô hạn. Ai giúp tôi với?

EDIT 3:

cố định nó! Tôi đã thêm GsonBuilder builder cuối cùng = new GsonBuilder(); builder.excludeFieldsWithoutExposeAnnotation(); nói chung. Nó hiện đang làm việc

+0

Servlet giống như Java đối với tôi và lỗi của bạn thấy để xác thực ý nghĩ đó ... có thể sử dụng thẻ java sẽ hữu ích? –

+0

Không sử dụng kiểu thô ở tất cả như được sử dụng ở đây 'Bộ sưu tập staffCollection' sau đó mà không có bất kỳ kiểm tra nó được chuyển đổi thành chung' danh sách'. * Điều đó có thể xảy ra nếu bạn có tham chiếu vòng tròn. * Kết quả là vòng lặp vô hạn khi phân tích cú pháp. Chia sẻ các lớp 'Posiiton' và' Staff'. – Braj

+0

@Braj các lớp của tôi được tạo thành các lớp thực thể từ cơ sở dữ liệu. Bảng "Staff" tham chiếu đến position_id của nó từ bảng "Position". Xin lỗi nếu tôi không thể hiểu rõ bạn, trong khi bạn tham khảo bộ sưu tập staffCollection, bạn sẽ gợi ý điều gì? – MLDS

Trả lời

7

Vấn đề là mọi đối tượng Staff chứa một đối tượng Chức vụ có chứa một Collection của Staff đối tượng, mỗi bảng chứa một Collection của Staff đối tượng lần nữa, vv GSON sẽ tiếp tục đi bộ cây này mãi mãi vì nó không bao giờ sẽ dừng lại .

Để giải quyết, bạn có thể xem câu trả lời cho câu hỏi this.

+0

Cảm ơn bạn đã chuyển hướng tôi. Tôi có một chút rắc rối khi hiểu những gì để phơi bày. Tôi có nên để lộ vị tríID trong lớp nhân viên không? Nó vẫn cho tôi lỗi. Bạn có thể làm rõ? – MLDS

+0

Không, bạn nên trưng ra tất cả các yếu tố ngoại trừ những yếu tố bạn không muốn trong JSON –

+0

Điều đó có ảnh hưởng đến hoạt động CRUD của tôi không? – MLDS