XPages:从分类视图创建 Json 字符串

XPages: Creating Json String from categorised view

我想使用 Java 从分类视图创建一个 Json 字符串,但我无法使 Json 子类别保留在父类别下。我不断收到以下输出:

{ "identifier":"id", "label":"State", "items": [

想知道是否可以从 2 级分类视图生成 JSON 字符串,或者是否有更好的方法来实现它。

下面是我的java方法:

public ResponseWriter getJSONData() { 
        long startTime = System.currentTimeMillis();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ResponseWriter resWriter = facesContext.getResponseWriter();

        //StringWriter stringOut = new StringWriter();
        JsonWriter writer = new JsonWriter(resWriter,false);
        Database db = null;

        try {
            writer.startObject();

            writer.startProperty("identifier");
            writer.outStringLiteral("id");
            writer.endProperty();

            writer.startProperty("label");
            writer.outStringLiteral("State");
            writer.endProperty();

            writer.startProperty("items");
            writer.startArray();

            db = DominoUtils.getCurrentSession().getCurrentDatabase();
            View lookupDB = db.getView("StateAndCity");         
            //Document doc = lookupDB.getFirstDocument();   

            ViewNavigator nav = lookupDB.createViewNav();
            ViewEntry ve = nav.getFirst();

            boolean run =false;
            while (ve != null){    
                counter++;
                Vector cv = ve.getColumnValues();
                int level = ve.getIndentLevel();
                String levelTitle = (String) cv.get(level);


                writer.startArrayItem();
                writer.startObject();

                if (ve.isCategory()) {

                    if (run) {
                        writer.endArrayItem();
                        writer.endArray();

                    } 
                    run= true;
                    writer.startArrayItem();

                    writer.startProperty("id"); 
                    writer.outStringLiteral(getID());
                    writer.endProperty();

                    writer.startProperty("title");
                    writer.outStringLiteral(levelTitle);
                    writer.endProperty();

                    writer.startProperty("category");
                    writer.outStringLiteral("true");
                    writer.endProperty();

                    writer.startProperty("children");
                    writer.startArray();

                }else{

                    writer.startArrayItem();
                    writer.startObject();

                    Document doc = ve.getDocument();


                    writer.startProperty("id"); 
                    writer.outStringLiteral(getID());
                    writer.endProperty();

                    writer.startProperty("docId"); 
                    writer.outStringLiteral(doc.getUniversalID());
                    writer.endProperty();

                    writer.startProperty("title");
                    writer.outStringLiteral(levelTitle);
                    writer.endProperty();

                    writer.startProperty("category");
                    writer.outStringLiteral("false");
                    writer.endProperty();

                    writer.endObject();
                    writer.endArrayItem();

                }    


                ViewEntry tmpentry = nav.getNext();

                ve.recycle();
                ve = tmpentry;
            }  

            writer.endArray();
            writer.endProperty();
            writer.endObject();


            long endTime   = System.currentTimeMillis();
            long totalTime = endTime - startTime;
            //System.out.println("running time:  "+totalTime);

            writer.flush();


            return resWriter;

        }catch (NotesException e) {

            e.printStackTrace();
        }
        return resWriter;
    }

更新: 想使用我的 return JSON 创建以下类型的网格,但具有两级类别 State 和 City

JSON输出

{
    "identifier": "id",
    "label": "name",
    "items": [{
        "id": "AK",
        "type": "state",
        "state": "AK",
        "childItems": [{
            "id": "Anchorage",
            "type": "city",
            "city": "Anchorage",
            "numPeople": "2",
            "childItems": [{
                    "id": "B3093953178C98E905257838007ABC48",
                    "firstname": "Bella",
                    "lastname": "Martin",
                    "valueToAdd": "2"
                },
                {
                    "id": "7FDB9CCDE7D6923E05257838007ABC1E",
                    "firstname": "Brian",
                    "lastname": "Leggett",
                    "valueToAdd": "2"
                }
            ]
        }]

....
    }]
}

您可以退回到 "old" 多米诺骨牌技巧并消除所有 Java。将视图定义为 Passthru HTML 并创建一个具有 MIME 类型 "text/Json" 的“$$ViewTemplate for ViewName”表单。然后您可以使用 ?Openview 访问输出。根据需要添加 Json 标记。

或者只使用 .../viewname?ReadviewEntries&Outputformat=json

内置Json输出

看起来你的代码在写任何东西之前就崩溃了。有几个有问题的语句:

  • Vectors/Arrays 是从零开始的,但是 int level = ve.getIndentLevel(); 不是,所以你很可能得到一个索引越界错误
  • 如果 returns null 转换为 String 也会出错。所以将 String levelTitle = (String) cv.get(level); 更改为 String levelTitle = String.valueOf(cv.get(level));
  • 我建议将您的方法签名更改为类似 public String getJSONFromView(final Database db, final String viewName) {...} 的内容,然后使用一些包装代码来调用该方法。这也允许您在 Domino 命令行应用程序中使用 class,这对于在本地 Designer/Eclipse 中进行调试非常方便。由于 class 没有使生活更轻松的 XPages 依赖项。我以这种方式开发了所有 VoP:核心没有服务器,只有 Notes classes 依赖项。您可以像这样创建一个测试 class(省略错误处理):

    public class Test1 {
       public static void main(String args[]) {
           NotesThread.sinitThread();
           Session s = NotesFactory.createSession();
           Database db = s.openDatabase("someserver","somedb");
           Yourclass yc = new Yourclass();
           System.out.println(yc.getJSONFromView(db,"viewname");
           db.recycle();
           s.recycle();
           NotesThread.stermThread();
       }
    }
    

您可能需要切换到 Domino 设计器中的 Java 透视图,并创建一个标准的 Java 项目来放置它。这应该允许您让 Java class 在 XPage 中使用它之前做您想做的事。

我写了一会儿类似的东西,你可以check it out

让我们知道需要澄清的内容。