我的xpage应用程序的基本REST服务

时间:2016-03-17 13:46:26

标签: java rest xpages

我想为我的XPage应用程序设置一些基本的REST服务。所以我在xpage上添加了xe:restService控件并选择了xe:customRestService,其中我引用了Java类:

<xe:restService id="restService1" pathInfo="json" state="false">
        <xe:this.service>
            <xe:customRestService contentType="application/json"
                serviceBean="se.banking.desk.CustomSearchHelper">
            </xe:customRestService>
        </xe:this.service>
    </xe:restService>

它自己的CustomSearchHelper类仍然很空,但我想知道我是否在正确的轨道上?

以下是该类的代码:

package se.banking.desk;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceEngine;
import com.ibm.xsp.extlib.component.rest.CustomService;
import com.ibm.xsp.extlib.component.rest.CustomServiceBean;

public class CustomSearchHelper extends CustomServiceBean {

    @Override
    public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {

        HttpServletRequest request = engine.getHttpRequest();           
        String method = request.getMethod();

        HttpServletResponse response = engine.getHttpResponse();        
        response.setHeader("Content-Type", "text/javascript; charset=UTF-8");        

        if(method.equals("GET")){
            this.get(engine);
        }
        else if(method.equals("POST")){
            this.post(engine,request);
        }
        else{
            this.other(engine);
        }

    }

