【问题标题】:Spring @Controller, Validator and JSF <h:messages /> tagSpring @Controller、Validator 和 JSF <h:messages /> 标签
【发布时间】:2013-12-10 15:32:09
【问题描述】:

我有一个 Spring MVC @Controller(带有一个 Spring Validator)和一个 JSF 页面。

我想要的是使用 JSF &lt;h:messages /&gt; 标记在 JSF 页面中显示 验证错误

据我所知:

  • MessageContext + MessageBuilder 适用于 webflows 但不适用于 @Controller
  • 我已阅读有关 Validation 的 Spring 文档,似乎(最后一段)唯一的方法是使用 Spring MVC 标签。

¿有没有办法在不使用 Spring MVC 标签的情况下从我的 @Controller Validator 显示 &lt;h:messages /&gt; 的错误?

【问题讨论】:

    标签: spring jsf spring-mvc


    【解决方案1】:

    默认情况下没有。

    您可以做的是创建一个实现postHandle 方法的HandlerInterceptor(我假设您对所有事情都使用普通的Spring MVC)。在此方法中,您可以查找 BindingResult 类型的所有模型属性,从中检索所有错误并将它们传输到 JSF。

    这样的东西应该可以工作(还没有测试过,取决于你进一步使用的东西)

    public class ErrorTransferingInterceptor extends HandlerInterceptorAdapter implements MessageSourceAware {
    
        private MessageSource messageSource;
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            FacesContext ctx = FacesContext.getCurrentInstance();
            for (Object o : modelAndView.getModel().values() ) {
                if (o instanceof Errors) {
                    Errors result = (Errors) o;
                    for (ObjectError err : result.getAllErrors() ) {
                        String msg = messageSource.getMessage(err, LocaleContextHolder.getLocale());
                        if (err instanceof FieldError) {
                            ctx.addMessage(((FieldError) err).getField(), new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, null));
                        } else {
                            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, null));
                        }
                    }
                }
            }
        }
    
        @Override
        public void setMessageSource(MessageSource messageSource) {
            this.messageSource=messageSource;
        }
    }
    

    【讨论】:

    • 谢谢 Deinum 先生。只有1个问题。 FacesContext 此时为null。正如我所见,在 Spring JsfView 实际创建 FacesContext 之前,处理程序被执行 (DispatcherServlet)。我们即将找到解决方案... ;)
    • 拍摄,你是对的。但是您使用的是JsfView,这也意味着您使用的是Spring Web Flow。使用自定义ViewFactory 代替拦截器,它返回自定义JsfView,将消息放入FacesContext。当前的JsfView 不这样做。
    【解决方案2】:

    在玩弄了 Spring 和 JSF 消息集成之后,最后我发现最简单的方法是:

    • 直接在应用程序控制器中添加人脸消息(尽管@M. Deinum 展示了一种架构解决方案)
    • 使用 jsf 验证器代替 spring 验证器,仍然可以访问 spring 上下文

    这行得通,我认为这是一个干净的集成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多