JSF如何在Facelet中抛出异常及EL引用不存在对象不报错原因
EL表达式引用不存在对象无异常的原因
默认JSF搭配EL 3.0+实现时,默认开启了容错处理,当EL表达式引用的托管Bean、属性不存在时,不会抛出PropertyNotFoundException,而是直接返回null,这是为了避免可选参数场景下页面直接崩溃,符合生产环境的稳定性要求。
如果需要全局开启不存在对象/属性抛出异常的规则,可在web.xml中添加对应实现的上下文参数:
- Mojarra(Oracle官方JSF实现)配置:
<context-param> <param-name>com.sun.faces.throwAttributeNotFoundException</param-name> <param-value>true</param-value> </context-param> <!-- 开发模式下也会默认开启部分异常抛出规则 --> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param>
- MyFaces(Apache实现)配置:
<context-param> <param-name>org.apache.myfaces.EL_RESOLVER_THROW_EXCEPTIONS</param-name> <param-value>true</param-value> </context-param>
Facelet组件内部主动抛出异常的实现方案
针对你需要校验必填Converter参数的场景,有两种常用的实现方式:
方式1:组件Backing Bean校验(推荐)
如果你自定义的组件关联了对应的托管Bean,可以在@PostConstruct初始化方法中做参数校验,为空时直接抛出业务异常:
@Named @ViewScoped public class CustomComponentBacking implements Serializable { // 注入父页面传入的pConverter参数 @ManagedProperty("#{pConverter}") private Converter<String> pConverter; @PostConstruct public void init() { if (pConverter == null) { throw new FacesException("必填参数pConverter为空,请检查EL表达式拼写是否正确"); } } // 省略其他组件逻辑 }
方式2:Facelet页面直接校验
如果是轻量复合组件不想额外写Backing Bean,可以先封装一个全局的异常工具类:
@Named @ApplicationScoped public class ViewExceptionUtils { /** 主动抛出参数异常,供Facelet页面调用 */ public void throwParamError(String message) { throw new IllegalArgumentException(message); } }
然后在组件的Facelet页面最开头添加校验逻辑:
<!-- 校验pConverter是否为空 --> <c:if test="#{empty pConverter}"> #{viewExceptionUtils.throwParamError('必填参数pConverter为空,请检查拼写')} </c:if>
当传入的pConverter为空时,EL表达式会调用工具类方法抛出异常,终止页面渲染,直接抛出错误信息。
内容的提问来源于stack exchange,提问作者Toru
相关产品推荐
相关产品推荐

