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

PrimeFaces PickList选择值触发NullPointerException问题求助

问题原因及解决方案

根因分析

NullPointerException 源于 PickListView 使用了 @RequestScoped 作用域。每次AJAX请求(比如选择事件)都会创建一个新的Bean实例。在验证阶段,PickList组件会对比旧模型(新Bean实例中@PostConstruct初始化的模型)与新模型,但选择事件并不会提交完整的PickList值,导致新模型为null,触发空指针异常。

解决方案

  1. 将 PickListView 的作用域从 @RequestScoped 改为 @ViewScoped,确保Bean在同一个视图的所有AJAX请求中保持状态。
  2. 让 PickListView 实现 Serializable 接口,这是 @ViewScoped 作用域的强制要求。

修改后的 PickListView 代码:

import org.primefaces.event.SelectEvent;
import org.primefaces.event.TransferEvent;
import org.primefaces.event.UnselectEvent;
import org.primefaces.model.DualListModel;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ViewScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
 
@Named
@ViewScoped
public class PickListView implements Serializable {

    @Inject
    private CountryService service; 
    private DualListModel<Country> countries;

    @PostConstruct
    public void init() {   
        //Countries
        List<Country> countriesSource = service.getCountries().subList(0, 10);
        List<Country> countriesTarget = new ArrayList<>();

        countries = new DualListModel<>(countriesSource, countriesTarget);

    }
     public CountryService getService() {
        return service;
    }

    public void setService(CountryService service) {
        this.service = service;
    }

    public DualListModel<Country> getCountries() {
        return countries;
    }

    public void setCountries(DualListModel<Country> countries) {
        this.countries = countries;
    }

    public void onTransfer(TransferEvent event) {
        StringBuilder builder = new StringBuilder();
        for (Object item : event.getItems()) {
            builder.append(((Country) item).getName()).append("<br />");
        }

        FacesMessage msg = new FacesMessage();
        msg.setSeverity(FacesMessage.SEVERITY_INFO);
        msg.setSummary("Items Transferred");
        msg.setDetail(builder.toString());

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onSelect(SelectEvent<Country> event) {
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Item Selected", event.getObject().getName()));
    }

    public void onUnselect(UnselectEvent<Country> event) {
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Item Unselected", event.getObject().getName()));
    }

    public void onReorder() {
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "List Reordered", null));
    }
}

补充说明

@ViewScoped 作用域会在用户停留在当前视图期间保持Bean的状态,非常适合处理单页面内的AJAX交互,既避免了@RequestScoped的状态丢失问题,又不会像@SessionScoped那样长期占用资源。

内容的提问来源于stack exchange,提问作者Najlae Cherkaoui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:29:52