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

问题描述 投票:0回答:2

我想为我的 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 服务的好方法吗?还有其他选择吗?我在哪里可以找到更多从入门级开始的示例/信息?

java rest xpages
2个回答
13
投票

你问了一个相当复杂的问题,这个问题在过去几年里一直萦绕在我的脑海里。我的评估是,找到“好方法”取决于开发人员和应用程序中使用的约定。我提供了我看到的可用替代方案来源的链接,其中有一些是我的,其中尝试从头开始解决一些概念,例如我的关于 http servlet 的系列

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

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

据我所知,大约有 5 种独特的方法可以实现 RESTful API/端点以在 XPages 上下文中进行操作。按照易于实施的一般顺序(取决于个人):

  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>
  1. 关于 xe:restService 最好的部分是像 xe:viewJsonService 这样的开箱即用选项(Domino 开发人员已经考虑了视图和文档,这在某种程度上类似于 RESTful API 的机制)正如马克在评论中指出的那样;这些很容易进入并且很方便(很多人都在博客上讨论了这些,Brad 在他的数据网格系列中相当广泛地介绍了其中一些available options, complete with pretty picker
  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>
  1. 实现 a DesignerFacesServlet,它有一些要求(受益于许多非 Domino/XPage 特定行业惯例,不需要部署 OSGi 插件的知识/经验/能力,保持应用程序代码包含在内在 NSF 容器内); 我编写的演示应用程序遵循此实现,修改版本(在该存储库的当前
    bluemix
    分支中)可以看到在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();
            }
        }
    }
}
  1. 创建“真正的”JEE 风格的 OSGi 插件来驱动 HttpServlet,可以使用 JAX-RS 之类的东西来加速(不需要像 NSF 中的 DesignerFacesServlet 那样获取类加载器,只是为了获得它可以与您的 NSF 包含的代码很好地配合,但是实现 OSGi 插件开发的障碍,已经被 多个优秀的开发人员很好地覆盖了

至于什么是“好方法”,我认为它们都有其用处,尤其是考虑到相关开发人员的技能水平时。对于那些希望在 XPages 应用程序中开始使用此类功能的人,我建议您正在做的事情,一个带有 CustomServiceBean 扩展类的 xe:restService,或者一个具有一次性功能的简单类或 bean方法

[更新]

Shean P. McManus 和我在 ICONUS (fka- IamLug) 为期两天的虚拟活动中举办了一场关于“标准化 XPage 开发”的会议。涵盖了创建与 XPages 应用程序一起使用的 RESTful API 时可用选项的大部分主题。幻灯片可从 Shean 的博客GitHub 上的 git 项目存储库 获取;后者包含应用程序代码以及预构建的独立 NSF

[/更新]


2
投票

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

演示涵盖了除 OSGi 插件之外的所有不同方法,因为这种技术对于 1 小时的会话来说有点繁重。

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

你已经走上了正路。

© www.soinside.com 2019 - 2024. All rights reserved.