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

Mal*_*lin 6 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>
Run Code Online (Sandbox Code Playgroud)

自己的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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*ick 12

你问了一个相当复杂的问题,这个问题在过去的几年里一直在我的脑海里浮现.我的评估是找到"好方法"归结为应用程序中使用的开发人员和约定.我已经包含了我可以看到的备选方案源代码的链接,其中包括一些我的,其中一些尝试从头开始解决一些概念,比如我在http servlets上的系列.

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

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

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

  1. XAgent(这可以与下一个交换;易于入手的好处,可用的大量示例,以及那些没有Java经验的人可以在SSJS或Java中完成更少的艰巨)
<?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>
Run Code Online (Sandbox Code Playgroud)
  1. 关于最好的部分XE:restService是搞什么出的现成的选项XE:viewJsonService(多米诺开发者已经认为在视图和文档,这有点类似于收集和记录的一个RESTful API的力学计算)正如马克在评论中指出的那样; 这些很容易进入和方便(很多人都在博客上写这些,Brad在他的数据网格系列中相当广泛地介绍了其中一些) 可用选项,配有漂亮的选择器
  2. xe:restService,或者作为上面显示的CustomServiceBean,或者作为xe的另一种风格:customRestService及其xe:this.doGet等方法(可以通过调用类的方法或SSJS来完成 ;我推荐前任的)
<?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>
Run Code Online (Sandbox Code Playgroud)
  1. 实现一个DesignerFacesServlet,它有一定的要求(从许多非Domino/XPages中特定行业惯例的好处,并不需要部署一个OSGi插件的知识/经验/能力,保持包含在NSF容器内的应用程序代码); 我编写的一个演示应用程序遵循此实现,可以看到在Bluemix上运行的修改版本(在该repo的当前bluemix分支中); 这里的示例遵循Jesse的博客文章
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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 创建"真正的"JEE风格的驱动HttpServlet的OSGi插件,可以使用像JAX-RS这样的东西来加快速度(没有像在NSF中那样使用DesignerFacesServlet获取类加载,只是为了让它与您的NSF包含Code,但是实现OSGi插件开发的障碍,已被多个优秀的开发人员很好地介绍了)

至于什么是"好方法",我认为它们都有它们的用途,特别是考虑到有关开发人员的技能水平.对于那些希望在XPage应用程序中开始使用这样的东西的人,我建议您正在做什么,使用CustomServiceBean扩展类的xe:restService,或者具有一次性方法的简单类或bean

[更新]

Shean P. McManus和我为ICONUS(fka-IamLug)举办了为期两天的"正常化XPage开发"虚拟活动.介绍了创建用于XPage应用程序的RESTful API时可用选项的大部分内容.幻灯片可以从Shean的博客GitHub上的git项目存储库获得 ; 后者包含应用程序代码,以及预先构建的独立NSF.

[/更新]