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

Servlet与JSF连接空指针问题求助及JavaEE书籍推荐

排查NullPointerException问题&JavaEE书籍推荐

一、NullPointerException原因分析与解决

你遇到的NPE是因为Servlet从Session中获取section_Model实例时拿到了null,咱们一步步拆解问题根源和修复步骤:

1. Managed Bean的致命冗余代码

你的Section_Model里自己注入了自己:

@Inject
private Section_Model section_Model;

这完全是多余的操作,还会引发循环依赖问题,直接删掉这行代码即可。

2. 核心问题:JSF Bean未被初始化

你在JSF页面里用了普通的HTML <form>提交到Servlet,而非JSF原生的<h:form>:

<form action="inputSections" method="post">

普通HTML表单提交不会触发JSF的生命周期流程,导致你的@SessionScoped注解的Section_Model根本没被创建,Session里自然没有这个属性,Servlet获取时就会得到null,调用sm.getSection()时直接抛出NPE。

修复方案二选一:

方案A:改用JSF表单处理提交(推荐,符合JSF架构设计)

把普通HTML表单替换成JSF组件,让JSF自动管理Bean的生命周期:

<h:form>
    <h:inputText value="#{section_Model.section.nameAlias}" required="true" requiredMessage="The NameAlias field is required."/>
    <h:inputText value="#{section_Model.section.codeSS}"/>
    <h:inputText value="#{section_Model.section.visible}"/>
    <h:commandButton value="Ok" action="#{section_Model.create}"/>
</h:form>

点击按钮时,JSF会自动初始化Section_Model并存入Session,之后如果需要跳转页面,可以在create()方法里返回导航字符串,比如return "testJSF?faces-redirect=true";,完全不需要再用Servlet处理提交逻辑。

方案B:Servlet中手动初始化Bean(不推荐,破坏JSF架构)

如果一定要保留Servlet处理提交,需要在Servlet中先检查Session里的Bean是否存在,不存在则手动创建并放入Session:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("---------------------Begin-----------------------------------------------");
    try {
        HttpSession session = request.getSession();
        Section_Model sm = (Section_Model) session.getAttribute("section_Model");
        // 若Bean不存在,手动创建并放入Session
        if (sm == null) {
            sm = new Section_Model();
            session.setAttribute("section_Model", sm);
        }
        // 处理参数时增加非空判断,避免NumberFormatException
        sm.getSection().setNameAlias(request.getParameter("nameAlias"));
        String codeSSParam = request.getParameter("codeSS");
        if (codeSSParam != null && !codeSSParam.isEmpty()) {
            sm.getSection().setCodeSS((Sections) sm.findSpecific(Integer.parseInt(codeSSParam)));
        }
        String visibleParam = request.getParameter("visible");
        sm.getSection().setVisible(visibleParam != null && Boolean.parseBoolean(visibleParam));
        
        sm.create();
        request.getRequestDispatcher("WEB-INF/testJSF.xhtml").forward(request, response);
    } catch (Exception ex) {
        Logger.getLogger(inputSections.class.getName()).log(Level.SEVERE, null, ex);
    }
}

但这个方案会失去CDI自动注入(比如@Inject、@EJB)的优势,需要手动处理依赖,非常繁琐,所以优先推荐方案A。

3. 其他优化建议

  • 用@PostConstruct代替手动调用init():
    给init()方法加上@PostConstruct注解,这样Bean初始化时会自动执行该方法,无需每次调用create()都手动初始化:
    @PostConstruct
    public void init(){
        controller=new SectionsJpaController(utx, em.getEntityManagerFactory());
    }
    
  • 统一持久层方式:你的Bean里同时用了SectionsFacadeLocal(EJB)和SectionsJpaController,建议选一种方式实现数据库操作,避免代码混乱。比如直接用EJB的sectionsFacade,删掉JpaController相关代码。

二、深入JavaEE书籍推荐

结合你做电商页面、使用JSF搭建分层架构的需求,推荐几本实用的书籍:

  • 《Java EE 8实战》:覆盖Java EE全栈核心技术(JSF、EJB、JPA、CDI等),实战案例丰富,能帮你系统掌握JavaEE,对电商这类企业级应用的架构设计也有参考价值。
  • 《Pro JSF 2.2 and Java EE 8》:专门针对JSF的深入书籍,从基础到高级特性(复合组件、AJAX、CDI集成等)讲解透彻,适合想要精通JSF开发的你。
  • 《Head First Servlets & JSP》:虽然版本稍旧,但对Servlet、JSP的底层原理和基础概念讲解生动易懂,能帮你巩固JavaEE基础,也涉及JSF的入门内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:53:10