XPages自定义验证器未显示提示且未拦截保存操作问题
问题根源及解决方案
核心问题:自定义验证器的异常被内部捕获,未向上抛出
你的valName方法将所有逻辑包裹在try-catch块中,当检测到重复值抛出ValidatorException后,会被自身的catch块捕获,仅记录日志却没有重新抛出异常。JSF框架无法感知到验证失败,因此不会触发xp:messages显示提示,也不会拦截后续的保存操作。
而自带的validateRequired和validateLength属于框架原生验证器,它们的异常不会被你的代码捕获,所以能正常工作。
修复步骤
调整try-catch逻辑,仅捕获非验证类异常
将验证逻辑中抛出的ValidatorException排除在catch范围外,或在catch中判断异常类型,若是ValidatorException则直接重新抛出: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(FacesMessage.SEVERITY_ERROR, msg, msg); throw new ValidatorException(message); } // 重复名称检查 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; break; // 找到重复后直接跳出循环,提升效率 } } } if (duplicateFound) { String msg = propStrings.getProperty("teamValidateNameDuplicate"); FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg); throw new ValidatorException(message); } } catch (ValidatorException ve) { // 直接重新抛出验证异常,交给JSF框架处理 throw ve; } catch (Exception e) { XspOpenLogUtil.logErrorEx(e, JSFUtils.getXSPContext().getUrl().toString(), Level.SEVERE, null); // 可选:针对非验证异常,抛出通用验证提示 String errorMsg = propStrings.getProperty("teamValidateUnexpectedError"); throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMsg, errorMsg)); } }为FacesMessage指定错误级别
原代码创建FacesMessage时未指定严重级别,建议显式设置为SEVERITY_ERROR,确保xp:messages能正确识别并显示错误样式。优化重复检查逻辑
找到重复值后立即跳出循环,避免不必要的遍历,提升性能。
额外验证点
- 确认
xp:messages控件未通过for属性限制仅显示特定组件的消息;若设置了for,需指向inpTeamName的ID。 - 检查对话框的提交按钮是否设置了
immediate="true",该属性会跳过验证阶段,需改为immediate="false"。
内容的提问来源于stack exchange,提问作者Patrick Kwinten
相关产品推荐
相关产品推荐

