java - 尝试在 Head First Servlets 和 JSP 中重现示例时出现 NullPointerException
问题描述
我正在重现 Head First Servlets 和 JSP Ch.5 中的示例,该示例展示了 Servlet 上下文侦听器的工作原理。实现书中的代码后,我得到了NullPonterException
.
servlet [ListenerTester] 在路径 [/ServletContextListenerPractice] 的上下文中的 Servlet.service() 引发异常 java.lang.NullPointerException
查了好几遍,肯定和书上的代码是一样的,除了文件路径。我设置了文件路径,就像com.example.web
本书使用com.example
. 任何人都知道问题是什么?
ListenerTester.java
package com.example.web;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
/**
* Servlet implementation class ListenerTester
*/
@WebServlet("/ListenerTester")
public class ListenerTester extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
public ListenerTester() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("test context attributes set by listener<br>");
out.println("<br>");
Dog dog = (Dog) getServletContext().getAttribute("dog");
// render brand name to client
out.println("The brand is " + dog.getBreed());
}
}
狗.java
package com.example.web;
public class Dog {
private String breed;
public Dog(String breed) {
this.breed = breed;
}
public String getBreed() {
return breed;
}
}
MyServletContextListener.java
package com.example.web;
import javax.servlet.*;
public class MyServletContextListener implements ServletContextListener {
public void contextInitilized(ServletContextEvent event) {
ServletContext sc = event.getServletContext();
String dogBreed = sc.getInitParameter("breed");
Dog d = new Dog(dogBreed);
// set Dog reference, d, as attribute on Servlet Context
sc.setAttribute("dog", d);
}
public void contextDestroyed(ServletContextEvent event) {
// do nothing
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<servlet>
<servlet-name>ListenerTester</servlet-name>
<servlet-class>com.example.web.ListenerTester</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListenerTester</servlet-name>
<url-pattern>/ListenTest.do</url-pattern>
</servlet-mapping>
<context-param>
<param-name>breed</param-name>
<param-value>Beta</param-value>
</context-param>
<listener>
<listener-class>
com.example.web.MyServletContextListener
</listener-class>
</listener>
</web-app>
解决方案
您拼写错误contextInitialized
,但编译器并不介意,因为您没有告诉它您打算覆盖超类中的方法,ServletContextListener
. 如果您添加@Override
注释来告诉编译器您的意图,它将验证您实际上是在覆盖超类方法。
public class MyServletContextListener implements ServletContextListener {
@Override // this one gives a compiler error because it doesn't override anything
public void contextInitilized(ServletContextEvent event) {
// . . .
}
@Override // this one doesn't complain because it does override a method
public void contextInitialized(ServletContextEvent event) {
// . . .
}
// this one compiles just fine, even though the name is spelled wrong
public void contextInitilized(ServletContextEvent event) {
// . . .
}
public void contextDestroyed(ServletContextEvent event) {
// do nothing
}
}
拥有一个名为contextInitilized
;的新方法是完全合法的。它也是完全没用的,不会做你所期望的。
推荐阅读
- c++ - 无法使用来自非 QT 应用程序的 TCP 套接字在 QT 中捕获数据
- oracle - 从 Tomcat 7 迁移到 Tomcat 9 后启动 Tomcat 的问题
- bash - 使用 bash 减少输出
- scala - log4j:向 Log Analytics 发送日志记录事件时出错
- hadoop - 聚合条件存储在另一个表中的数据
- azure - Azure 媒体服务播放没有资产和输出对象的视频
- apache-spark - 如何确保火花作业在具有所有指定的 minExecutor 之前不应启动
- swift - 当从 GeometryReader 中进行更改时,SwiftUI 不会反映对 @Binding @State 变量的更改
- python-3.x - 查找 numpy 数组上的所有最大值
- javascript - Foreach 在 foreach 中,同时附加到结果 div