小服务程序 - requestDispatcher.forward java.lang.NullPointerException
Servlet - requestDispatcher.forward java.lang.NullPointerException
我正在做一个网络服务器作为在线商店应用程序的一部分,我正在尝试使表单 jsp 页面正常工作。我将 Eclipse IDE 与 Maven 和 Jetty 插件一起使用来尝试。
它是这样的:
用户在 index.jsp 欢迎页面按下按钮,向 AddProductoServlet 提交 GET 请求。这是加载 "tiendas"(商店) 列表并将其传递到 jsp 页面所必需的,这样用户就可以从下拉列表中选择一个 (select html元素)
这是 AddProductoServlet 中的 GET 方法:
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
logger.debug("doGet de AddProductoServlet");
// llamada al servicio para pedir la lista de tiendas en la BD
// TODO añadir metodo a la clase conversora para meter listas de tiendas
//List<TiendaWTO> tiendaWTOs = TiendaTOtoTiendaWTOConversor.toTiendaWTO(productoService.getTiendas());
// Test
List<String> tiendaWTOs = new ArrayList<String>();
tiendaWTOs.add("El Rincón de José");
tiendaWTOs.add("El bar de Antonio");
tiendaWTOs.add("Pezuñita comics");
request.setAttribute("tiendas", tiendaWTOs);
// TODO lo que viene a continuacion en el ejemplo de servjsptutorial
// va en una clase aparte y se llama a la función forwardTo
RequestDispatcher requestDispatcher = request.getRequestDispatcher("AddProducto.jsp");
requestDispatcher.forward(request, response);
}
这里是 jsp 页面 AddProducto:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
import="java.util.Map,
java.util.List" %>
<html>
<head>
<title>Nosa Tenda - Crear producto</title>
</head>
<body text="#000000" bgcolor="#ffffff">
<%-- Get errors. --%>
<%
String nombreErrorMessage = "";
String imagenErrorMessage = "";
String precioErrorMessage = "";
String stockErrorMessage = "";
String tiendaErrorMessage = "";
Map<String, String> errors = (Map<String, String>) request.getAttribute("errors");
if (errors != null) {
String errorHeader = "<font color=\"red\"><b>";
String errorFooter = "</b></font>";
if (errors.containsKey("nombre")) {
nombreErrorMessage = errorHeader + errors.get("nombre") +
errorFooter;
}
if (errors.containsKey("imagen")) {
imagenErrorMessage = errorHeader + errors.get("imagen") +
errorFooter;
}
if (errors.containsKey("precio")) {
precioErrorMessage = errorHeader + errors.get("precio") +
errorFooter;
}
if (errors.containsKey("stock")) {
stockErrorMessage = errorHeader + errors.get("stock") +
errorFooter;
}
if (errors.containsKey("tienda")) {
tiendaErrorMessage = errorHeader + errors.get("tienda") +
errorFooter;
}
}
String nombre = request.getParameter("nombre");
if (nombre==null) {
nombre="";
}
String descripcion = request.getParameter("descripcion");
if (descripcion==null) {
descripcion="";
}
String imagen = request.getParameter("imagen");
if (imagen==null) {
imagen="";
}
String precio = request.getParameter("precio");
if (precio==null) {
precio="";
}
String stock = request.getParameter("stock");
if (stock==null) {
stock="";
}
List<String> tiendas = (List<String>) request.getAttribute("tiendas");
//response.setContentType("charset=UTF-8");
%>
<div align="center">
<p>
<font color="#000099" face="Arial, Helvetica, san-serif">
<b>Crear producto</b>
</font>
</p>
</div>
<form method="POST" action="AddProducto">
<table width="100%" border="0" align="center" cellspacing="12">
<%-- Nombre --%>
<tr>
<th align="right" width="50%">
Nombre
</th>
<td align="left">
<input type="text" name="nombre"
value="<%= nombre %>"
size="64" maxlength="100">
<%= nombreErrorMessage %>
</td>
</tr>
<%-- Descripcion --%>
<tr>
<th align="right" width="50%">
Descripción
</th>
<td align="left">
<textarea name="descripcion"
rows="8" cols="40" maxlength="450"><%= descripcion %></textarea>
</td>
</tr>
<%-- Imagen --%>
<tr>
<th align="right" width="50%">
URL de la imagen
</th>
<td align="left">
<textarea name="imagen"
rows="8" cols="40" maxlength="450"><%= imagen %></textarea>
<%= imagenErrorMessage %>
</td>
</tr>
<%-- Precio --%>
<tr>
<th align="right" width="50%">
Precio
</th>
<td align="left">
<input type="text" name="precio"
value="<%= precio %>"
size="9" maxlength="8">
<%= precioErrorMessage %>
</td>
</tr>
<%-- Stock --%>
<tr>
<th align="right" width="50%">
Stock
</th>
<td align="left">
<input type="text" name="stock"
value="<%= stock %>"
size="9" maxlength="8">
<%= stockErrorMessage %>
</td>
</tr>
<%-- Tienda --%>
<tr>
<th align="right" width="50%">
Tienda
</th>
<td align="left">
<select name="tiendaId">
<% for (int i=0; i < tiendas.size(); i++) { %>
<option value="<%= tiendas.get(i) %>"><%= tiendas.get(i) %></option>
<% } %>
</select>
<%= tiendaErrorMessage %>
</td>
</tr>
<%-- Create button --%>
<tr>
<td width="50%"></td>
<td align="left" width="50%">
<input type="submit" value="Crear producto">
</td>
</tr>
</table>
</form>
</body>
</html>
至此一切正常,页面加载并且下拉列表已正确填充。请注意,现在我正在使用模拟来加载商店名称,稍后将调用 Web 服务和数据库之间的服务,但现在这并不重要。
现在,当用户按下表单的提交按钮时,我下一步要做的是调用 AddProductoServlet 的 post 方法并检查表单字段:如果没有错误,它重定向到成功页面。我已经测试过它,它可以工作,并且从调试中我知道所有参数都正确地传递给了 servlet:
response.sendRedirect("AddProductoExito.jsp?id="
+ 1);
当有任何错误时问题就来了,这一行被称为:
requestDispatcher.forward(request, response);
这是整个 doPost 方法:
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
logger.debug("doPost de AddProductoServlet");
Map<String, String> errors = new HashMap<String, String>();
String nombre = request.getParameter("nombre");
String descripcion = request.getParameter("descripcion");
String imagen = request.getParameter("imagen");
String precio = request.getParameter("precio");
String stock = request.getParameter("stock");
//Long tiendaId = Long.parseLong(request.getParameter("tiendaId"));
String tiendaId = request.getParameter("tiendaId");
// validamos campos
PropertyValidator.validateMandatory(errors, "nombre", nombre);
PropertyValidator.validateMandatory(errors, "imagen", imagen);
double precioAsDouble = PropertyValidator.validateDouble(errors,
"precio", precio, true, 0, Double.MAX_VALUE);
long stockAsLong = PropertyValidator.validateLong(errors,
"stock", stock, true, 0, Long.MAX_VALUE);
/*long tiendaIdAsLong = PropertyValidator.validateLong(errors,
"tiendaId", tiendaId, true, 0, Long.MAX_VALUE);*/
if (!errors.isEmpty()) {
request.setAttribute("errors", errors);
// TODO lo que viene a continuacion en el ejemplo de servjsptutorial
// va en una clase aparte y se llama a la función forwardTo
RequestDispatcher requestDispatcher = request.getRequestDispatcher("AddProducto.jsp");
requestDispatcher.forward(request, response);
} else {
// llamada al servicio para insertar producto
// TODO usar productoWTO (meter clase conversora en la linea siguiente)
/*ProductoTO insertedProducto = productoService.newProducto(
nombre,
descripcion,
imagen,
precio,
stock,
tiendaId);
response.sendRedirect("AddProductoExito.jsp?id="
+ insertedProducto.getId());*/
// Test
response.sendRedirect("AddProductoExito.jsp?id="
+ 1);
}
所有这些的 objective 将在出错的情况下再次加载 AddProducto.jsp,但这次在屏幕上显示错误(字段旁边的一些红色文本表示有错误问题),并显示之前在文本字段中填写的内容。
这是我得到的 NullPointerException 错误的堆栈跟踪。提到的 AddProductoServlet 的第 85 行对应于我之前提到的'requestDispatcher.forward(request, response);':
2015-01-29 12:01:24.877:WARN:oejs.ServletHandler:
org.apache.jasper.JasperException: java.lang.NullPointerException
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:276)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:103)
at es.udc.jcastedo.NosaTenda.webservice.service.web.servlets.AddProductoServlet.doPost(AddProductoServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:695)
Caused by:
java.lang.NullPointerException
at org.apache.jsp.AddProducto_jsp._jspService(AddProducto_jsp.java from :233)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:403)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:276)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:103)
at es.udc.jcastedo.NosaTenda.webservice.service.web.servlets.AddProductoServlet.doPost(AddProductoServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:695)
2015-01-29 12:01:24.880:WARN:oejs.ServletHandler:/NosaTenda-webservice/AddProducto
java.lang.NullPointerException
at org.apache.jsp.AddProducto_jsp._jspService(AddProducto_jsp.java from :233)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:403)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:276)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:103)
at es.udc.jcastedo.NosaTenda.webservice.service.web.servlets.AddProductoServlet.doPost(AddProductoServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:695)
所以现在我卡住了。不知道为什么会发生该错误。该调用与 GET 方法中的调用相同,工作正常。
我已经调试过了,路径是正确的,和之前一样。尽管如此,我已经尝试了几种组合,因为它似乎出于某种原因找不到 jsp 页面,例如 /AddProducto.jsp 和其他,但无济于事。
我也在这个页面和其他页面上对类似的问题进行了研究,但没有。配置看起来不错,因为所有其他 servlet 都可以正常工作。
我在这里错过了什么?谢谢。
谈论过于复杂的事情...在这里我在想 doGet 和 doPost 对同一页面的两次连续调用有些不对劲,可能响应或请求的属性已损坏或其他原因,甚至更糟的是,配置有问题……不,当然,一旦您注意到它,就会像往常一样更简单、更明显。
简单地说,"tiendas" 引用没有在 doPost 中再次生成,因为出于某种原因我认为它仍然附加到请求中。因此,当 jsp 页面尝试执行 "tiendas.get(i)" 时,显然它没有找到变量并抛出 NullPointerException。
也是因为我缺乏调试页面的能力,所以我把重点放在了servlet上,没想到异常实际上是页面抛出的。
感谢并向为此投入时间的任何人道歉,我的错误。
我正在做一个网络服务器作为在线商店应用程序的一部分,我正在尝试使表单 jsp 页面正常工作。我将 Eclipse IDE 与 Maven 和 Jetty 插件一起使用来尝试。
它是这样的:
用户在 index.jsp 欢迎页面按下按钮,向 AddProductoServlet 提交 GET 请求。这是加载 "tiendas"(商店) 列表并将其传递到 jsp 页面所必需的,这样用户就可以从下拉列表中选择一个 (select html元素)
这是 AddProductoServlet 中的 GET 方法:
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
logger.debug("doGet de AddProductoServlet");
// llamada al servicio para pedir la lista de tiendas en la BD
// TODO añadir metodo a la clase conversora para meter listas de tiendas
//List<TiendaWTO> tiendaWTOs = TiendaTOtoTiendaWTOConversor.toTiendaWTO(productoService.getTiendas());
// Test
List<String> tiendaWTOs = new ArrayList<String>();
tiendaWTOs.add("El Rincón de José");
tiendaWTOs.add("El bar de Antonio");
tiendaWTOs.add("Pezuñita comics");
request.setAttribute("tiendas", tiendaWTOs);
// TODO lo que viene a continuacion en el ejemplo de servjsptutorial
// va en una clase aparte y se llama a la función forwardTo
RequestDispatcher requestDispatcher = request.getRequestDispatcher("AddProducto.jsp");
requestDispatcher.forward(request, response);
}
这里是 jsp 页面 AddProducto:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
import="java.util.Map,
java.util.List" %>
<html>
<head>
<title>Nosa Tenda - Crear producto</title>
</head>
<body text="#000000" bgcolor="#ffffff">
<%-- Get errors. --%>
<%
String nombreErrorMessage = "";
String imagenErrorMessage = "";
String precioErrorMessage = "";
String stockErrorMessage = "";
String tiendaErrorMessage = "";
Map<String, String> errors = (Map<String, String>) request.getAttribute("errors");
if (errors != null) {
String errorHeader = "<font color=\"red\"><b>";
String errorFooter = "</b></font>";
if (errors.containsKey("nombre")) {
nombreErrorMessage = errorHeader + errors.get("nombre") +
errorFooter;
}
if (errors.containsKey("imagen")) {
imagenErrorMessage = errorHeader + errors.get("imagen") +
errorFooter;
}
if (errors.containsKey("precio")) {
precioErrorMessage = errorHeader + errors.get("precio") +
errorFooter;
}
if (errors.containsKey("stock")) {
stockErrorMessage = errorHeader + errors.get("stock") +
errorFooter;
}
if (errors.containsKey("tienda")) {
tiendaErrorMessage = errorHeader + errors.get("tienda") +
errorFooter;
}
}
String nombre = request.getParameter("nombre");
if (nombre==null) {
nombre="";
}
String descripcion = request.getParameter("descripcion");
if (descripcion==null) {
descripcion="";
}
String imagen = request.getParameter("imagen");
if (imagen==null) {
imagen="";
}
String precio = request.getParameter("precio");
if (precio==null) {
precio="";
}
String stock = request.getParameter("stock");
if (stock==null) {
stock="";
}
List<String> tiendas = (List<String>) request.getAttribute("tiendas");
//response.setContentType("charset=UTF-8");
%>
<div align="center">
<p>
<font color="#000099" face="Arial, Helvetica, san-serif">
<b>Crear producto</b>
</font>
</p>
</div>
<form method="POST" action="AddProducto">
<table width="100%" border="0" align="center" cellspacing="12">
<%-- Nombre --%>
<tr>
<th align="right" width="50%">
Nombre
</th>
<td align="left">
<input type="text" name="nombre"
value="<%= nombre %>"
size="64" maxlength="100">
<%= nombreErrorMessage %>
</td>
</tr>
<%-- Descripcion --%>
<tr>
<th align="right" width="50%">
Descripción
</th>
<td align="left">
<textarea name="descripcion"
rows="8" cols="40" maxlength="450"><%= descripcion %></textarea>
</td>
</tr>
<%-- Imagen --%>
<tr>
<th align="right" width="50%">
URL de la imagen
</th>
<td align="left">
<textarea name="imagen"
rows="8" cols="40" maxlength="450"><%= imagen %></textarea>
<%= imagenErrorMessage %>
</td>
</tr>
<%-- Precio --%>
<tr>
<th align="right" width="50%">
Precio
</th>
<td align="left">
<input type="text" name="precio"
value="<%= precio %>"
size="9" maxlength="8">
<%= precioErrorMessage %>
</td>
</tr>
<%-- Stock --%>
<tr>
<th align="right" width="50%">
Stock
</th>
<td align="left">
<input type="text" name="stock"
value="<%= stock %>"
size="9" maxlength="8">
<%= stockErrorMessage %>
</td>
</tr>
<%-- Tienda --%>
<tr>
<th align="right" width="50%">
Tienda
</th>
<td align="left">
<select name="tiendaId">
<% for (int i=0; i < tiendas.size(); i++) { %>
<option value="<%= tiendas.get(i) %>"><%= tiendas.get(i) %></option>
<% } %>
</select>
<%= tiendaErrorMessage %>
</td>
</tr>
<%-- Create button --%>
<tr>
<td width="50%"></td>
<td align="left" width="50%">
<input type="submit" value="Crear producto">
</td>
</tr>
</table>
</form>
</body>
</html>
至此一切正常,页面加载并且下拉列表已正确填充。请注意,现在我正在使用模拟来加载商店名称,稍后将调用 Web 服务和数据库之间的服务,但现在这并不重要。
现在,当用户按下表单的提交按钮时,我下一步要做的是调用 AddProductoServlet 的 post 方法并检查表单字段:如果没有错误,它重定向到成功页面。我已经测试过它,它可以工作,并且从调试中我知道所有参数都正确地传递给了 servlet:
response.sendRedirect("AddProductoExito.jsp?id="
+ 1);
当有任何错误时问题就来了,这一行被称为:
requestDispatcher.forward(request, response);
这是整个 doPost 方法:
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
logger.debug("doPost de AddProductoServlet");
Map<String, String> errors = new HashMap<String, String>();
String nombre = request.getParameter("nombre");
String descripcion = request.getParameter("descripcion");
String imagen = request.getParameter("imagen");
String precio = request.getParameter("precio");
String stock = request.getParameter("stock");
//Long tiendaId = Long.parseLong(request.getParameter("tiendaId"));
String tiendaId = request.getParameter("tiendaId");
// validamos campos
PropertyValidator.validateMandatory(errors, "nombre", nombre);
PropertyValidator.validateMandatory(errors, "imagen", imagen);
double precioAsDouble = PropertyValidator.validateDouble(errors,
"precio", precio, true, 0, Double.MAX_VALUE);
long stockAsLong = PropertyValidator.validateLong(errors,
"stock", stock, true, 0, Long.MAX_VALUE);
/*long tiendaIdAsLong = PropertyValidator.validateLong(errors,
"tiendaId", tiendaId, true, 0, Long.MAX_VALUE);*/
if (!errors.isEmpty()) {
request.setAttribute("errors", errors);
// TODO lo que viene a continuacion en el ejemplo de servjsptutorial
// va en una clase aparte y se llama a la función forwardTo
RequestDispatcher requestDispatcher = request.getRequestDispatcher("AddProducto.jsp");
requestDispatcher.forward(request, response);
} else {
// llamada al servicio para insertar producto
// TODO usar productoWTO (meter clase conversora en la linea siguiente)
/*ProductoTO insertedProducto = productoService.newProducto(
nombre,
descripcion,
imagen,
precio,
stock,
tiendaId);
response.sendRedirect("AddProductoExito.jsp?id="
+ insertedProducto.getId());*/
// Test
response.sendRedirect("AddProductoExito.jsp?id="
+ 1);
}
所有这些的 objective 将在出错的情况下再次加载 AddProducto.jsp,但这次在屏幕上显示错误(字段旁边的一些红色文本表示有错误问题),并显示之前在文本字段中填写的内容。
这是我得到的 NullPointerException 错误的堆栈跟踪。提到的 AddProductoServlet 的第 85 行对应于我之前提到的'requestDispatcher.forward(request, response);':
2015-01-29 12:01:24.877:WARN:oejs.ServletHandler:
org.apache.jasper.JasperException: java.lang.NullPointerException
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:276)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:103)
at es.udc.jcastedo.NosaTenda.webservice.service.web.servlets.AddProductoServlet.doPost(AddProductoServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:695)
Caused by:
java.lang.NullPointerException
at org.apache.jsp.AddProducto_jsp._jspService(AddProducto_jsp.java from :233)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:403)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:276)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:103)
at es.udc.jcastedo.NosaTenda.webservice.service.web.servlets.AddProductoServlet.doPost(AddProductoServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:695)
2015-01-29 12:01:24.880:WARN:oejs.ServletHandler:/NosaTenda-webservice/AddProducto
java.lang.NullPointerException
at org.apache.jsp.AddProducto_jsp._jspService(AddProducto_jsp.java from :233)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:403)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:276)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:103)
at es.udc.jcastedo.NosaTenda.webservice.service.web.servlets.AddProductoServlet.doPost(AddProductoServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:695)
所以现在我卡住了。不知道为什么会发生该错误。该调用与 GET 方法中的调用相同,工作正常。
我已经调试过了,路径是正确的,和之前一样。尽管如此,我已经尝试了几种组合,因为它似乎出于某种原因找不到 jsp 页面,例如 /AddProducto.jsp 和其他,但无济于事。
我也在这个页面和其他页面上对类似的问题进行了研究,但没有。配置看起来不错,因为所有其他 servlet 都可以正常工作。
我在这里错过了什么?谢谢。
谈论过于复杂的事情...在这里我在想 doGet 和 doPost 对同一页面的两次连续调用有些不对劲,可能响应或请求的属性已损坏或其他原因,甚至更糟的是,配置有问题……不,当然,一旦您注意到它,就会像往常一样更简单、更明显。
简单地说,"tiendas" 引用没有在 doPost 中再次生成,因为出于某种原因我认为它仍然附加到请求中。因此,当 jsp 页面尝试执行 "tiendas.get(i)" 时,显然它没有找到变量并抛出 NullPointerException。
也是因为我缺乏调试页面的能力,所以我把重点放在了servlet上,没想到异常实际上是页面抛出的。
感谢并向为此投入时间的任何人道歉,我的错误。