    public void get(RestServiceEngine engine){
        HttpServletResponse response = engine.getHttpResponse();
        try {
            response.getWriter().write("get()");
            response.getWriter().close();
            return;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void post(RestServiceEngine engine,HttpServletRequest request){
      HttpServletResponse response = engine.getHttpResponse();
      Map parameters = request.getParameterMap();
      try {
          response.getWriter().write("post()");
          response.getWriter().write( request.getParameter("form"));
          String[] form = (String[])parameters.get("form");
          String val = form[0];
          response.getWriter().write(val);
        response.getWriter().close();
    } catch (Exception e) {
        // TODO: handle exception
    }     

  }

    public void other(RestServiceEngine engine){
       HttpServletResponse response = engine.getHttpResponse();
        try {
            response.getWriter().write("other()");
            response.getWriter().close();
            return;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

我遇到的问题:这是编写自定义REST服务的好方法吗?还有替代品吗?我在哪里可以找到更多从入门级开始的示例/信息?

2 个答案:

答案 0 :(得分:12)

你问了一个相当复杂的问题,这个问题在过去几年一直在我的脑海中浮现。我的评估是找到“好方法”归结为应用程序中使用的开发人员和约定。我已经包含了我所看到的备选方案的来源链接,其中包括我的一些,其中一些试图从头开始解决一些概念,例如我的series on http servlets

[更新]我编辑了这个答案以包含一些代码示例,因为链接最终可能无法正常工作;这应该保留答案的意图。[/ Update]

您的实现是如何将 xe:restService 控件轻松绑定到XPage的一个很好的示例,可以在XPage运行时和Domino服务器中使用各种选项。

据我所知,在XPage上下文中有大约5种实现RESTful API /端点的独特(-ish)方式。按照易于实施的一般顺序(取决于人):

  1. XAgent(这可以与下一个交换;易于入手的好处,可用的大量示例,以及那些没有Java经验的人可以在SSJS或Java中完成更少的工作)< / LI>
    <?xml version="1.0" encoding="UTF-8"?>
    <xp:view
        xmlns:xp="http://www.ibm.com/xsp/core"
        rendered="false"
        viewState="nostate">
        <xp:this.afterRenderResponse>
            <![CDATA[#{javascript:com.demo.DataProvider.myCustomDataServiceAsJson();}]]>
        </xp:this.afterRenderResponse>
    
        XAgent. This will not render as a page, but as application/json data.
    </xp:view>
    
    1. 关于 xe:restService 的最佳部分是 xe:viewJsonService 之类的开箱即用选项(Domino开发人员已经根据视图考虑了这些选项)正如马克在评论中所指出的那样,和文档有点类似于RESTful API的集合和记录机制。这些很容易进入和方便(很多人都在博客上写这些,Brad has covered some of these rather extensively in his data grids seriesavailable options, complete with pretty picker
    2. xe:restService ,或者作为上面显示的 CustomServiceBean ,或者作为 xe:customRestService 的另一种风格,带有 xe:this.doGet 等方法(可以通过调用类的方法或SSJS来完成;我推荐前者)
    3. <?xml version="1.0" encoding="UTF-8"?>
      <xp:view
          xmlns:xp="http://www.ibm.com/xsp/core"
          xmlns:xe="http://www.ibm.com/xsp/coreex">
          <xe:restService
              id="restService1"
              pathInfo="beers">
              <xe:this.service>
                  <xe:customRestService
                      contentType="application/json"
                      requestContentType="application/json">
                      <xe:this.doGet><![CDATA[${javascript:var resp = {
          "data": [
              { "key": "value" }
          ],
          "error": false
      };
      return toJson(resp);}]]></xe:this.doGet>
                  </xe:customRestService>
              </xe:this.service>
          </xe:restService>
      </xp:view>
      
      1. 实施a DesignerFacesServlethas some requirements(许多非Domino / XPages特定行业惯例的好处,不需要知识/经验/能力来部署OSGi插件,保留您的应用程序代码包含在NSF容器内); a demo app I wrote follows this implementation,修改后的版本(在该回购的当前bluemix分支中)can be seen running on Bluemix; the sample here follows Jesse's blog post
      2. public class SampleServlet extends DesignerFacesServlet implements Serializable {
            private static final long serialVersionUID = 1L;
        
            @SuppressWarnings("unchecked")
            @Override
            public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
                // Set up handy environment variables
                HttpServletRequest req = (HttpServletRequest)servletRequest;
                HttpServletResponse res = (HttpServletResponse)servletResponse;
                ServletOutputStream out = res.getOutputStream();
                FacesContext facesContext = this.getFacesContext(req, res);
        
                try {
                    res.setContentType("text/plain");
        
                    // write some amazing code!
        
                    out.println("done");
        
                } catch(Exception e) {
                    e.printStackTrace(new PrintStream(out));
                } finally {
                    out.close();
        
                    // It shouldn't be null if things are going well, but a check never hurt
                    if(facesContext != null) {
                        facesContext.responseComplete();
                        facesContext.release();
                    }
                }
            }
        }
        
        1. 创建“真正的”JEE风格的驱动 HttpServlets 的OSGi插件,可以使用像JAX-RS这样的东西来加快速度(没有像使用 DesignerFacesServlet那样摆弄类加载器在NSF内部,只是为了让它与你的NSF包含的代码很好,但是实现OSGi插件开发的障碍,which has been covered nicely multiple excellent developers
        2. 至于什么是“好方法”,我认为它们都有它们的用途,特别是考虑到有关开发人员的技能水平。对于那些希望在XPage应用程序中开始使用这样的东西的人,我建议你正在做什么, xe:restService CustomServiceBean 扩展类,或者简单的类或bean,它有一次性的方法

          [更新]

          Shean P. McManus和我为ICONUS(fka-IamLug)举办了为期两天的“正常化XPage开发”虚拟活动。介绍了创建用于XPage应用程序的RESTful API时可用选项的大部分内容。幻灯片可用于from Shean's blogthe git project repository on GitHub;后者包含应用程序代码,以及a pre-built, stand alone NSF

          [/更新]

答案 1 :(得分:2)

Eric指出了如何在XPage中实现REST服务的不同方法。以下是我在IBM Connect 2016上关于REST服务的演示文稿的链接。http://www.assono.de/blog/d6plinks/ibmconnect2016-ad1238

该演示文稿涵盖了除OSGi插件之外的所有不同方式,因为这种技术在1小时的会话中有点重。

在示例数据库中,使用了所有其他方法。只需下载示例并在Notes客户端中打开它即可。有一个欢迎页面可以指导您访问代码和示例。

你已经走得很好了。