如何从JSF EL表达式向CDI生产者传递上下文信息?
解决方案
首先需要明确:你写的带@CurrencyLocale限定符的生产者写法不符合CDI的工作逻辑——CDI生产者的方法参数是用来注入其他Bean实例的,不是用来接收JSF EL传入的动态参数的。@CurrencyLocale作为限定符,CDI会尝试寻找被该注解修饰的String类型Bean来注入,而不是接收你从展示数据里拿到的动态Locale值。
针对你的需求,最直接的解决方式是重构代码,将原来的生产者改为普通的@Named Bean方法,具体步骤如下:
1. 重构CDI生产者为普通Bean
替换原来的生产者代码为一个带命名的Bean,包含带参数的货币获取方法:
@Named("currencyService") @ApplicationScoped public class CurrencyService { public String getCurrency(String locale) { return CurrencyUtil.getCurrencyCodeByLocale(locale); } }
2. 修改JSF EL表达式
在EL中直接调用带参数的方法,传入展示数据中的Locale值:
#{currencyService.getCurrency(item.locale)}
这里的item.locale替换为你实际从展示数据中获取Locale的表达式(比如#{product.locale}、#{order.customerLocale}等)。
可选方案(CDI生产者方式)
如果坚持要用CDI生产者,需要将动态Locale存入一个请求作用域的Holder Bean中,再让生产者注入该Holder:
步骤1:创建Locale Holder Bean
@RequestScoped public class RequestLocaleHolder { private String locale; // Getter & Setter public String getLocale() { return locale; } public void setLocale(String locale) { this.locale = locale; } }
步骤2:修改生产者注入Holder
@Produces @Named("currency") @ApplicationScoped public String getCurrency(RequestLocaleHolder localeHolder) { return CurrencyUtil.getCurrencyCodeByLocale(localeHolder.getLocale()); }
步骤3:在展示数据前设置Locale
在页面或后端代码中,先设置Holder的Locale值(比如在遍历展示数据时):
<!-- 示例:在遍历数据时设置Locale --> <c:forEach items="#{dataList}" var="item"> <f:setPropertyActionListener target="#{requestLocaleHolder.locale}" value="#{item.locale}" /> 货币代码:#{currency} </c:forEach>
这种方式相对繁琐,仅适合必须使用CDI生产者的场景。
内容的提问来源于stack exchange,提问作者Tactical Downvote
相关产品推荐
相关产品推荐

