NullPointer 试图检索一个整数值

NullPointer trying to retrieve an Integer value

我在 servlet 之间检索数据(整数值)时遇到问题,当时我想乘以检索到的值。我的第一个 servlet 中有这个功能,

        private int totalNumberOf(Map<String,Integer> cart) {
    int counter = 0;

    for (String key : cart.keySet())
        counter += cart.get(key);

    return counter;
}

我也有它的属性(放在 doGet() 方法的末尾)...

        req.setAttribute("quantity", new Integer(totalNumberOf(cart)));

,该函数提供购物车中的产品总数,每次我将商品添加到购物车时都会更新该值,因此当我完成购买时,我可以获得产品数量的更新值当前在购物车中。

现在问题来了,当我尝试进行虚构的结帐时(因为我只有每种产品的通用价格)并且我必须将商品数量乘以通用价格(这里是 NullPointer出现了)。

这是我的第二个 servlet 的代码,

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {

    HttpSession session = req.getSession();

    Integer quantity;
    int toPay;
    int genericValue = 20;

    quantity = (Integer) req.getAttribute("quantity");

    toPay = quantity.intValue() * genericValue; // NullPointer

}

我已经尝试了所有方法,但我无法摆脱那个丑陋的 NullPointer。希望你能帮我一点忙...

更新 Servlet1

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {

    String mensajeBienvenida = "";
    Map<String,Integer> carrito = null;

    String articuloElegido = req.getParameter("producto");

    HttpSession session = req.getSession();

    if (session.isNew()) {
        session.invalidate();
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/error.html");
        dispatcher.forward(req, res);
    }
    else {
        String nombreUsuario = ((Usuario)session.getAttribute("user")).getNombre();
        if (session.getAttribute("carrito") == null) {
            carrito = new HashMap<String,Integer>();
            session.setAttribute("carrito",carrito);
            mensajeBienvenida="Bienvenido a la tienda, " + nombreUsuario + "!";
        }
        else {
            carrito = (Map<String,Integer>) session.getAttribute("carrito");
            mensajeBienvenida = "Qué bien que sigas comprando, " + nombreUsuario + "!";
        }
        insertarEnCarrito(carrito, articuloElegido);
    }
    req.setAttribute("mensaje", mensajeBienvenida);
    req.setAttribute("cesta", cestaDeLaCompraEnHTML(carrito));
    req.setAttribute("cantidad", numeroTotalLibros(carrito));
    RequestDispatcher dispatcher = getServletContext().getNamedDispatcher("VistaTienda");
    dispatcher.forward(req, res);

}

@Override
public void doPost(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {
        doGet( req,res );
}

private void insertarEnCarrito(Map<String,Integer> carrito, String articulo) {
    if (carrito.get(articulo) == null){
        carrito.put(articulo, new Integer(1));
    }
    else {
        int numeroArticulos = (Integer)carrito.get(articulo).intValue();
        carrito.put(articulo, new Integer(numeroArticulos+1));
    }
}

private String cestaDeLaCompraEnHTML(Map<String,Integer> carrito) {
    String cestaEnHTML = "";

    for (String key : carrito.keySet())
        cestaEnHTML += "<p>["+key+"], "+carrito.get(key)+" unidades</p>";
    return cestaEnHTML;
}

private int numeroTotalLibros(Map<String,Integer> carrito) {
    int counterLibro = 0;

    for (String key : carrito.keySet())
        counterLibro += carrito.get(key);

    return counterLibro;
}

}

Servlet2

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {

    String mensajeBienvenida;
    String cestaDeLaCompraEnHTML;

    mensajeBienvenida = (String) req.getAttribute("mensaje");
    cestaDeLaCompraEnHTML = (String) req.getAttribute("cesta");

    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Tienda con login!</TITLE></HEAD>");
    out.println("<BODY>" + mensajeBienvenida + "<br>");
    out.println(cestaDeLaCompraEnHTML + "<br>");
    out.println("PRUEBA CANTIDAD LIBROS EN TOTAL - " + req.getAttribute("cantidad") + "<br>");
    out.println("<a href=\"form.html\">Seguir comprando!</a></BODY></HTML>");
    out.println("<a href=\"login.html\">Anular Compra</a></BODY></HTML>");
    out.println("<a href=\"pagar\">Pagar Compra</a></BODY></HTML>");

}

