【问题标题】:Calling session bean from servlet vs jsp->servlet grants different result从 servlet 与 jsp->servlet 调用会话 bean 授予不同的结果
【发布时间】:2014-02-28 15:02:21
【问题描述】:

我在尝试调用会话 bean 的方法时遇到问题,首先从 JSP 调用 servlet,然后 servlet 调用会话 bean 的方法来获取一些数据,它似乎得到了 NullPointerException。另一方面,如果我只是自己运行 servlet,它会完成这项工作并从会话 bean 中检索数据。

以下是servlet的代码;

    package web;

import java.io.IOException;
import java.util.ArrayList;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import auction.ItemRegistrationSessionBeanRemote;

/**
 * Servlet implementation class processItem
 */
@WebServlet("/processItem")
public class processItem extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public ArrayList<String> categories = new ArrayList<String>();
    @EJB ItemRegistrationSessionBeanRemote itemRegistrationSession;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public processItem() {
        super();
    }

   @PostConstruct
    public
    void init() {
       System.out.println("init()");
       categories = itemRegistrationSession.getCategories();
       System.out.println("init() categories = " + categories.toString());

    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}

    @PostConstruct
    public void obtainCategories() {
        categories = itemRegistrationSession.getCategories();

    }
    @PostConstruct
    public ArrayList<String> getCategories() {
        return categories;
    }
}

这是调用servlet的JSP部分:

<jsp:useBean id="obj" scope="page" class="web.processItem" />
<select name="affiliation" id="categories-dropdown">
<% obj.init(); %>
<c:forEach var="aff" items="${obj.getCategories()}"
<%System.out.println("categories = " + obj.getCategories()); %>
<option value="${aff}">${aff}</option>
</c:forEach>
</select> 

这是会话 Bean:

package auction;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.sun.jersey.spi.resource.Singleton;

import entity.Category;

/**
 * Session Bean implementation class ItemRegistrationSessionBean
 */
@Stateful @Singleton
public class ItemRegistrationSessionBean implements ItemRegistrationSessionBeanRemote {

    @PersistenceContext(name = "MiniEbayEJB")
    private EntityManager emgr;
    /**
     * Default constructor. 
     */
    public ItemRegistrationSessionBean() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public ArrayList<String> getCategories() {
        System.out.println("Hello from SessionBean getCategories");
        ArrayList<String> categories = new ArrayList<String>(); 
        List<Category> obtainedCategories = (List<Category>) emgr.createNamedQuery("Category.findAll", Category.class).getResultList();
        for (int i = 0; i < obtainedCategories.size(); i++) {
            categories.add(obtainedCategories.get(i).toString());
            System.out.println("Current ArrayList of categories = " + categories);
        }
        return categories;
    }

}

这是从 jsp->servlet->session bean 调用时的堆栈跟踪:

2014-02-28T14:48:21.696+0000|WARNING: StandardWrapperValve[jsp]: PWC1406: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
    at web.processItem.init(processItem.java:35)
    at org.apache.jsp.insert_jsp._jspService(insert_jsp.java:166)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:411)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:744)

【问题讨论】:

    标签: java jsp servlets ejb session-bean


    【解决方案1】:

    您不能像您那样从 JSP 调用“servlet”实例。 你实际做了什么:

    <jsp:useBean id="obj" scope="page" class="web.processItem" />
    

    是创建一个 web.processItem 的“新”实例,它根本不是容器管理的 - 因此它没有你的依赖项。

    仅 servlet 调用确实有效,因为容器确实创建并管理了 processItem 的实例,并且您注入了依赖项。

    【讨论】:

    • 有没有办法从 jsp 调用 servlet 以便它由 contrainer 管理?谢谢你的解释
    • 通常情况相反。您有一个 URL,它映射到一个 Servlet,并调用 JSP 来表示视图。如果要调用 Servlet,只需从 JSP 转发或重定向到 servlet。或者只是将您的列表放入 servlet 中的 pageContext 并使用您的 JSP 呈现它。只需使用您未在您的 servlet 中实现的 doGet 方法,将结果 - 您的列表等放入 pageContext(通过请求对象上的 setAttribute)并在 jsp 中呈现您的 html,您就完成了。
    猜你喜欢
    • 2011-02-09
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多