You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:42:43