我想为我的 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 服务的好方法吗?还有其他选择吗?我在哪里可以找到更多从入门级开始的示例/信息?
你问了一个相当复杂的问题,这个问题在过去几年里一直萦绕在我的脑海里。我的评估是,找到“好方法”取决于开发人员和应用程序中使用的约定。我提供了我看到的可用替代方案来源的链接,其中有一些是我的,其中尝试从头开始解决一些概念,例如我的关于 http servlet 的系列。
[更新]我编辑了这个答案以包含一些代码示例,因为链接最终有可能不起作用;这应该保留答案的意图。[/更新]
您的实现是一个很好的示例,展示了如何将 xe:restService 控件轻松绑定到 XPage,并在 XPages 运行时和 Domino 服务器中使用多种选项。
据我所知,大约有 5 种独特的方法可以实现 RESTful API/端点以在 XPages 上下文中进行操作。按照易于实施的一般顺序(取决于个人):
<?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>
<?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>
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();
}
}
}
}
至于什么是“好方法”,我认为它们都有其用处,尤其是考虑到相关开发人员的技能水平时。对于那些希望在 XPages 应用程序中开始使用此类功能的人,我建议您正在做的事情,一个带有 CustomServiceBean 扩展类的 xe:restService,或者一个具有一次性功能的简单类或 bean方法
[更新]
Shean P. McManus 和我在 ICONUS (fka- IamLug) 为期两天的虚拟活动中举办了一场关于“标准化 XPage 开发”的会议。涵盖了创建与 XPages 应用程序一起使用的 RESTful API 时可用选项的大部分主题。幻灯片可从 Shean 的博客 和 GitHub 上的 git 项目存储库 获取;后者包含应用程序代码以及预构建的独立 NSF。
[/更新]
正如 Eric 指出的那样,在 XPage 中实现 REST 服务有不同的方法。以下是我有关 IBM Connect 2016 REST 服务的演示文稿的链接。http://www.assono.de/blog/d6plinks/ibmconnect2016-ad1238
演示涵盖了除 OSGi 插件之外的所有不同方法,因为这种技术对于 1 小时的会话来说有点繁重。
在示例数据库中使用了所有其他方式。只需下载示例并在 Notes 客户端中打开它即可。有一个欢迎页面可指导您使用代码和示例。
你已经走上了正路。