如何在FacesConverter中处理异常?修复日期格式错误致应用崩溃问题
如何在JSF的FacesConverter中处理日期输入异常?
这种情况我在做JSF项目时碰到过好多次——手动输入日期格式不对或者无效日期直接导致应用崩溃,确实头疼。不过只要在自定义Converter里做好异常处理,再配合JSF的消息机制就能解决,下面一步步来:
1. 修改自定义日期Converter,捕获解析异常并抛出ConverterException
核心思路是:在getAsObject方法里,当解析日期失败时,不要让异常往上抛导致应用崩溃,而是抛出JSF专门的ConverterException,并附带友好的错误提示消息。JSF会自动捕获这个异常,不会让应用挂掉,还能把消息展示给用户。
示例(用Java 8+的LocalDate)
@FacesConverter("customDateConverter") public class CustomDateConverter implements Converter<LocalDate> { // 定义我们期望的日期格式 private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); @Override public LocalDate getAsObject(FacesContext context, UIComponent component, String inputValue) { // 处理空输入 if (inputValue == null || inputValue.trim().isEmpty()) { return null; } try { // 尝试按指定格式解析日期 return LocalDate.parse(inputValue.trim(), DATE_FORMATTER); } catch (DateTimeParseException e) { // 解析失败时,创建错误消息并抛出ConverterException FacesMessage errorMessage = new FacesMessage( FacesMessage.SEVERITY_ERROR, "日期输入错误", "请输入符合格式的有效日期,例如:13.02.2018" ); throw new ConverterException(errorMessage, e); } } @Override public String getAsString(FacesContext context, UIComponent component, LocalDate dateValue) { // 把日期对象转回字符串展示 if (dateValue == null) { return ""; } return DATE_FORMATTER.format(dateValue); } }
示例(老项目用java.util.Date)
如果你的项目还在使用java.util.Date,要注意SimpleDateFormat不是线程安全的,所以每次解析都要创建新实例,还要开启严格模式拒绝无效日期(比如2月30号、年份999这种):
@FacesConverter("legacyDateConverter") public class LegacyDateConverter implements Converter<Date> { private static final String DATE_PATTERN = "dd.MM.yyyy"; @Override public Date getAsObject(FacesContext context, UIComponent component, String inputValue) { if (inputValue == null || inputValue.trim().isEmpty()) { return null; } SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERN); dateFormat.setLenient(false); // 严格模式,拒绝无效日期 try { return dateFormat.parse(inputValue.trim()); } catch (ParseException e) { FacesMessage errorMessage = new FacesMessage( FacesMessage.SEVERITY_ERROR, "无效日期", "请输入格式为dd.MM.yyyy的有效日期,例如13.02.2018" ); throw new ConverterException(errorMessage, e); } } @Override public String getAsString(FacesContext context, UIComponent component, Date dateValue) { if (dateValue == null) { return ""; } SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERN); return dateFormat.format(dateValue); } }
2. 在XHTML页面中使用转换器并添加错误消息组件
光有Converter还不够,得在输入组件上引用它,还要添加消息组件来显示错误提示,不然用户看不到错误反馈:
<h:form> <!-- 绑定日期输入,指定我们的自定义转换器 --> <h:inputText id="userDate" value="#{yourBean.selectedDate}" converter="customDateConverter"> <!-- 可选:如果需要额外的日期范围验证,可以加自定义validator --> <!-- <f:validator validatorId="dateRangeValidator" /> --> </h:inputText> <!-- 显示该输入框的错误消息 --> <h:message for="userDate" style="color: red; margin-left: 8px;" /> <h:commandButton value="提交" action="#{yourBean.handleSubmit}" /> </h:form>
关键注意点
- 为什么用ConverterException? 这是JSF提供的专用异常,框架会自动处理它,不会让异常渗透到上层导致应用崩溃,同时会把附带的FacesMessage展示给用户。
- 严格模式的重要性:对于
SimpleDateFormat,一定要调用setLenient(false),否则它会自动调整无效日期(比如把02.30.2018转换成03.02.2018),这不符合我们的需求。 - 消息组件不能少:如果页面上没有
<h:message>或<h:messages>,用户输入错误后看不到任何提示,会以为页面没反应,体验很差。
这样处理后,不管用户输入的是格式错误(用逗号代替点)还是无效日期(比如年份999),应用都不会崩溃,而是友好地显示错误提示,引导用户纠正输入。
内容的提问来源于stack exchange,提问作者Yiour
相关产品推荐
相关产品推荐

