XPages是IBM的Web和移动应用程序开发平台,用于构建在IBM Domino和IBM XWork Server平台之上的协作和社交应用程序。
我已经为 xp:input 控件设置了一个验证器类: 我已经为 xp:input 控件设置了一个验证器类: <xp:inputText id="inpTeamName" title="${strings.label_name_team_title}" value="#{teamBean.team.name}" defaultValue="#{teamBean.team.name}" required="true" validator="#{teamValidator.valName}"> <xp:this.attrs> <xp:attr name="placeholder" value="#{strings.label_name_team_ph}"> </xp:attr> </xp:this.attrs> <xp:this.validators> <xp:validateRequired loaded="true" message="#{strings.teamValidateNameEmpty}"> </xp:validateRequired> <xp:validateLength minimum="6" message="#{strings.teamValidateNameTooShort}"> </xp:validateLength> </xp:this.validators> </xp:inputText> <xp:panel> <small id="infoHelp" class="form-text text-muted"> <xp:text value="${strings.label_name_team_helper}" /> </small> </xp:panel> 这是 TeamValidator 类中的方法(作为托管 bean 访问): public void valName(FacesContext facesContext, UIComponent component, Object value) { String methodName = new Object(){}.getClass().getEnclosingMethod().getName(); utils.printToConsole(this.getClass().getSimpleName().toString() + " " + methodName); try { if (value.toString().replaceAll("\\s+","").equals("")){ String msg = propStrings.getProperty("teamValidateNameEmpty"); FacesMessage message = new FacesMessage(msg); throw new ValidatorException(message); } //check for duplicate name for team for event String qParam = utils.getUrlParameterValue("unid"); TeamBean teamBean = new TeamBean(); ArrayList<JsonJavaObject> teams = teamBean.loadObjects(); boolean duplicateFound = false; for (JsonJavaObject team : teams) { String key = "team"; if (team.containsKey(key)) { String name = team.getAsString(key).replaceAll("\\s+",""); if (value.toString().replaceAll("\\s+","").equals(name)){ duplicateFound = true; } } } if (true == duplicateFound ) { String msg = propStrings.getProperty("teamValidateNameDuplicate"); FacesMessage message = new FacesMessage(msg); throw new ValidatorException(message); } } catch (Exception e) { XspOpenLogUtil.logErrorEx(e, JSFUtils.getXSPContext().getUrl().toString(), Level.SEVERE, null); } } 如果我添加一些打印语句,我会发现它检测到重复项,并且应该抛出验证器异常。但该消息不会出现在屏幕上(我添加了 xp:messages 控件)。 所需和长度的验证确实出现在屏幕上。 我还看到触发验证器(保存文档)的代码未被验证禁止。 我想知道我在这里做错了什么? 仅供参考,inputput 控件驻留在 xe:dialog 控件中。 您抛出的 ValidatorException 被同一方法中的 try/catch 捕获。所以删除 try/catch。
如何使用 Azure OAuth 或 Azure API 网关保护 Open xpage REST API
我已经使用 xpages 创建了一个 REST API,并且该数据库具有匿名“作者访问权限”。 还有 Azure 上的 OAuth 设置。因此 API 使用者将使用 OAuth Url、客户端 id、客户端机密...
我想为我的 XPage 应用程序设置一些基本的 REST 服务。因此,我在 xpage 上添加了 xe:restService 控件,并选择 xe:customRestService,其中我引用了 Java 类: 我想为我的 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 上下文中进行操作。按照易于实施的一般顺序(取决于个人): 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> 关于 xe:restService 最好的部分是像 xe:viewJsonService 这样的开箱即用选项(Domino 开发人员已经考虑了视图和文档,这在某种程度上类似于 RESTful API 的机制)正如马克在评论中指出的那样;这些很容易进入并且很方便(很多人都在博客上讨论了这些,Brad 在他的数据网格系列中相当广泛地介绍了其中一些) 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> 实现 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(); } } } } 创建“真正的”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。 [/更新] 正如 Eric 指出的那样,在 XPage 中实现 REST 服务有不同的方法。以下是我有关 IBM Connect 2016 REST 服务的演示文稿的链接。http://www.assono.de/blog/d6plinks/ibmconnect2016-ad1238 演示涵盖了除 OSGi 插件之外的所有不同方法,因为这种技术对于 1 小时的会话来说有点繁重。 在示例数据库中使用了所有其他方式。只需下载示例并在 Notes 客户端中打开它即可。有一个欢迎页面可指导您使用代码和示例。 你已经走上了正路。
在 JavaScript、Domino Notes 中注释多行快捷方式
Notes中有没有注释掉JavaScript代码的快捷方式? 我知道 Xpage 的快捷键是 ctrl+shift+c
我想测试 CKEditor(富文本)字段作为某些业务逻辑的一部分是否为空。 我不想使用内置的验证功能。 如果 CK 编辑器字段之前有文本和 t...
XPages - 自动注销时在 $$LoginUserForm 中设置 ReasonType
我是 XPages 的新手,我正在努力学习..;-) 我使用超时来注销用户并重定向到登录站点($$LoginUserForm)。 URL +“?注销&重定向=”+ URL +“?
自定义控件-如何在onClientLoad中获取compositeData
超时后,我注销用户并重定向到登录,如下所述: 笔记说话 该代码的一部分在 onCliendLoad() 中执行。 var thisUrl = window.location.pathname; var FinalPat...
我有一个表单,其中包含两个用于保存附件的富文本字段和一个 XPage,其中包含两个文件下载控件(每个字段一个)和两个按钮。 这些按钮调用 Java 类中的方法...
xPages 如何处理传入的 FORM POSTpunchOutOrderMessage (POOM)
我正在设置 PunchOut 解决方案的 Byer-Side。 https://punchoutcommerce.com/guides/punchout/cxml-punchout-setup-request/ 一切正常,直到实际的“Cart-PunchOut”。 (Cre...
XPages 带有日期选择器的日期字段保存 12:00:00 时间的值
我使用标准的道场日期选择器,它工作正常。唯一的问题是保存到文档中的实际值始终包含 12:00:00 时间部分。我猜它可能会尝试设置上午 12 点,但自从...
在 HCL Domino 代理中使用 okhttp3 清理代理线程时出错
我在 Notes 代理中使用 okhttp3,每次运行时,我都会在控制台中收到消息“清理代理线程时出错”。 如果我在 Notes 14 客户端中运行代理,我会收到相同的消息...
当编辑器最初隐藏时,CKEditor 自动增长将高度设置为 0
我们正在将 XPage 应用程序升级到版本 12.0.2。平台附带的 CKEditor 版本已更改为 4.18(从 4.5.6.1)。 现在,当 CKEditor 最初隐藏时,例如在一个隐藏的
Domino 中不同的 java.protocol.handler.pkgs 设置导致 XPage java 出现错误
我在两个不同的多米诺骨牌服务器上使用相同的版本有两个不同的java设置。 12.0.2 FP2。 在这里您可以看到在 System.properties 中找到的服务器设置: 服务器1。 java.protocol.hand...
我们的大多数 Lotus Notes 开发人员都没有 XPage 经验。他们习惯于进行旧式表单开发。 我们正在设计一个新的 Lotus Notes 数据库应用程序,需要...
在 Notes Designer v12 xpages 中出现错误“访问限制:Java 问题”
我安装了 Lotus Designer v12,当我尝试使用 HCL Domino 设计器打开数据库时,出现下一个错误:“访问限制:构造函数 'UISelect2PickerCombo()' 不是 API(限制...
在 XPage 环境中运行时: NotesDatabase db = new NotesDatabase(ExtLibUtil.getCurrentSession(), "", fakenamesPath); 我收到消息: HTTP JVM:java.lang.IllegalStateException:Th...
“无法加载未注册的资源/.extlib/dijit/nls/de/pickers.js”
给定的 XPages 应用程序会抛出一些关于不存在的错误 /.extlib/dijit/nls/de/pickers.js 我不知道为什么这个资源不存在,也不知道为什么它被引用,...
我想编写一个 JavaScript 函数来清理用户输入并删除任何不需要的和危险的字符。 它必须仅允许以下字符: 字母数字字符(不区分大小写...
使用 XPage 中 bean 中的 DataObject 将文档项值加载到地图中
我正在尝试创建一个使用 DataObject 从文档中收集值的 bean。 代码的灵感来自这篇文章 包 com.consili; 导入莲花.多米诺骨牌.*; 导入 java.util.*; 导入com...
我正在尝试在 domino v12 上使用 Bootstrap 和 XPage。 我已在 XPage 属性中将应用程序主题设置为 Bootstrap4。 然后我将下面的示例代码复制粘贴到 XPage 中(https://getboo...