@Override
public void doPost(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {
        doGet( req,res );
}

Servlet3

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {

    HttpSession session = req.getSession();

    Integer cantidadLibro;
    int pagar;
    int valorLibro = 20;

    Map<String,Integer> carrito = (Map<String,Integer>) session.getAttribute("carrito");
    Usuario usuario = (Usuario) session.getAttribute("user");
    cantidadLibro = (Integer) req.getAttribute("cantidad");

    if (cantidadLibro == null){
        cantidadLibro = 0;
    } else {
        cantidadLibro = (Integer) req.getAttribute("cantidad");
    }

    // pagar = cantidadLibro.intValue() * valorLibro;

    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Tienda con login!</TITLE></HEAD>");
    out.println("<BODY><p><b>COMPRA REALIZADA!</b><br>");
    out.println("<br><p>Total a pagar por su compra - " + "<br>");
    out.println("<br><p>PRUEBA getAttribute - " + req.getAttribute("cantidad") + "<br>");
    out.println("<br><p>Gracias por su compra " + usuario.getNombre() + " " + usuario.getApellidos() + "<br>");
    out.println("<br><p>e-mail del usuario - " + usuario.getEmail() + "<br>");
    out.println("<br><p>User ID - " + usuario.getId() + "<br>");

    session.invalidate();

}

@Override
public void doPost(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {
        doGet( req,res );
}

您听说过 debugging 工具吗?

你的quantity变量有null值,可能是因为请求中的abscense属性quantity。这就是为什么你得到 NPE: null * (primitive numeric constant) -> NullPointerException.

您的 getAttribute 函数可能返回了 null。请记住在代码中进行空检查。我建议您在致电 .intValue()

之前进行 if (quantity != null) 检查

另一种可能的解决方案是检查 .getAttribute() 返回的内容,而不是检查设置的数量。您也可以给数量一个默认值。

if (req.getAttribute("quantity") == null) {
    quantity = 0;
} else {
    quantity = (Integer) req.getAttribute("quantity");
}

从您的代码看来,"quantity.intValue()" 抛出您的空指针,因为数量为空。试试这个:

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException {

HttpSession session = req.getSession();

Integer quantity = 0;
int toPay;
int genericValue = 20;

if (req.getAttribute("quantity") != null) {
  quantity = (Integer) req.getAttribute("quantity");
}


toPay = quantity.intValue() * genericValue; 

}

注意,我不仅将数量初始化为 0(这样它就不是空值),我还向 "req.getAttribute("数量")" 添加了一个空值检查,这样您就不会将空值分配给数量在 .getAttribute returns null.

的情况下

除了您的代码可能需要的重构和优化之外,您提到的问题是您将属性 "cantidad" 设置为请求而不是会话。

在 Servlet1 中,替换这个

req.setAttribute("cantidad", numeroTotalLibros(carrito));

有了这个

session.setAttribute("cantidad", numeroTotalLibros(carrito));

而在 Servlet3 中,替换这个

cantidadLibro = (Integer) req.getAttribute("cantidad");

有了这个

cantidadLibro = (Integer) session.getAttribute("cantidad");

原因是您将请求从 Servlet1 转发到 Servlet2,因此在 Servlet2 中您可以访问 "forwarded" 请求及其所有属性,但 Serlvet3 在稍后阶段被独立调用。我想那是当您在呈现的 HTML 页面中按 "Pagar" 时。因此,您不能再通过该请求访问这些属性,因为它是一个不同的请求。如果您之前将它们存储在那里,您可以改为通过会话访问它们。

希望对您有所帮助。