2014-09-22 98 views
1

我想從視圖中的文檔加載JSON並最終顯示dojo增強型數據網格。有大約1000個文件,我需要檢查多行數據。這是遺留應用程序,文檔可以包含80個不同用戶的詳細信息。所以我的代碼在最壞的情況下會生成80000個Json行。現在它可以從980個文檔加載70k +記錄。我目前的做法是創建完整的JSON,並在瀏覽器中寫入JS變量,該變量正在工作,但速度很慢。 Java生成JSON大約需要45-80秒。xpages從文檔加載json

我改變了將JSON加載到NotesDocument並在客戶端解析它的方法。這樣我的java代碼將只循環980次。我使用document.generateXML()生成XML,然後使用org.json.XML.toJSONObject()方法(來自json.org jar文件)將其轉換爲JSON。這也是工作,但似乎比第一種方法更慢。

我不知道我還能如何將這麼多的數據加載到瀏覽器。

最大的問題是:在打開Xpage後,Java代碼開始執行很長時間。它在beforePageLoad事件上被調用。這我真的很擔心。第一個控制檯消息(檢查代碼開始的日期時間)在我打開xpage鏈接後顯示很久。

現在對於數據網格,我只顯示30行,但問題是因爲每個文檔有多行數據,我不能讓用戶在獲取所有記錄之前對網格進行排序/過濾。

這是我當前使用的後端Java代碼。如果你願意,我可以發佈工作代碼(第一種方法)。

import java.io.IOException; 
import java.util.*; 

import javax.faces.context.ExternalContext; 
import javax.faces.context.FacesContext; 
import javax.faces.context.ResponseWriter; 
import javax.servlet.http.HttpServletResponse; 

import lotus.domino.Database; 
import lotus.domino.Document; 
import lotus.domino.View; 

import com.ibm.xsp.extlib.util.ExtLibUtil; 
import com.ibm.commons.util.io.json.*; 
import org.json.*; 

/** 
* @author agnihotri.a 
* 
*/ 

public class AccessRequests { 
    public static void mainly() { 
     Date dt1 = new Date(); 
     System.out.println(dt1.toString()); 
     System.out.println("here"); 
     Database database = null; 
     View accReqView = null; 
     Document accReqDoc = null; 
     JSONArray jarr = new JSONArray(); 
     //try out JSONObject here 
     //List <JSONObject> ljo = new ArrayList<JSONObject>(); 

     try { 

      /** 
      * we need handle current user session to compute common name in 
      * user names field 
      */ 
      // Session s = ExtLibUtil.getCurrentSession(); 
      database = ExtLibUtil.getCurrentDatabase(); 
      System.out.println("generating grid in : " + database.getFilePath()); 
      accReqView = database.getView("AccessRequestsGrid"); 

      // get access request document 
      accReqDoc = accReqView.getFirstDocument(); 
      //int counter = 0; 
      while (accReqDoc != null) { 
       //counter++; 
       jarr.put(org.json.XML.toJSONObject(accReqDoc.generateXML())); 
       //ljo.add(org.json.XML.toJSONObject(accReqDoc.generateXML())); 
       accReqDoc = accReqView.getNextDocument(accReqDoc); 
      } 

      ExtLibUtil.getSessionScope().put("allAccReq", jarr); 
      //System.out.println(ljo.size()); 
      //System.out.println(counter); 
      //ExtLibUtil.getSessionScope().put("totDocs", ljo.size()); 

     } 

     catch (final Exception ex) { 
      // tbd: handle exception 
      ex.printStackTrace(); 
      System.out.println(ex.getStackTrace().toString()); 
      // return "An Error occured. Check with IT team."; 
     } finally { 
      // recycle domino objects 
      KillDomObjects.incinerate(accReqDoc, accReqView, database); 
      final Date dt2 = new Date(); 
      System.out.println(dt2.toString()); 
     } 
    } 

} 
+0

您是否曾想過在視圖範圍中使用託管bean?然後直接從EL管理Bean中的JSON重新返回到數據網格,而不是將其存儲在sessionScope變量中中間層 – 2014-09-22 14:19:30

+0

謝謝弗蘭克。我一直有意使用bean,但不知道如何啓動esp,因爲我最近開始在其他傳統應用程序中使用xpages。另外我沒有使用數據網格控件。我以編程方式創建它,因爲我想在過濾器選項中顯示列值,這些列值不能以某種方式使用extlib dojo控件工作。 – Arun 2014-09-22 18:34:19

回答

2

我推薦在XPages REST服務中使用xe:viewItemFileService。這將返回JSON,而不必通過您提到的XML到JSON轉換。此外,一次只能返回50到100個條目,我發現這是速度和返回數據量之間的最佳折衷。是的,你必須配置無盡的滾動或分頁,但它是值得的,因爲人們不會很高興等待45 - 80秒,讓屏幕上的東西。你想拍攝< 3秒退貨。

如果您決定編寫自己的JSON傳遞,那麼確保您只返回使當前頁面可用的絕對必要條件。另外看看OpenNTF Domino API,這個項目有一個Document.toJSON()方法,它是一個巨大的節省時間和代碼大小的縮減器。更不用說正確實現Java Collections API來循環集合。

至於將這些數據存儲在sessionScope中,這裏引入了一個巨大的可伸縮性問題。您必須考慮到這些數據可能會存儲在您的應用程序的每個用戶的內存中。這是一個崩潰服務器的好方法,或者至少會導致越來越多的用戶使用該系統時性能下降。

你可能也想看看這些社區資源:

關於延遲,我在代碼中看到幾件事情:

  • 視圖索引可能未建立。如果您的視圖在任何選擇或列公式中都有@Now或@Today,則索引將在您每次訪問視圖時重建。根據視圖的大小,這可能是一個真實的性能瓶頸
  • 您可能想使用ViewNavigator而不是文檔集合
  • 使用ViewEntry和列值而不是打開文檔。在循環瀏覽1000個文檔時打開文檔是非常昂貴的操作