2311 字
12 分钟
【WEB】使用NetBeans创建Servlet

前言#

这一章将记录使用 NetBeans 在 Tomcat 中创建 servlet 程序。

Servlet(Ser ver App let) 是运行在 WEB 服务端的小程序,目的是和客户端交互并且生成动态的 web 内容,它可以接收来自客户端的请求并生成响应。

环境搭建#

本篇记录将基于 Java 环境和 Tomcat 服务器创建 Servlet 应用程序,关于集成 Java 环境和 NetBeans 搭建 Tomcat 服务器可以看之前的记录:

https://hoyue.fun/web_tomcat_starthost.html


创建 Servlet 程序#

首先我们必须要新建一个 Web 项目才能创建 servlet 应用,打开 NetBeans IDE,选择 File -> New Project

然后选择 Java Web -> Web Application 创建 Java Web 项目。

给你的 Web 项目起一个名字,例如 hoyue,我们可以点击 browse 选择这个项目存储的位置:

然后选择我们之前创建过的 Tomcat 服务器,path 处可以填写不同的映射地址。

对于 Frameworks 则不需要选择其他的框架,直接点击 Finish。至此 Java Web 项目已经创建完成。

要创建 Servlet,请打开 Source Package,右键单击 -> New -> Servlet

接下来为你的 Servlet 类文件命名,同时也建议自定义 Package(包)名。

PS:Servlet 类文件 没有 main() 方法,它是一个 Java 类,通过覆盖 doGet()doPost() 等方法来处理客户端请求。

接下来,如果在配置部署中勾选了“将信息添加到部署描述符(web.xml)” ,它会自动将你的 servlet 应用注册到 web.xml 中,让 web 程序能自动识别到你的应用。

我们可以修改 URL Pattern(URL 模式),用于定义访问我们的 servlet 应用 URL。

当然还可以通过 @WebServlet 注解来解决,之后也会讲解。如果选择添加 @WebServlet 注解这里请不要勾选。

@WebServlet 注解用于将一个 Java 类声明为 Servlet,并指定它所处理的 URL 模式。

至此就已经创建好了 servlet 应用。


运行 Servlet 应用#

遇到错误问题可以到下面的 Q&A 下查找!

以一个 ServletHello 作为一个测试应用,让它输出 hello world。例如下面的这个程序:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Hello World! servlet
*/
public class ServletHello extends HttpServlet
{
/**
* Respond to any HTTP GET request with an
* HTML Hello World! page.
* @param request
* @param response
* @throws javax.servlet.ServletException
* @throws java.io.IOException
*/
@Override
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Set the HTTP content type in response header
response.setContentType("text/html; charset=\"UTF-8\"");
// Create the body of the response
try ( // Obtain a PrintWriter object for creating the body
// of the response
PrintWriter servletOut = response.getWriter()) {
// Create the body of the response
servletOut.println(
"<!DOCTYPE html \n" +
" PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \n" +
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"> \n" +
"<html xmlns='http://www.w3.org/1999/xhtml'> \n" +
" <head> \n" +
" <title> \n" +
" ServletHello.java \n" +
" </title> \n" +
" </head> \n" +
" <body> \n" +
" <p> \n" +
" Hello World! \n" +
" </p> \n" +
" </body> \n" +
"</html> ");
servletOut.close();
}
}
}

我们可以将这些代码添加到刚才创建好的文件中,替换到 Package 之下(如果你设定了 Package 的名字):

注意:如果代码块区域出现了黄色三角形警告,可以点击自动修复让 NetBeans 帮你修改警告的部分即可。(上述提供的代码已经做出一部分修改)

(下面添加内容仅为没有勾选添加到 web.xml 的用户需要的操作)

如果你之前没有勾选添加到 web.xml 的选项,请添加一些内容用于定义 URL 模式。

我们需要引用一个 javax.servlet.annotation.WebServlet 库和 @WebServlet 注解。

import javax.servlet.annotation.WebServlet;
@WebServlet(name = "ServletHello", urlPatterns = { "/ServletHello" })
// Class 定义之前

我们使用 @WebServlet 注解来定义一个 servlet,并使用 urlPatterns 属性将 HTTP GET 请求映射到 /ServletHello 路径上。当客户端访问这个路径时,将会执行 doGet 方法并将 “Hello, World!” 字符串写入 HTTP 响应中。

然后我们就可以通过这个地址运行访问我们的应用了。选择左侧该 Servlet 应用,点击 Run

接下来设置 URL 模式,这里因为我们这个例子中没有参数,那就直接点击 OK 即可。

然后等待 NetBeans 的部署,完成后就可以在浏览器中查看结果了。我的例子的地址为:http://localhost:8084/hoyue/ServletHello

一般你的地址为:http://hostname:[port]/project_name/servlet_name

成功结果如图:


动态响应案例#

上面的 hello 例子没有体现出 servlet 根据 GET 与 POST 动态反馈内容的能力,下面是一个简单的动态响应案例。

一个博客有一个登录页面和一个评论页面。如果我们正确填写了账号密码就会跳转到评论页面,反之则没有。

博客文件将会被放在项目的 MOBFiles 文件夹下,登录页面为 login.htmladdentry.html 表示一个评论页面,servlet 类文件为 Login.java

我们先创建 servlet 类文件并命名为 Login,在 Package 之后写下如下代码:

代码已做精简(去除暂未使用的 import,并调整路径):

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Login extends HttpServlet {
/**
* Processes requests for both HTTP GET and POST methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
response.sendRedirect("./MOBFiles/login.html");
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String username = request.getParameter("username");
String password = request.getParameter("pwd");
if (username != null && password != null &&
username.equals("nice") &&
password.equals("try")) {
HttpSession session = request.getSession();
session.setAttribute("loggedIn", true);
response.sendRedirect("./MOBFiles/addentry.html");
}
else {
response.sendRedirect("./MOBFiles/login.html");
}
}
}

代码的意思是:

  • doGet 方法中,servlet 发送一个重定向响应到 URL ./MOBFiles/login.html。这意味着当用户使用 HTTP GET 请求访问 servlet 时,他们将被重定向到登录页面。
  • doPost 方法中,servlet 处理 POST 请求,使用 getParameter() 方法从请求中检索 usernamepwd 参数。当两者与正确值 nice/try 匹配时,创建会话并设置 loggedIn=true,再重定向到 ./MOBFiles/addentry.html
  • 否则重定向回登录页面。

接下来就是两个简单的 html 页面及其 CSS 文件,我们把它们放到项目的 MOBFiles 文件夹下(即移动到 web 目录下),如下图:

这些文件放到了网盘中可以直接下载:

当然我们需要修改 login.html 文件中提交的 action,以便于将 POST 内容发送给 servlet。只需要填写 /project_name/Login 即可(根据你的项目名调整)。

最后尝试运行这个 servlet 程序,然后在浏览器中访问它,我设置的地址为 http://localhost:8084/hoyue/Login,一般为 http://hostname:[port]/project_name/Login_name

输入地址后会被重定向到登录页面 login.html

在 servlet 程序中设置的账号为 nice,密码为 try,输入正确后会跳转到评论页面:

如果密码错误则重新返回登录页面:

至此,这是一个简单的根据 GET 与 POST 做出响应的 servlet 程序案例。


Q&A#

下面是一些常见问题与解答,如果遇到了其他问题,欢迎在评论区留言,或通过邮箱等方式联系我

  1. Q:Class “[classname]” neither has a main method nor is it a servlet specified in web.xml

    首先,请注意 在左侧文件中右键运行文件,而不是点击上方的运行键。上方的运行键在部署后将需要 main() 方法,而 servlet 没有 main() 方法。除此之外,这个问题还说明你的 Servlet 类没有在 web.xml 文件中被定义为 servlet:如果你想将你的类作为 servlet 运行,那么你需要在 web.xml 文件中定义它。

    • 如果你在创建 servlet 的时候勾选了 自动添加,请在 Files -> web -> WEB-INF 找到 web.xml,检查 <servlet-name><servlet-class> 是否填写正确;若你修改了文件名,也需要同步修改这里的配置。形如:

      <servlet>
      <servlet-name>Servletname</servlet-name>
      <servlet-class>package_name.Servletname</servlet-class>
      </servlet>
      <servlet-mapping>
      <servlet-name>Servletname</servlet-name>
      <url-pattern>/url</url-pattern>
      </servlet-mapping>
    • 如果你 没有勾选 添加到 web.xml,那么请检查 @WebServlet 注解,例如在 ServletHello 类上添加注解,指定名称为 “MyServlet”,URL 模式为 “/hello”:

      @WebServlet(name = "MyServlet", urlPatterns = { "/hello" })
  2. Q:“HTTP Status 404 – Not Found” 错误

    这通常是由于 servlet 的 URL 映射不正确 导致。确保在 web.xml 文件中或者在 @WebServlet 注解里正确地映射了 servlet 的 URL,并且在浏览器中输入的 URL 与映射匹配。例如项目名为 hoyue,映射 URL 模式为 /ServletHello,则应访问 http://hostname:[port]/hoyue/ServletHello

  3. Q:javax.servlet 不存在

    可能因为没有将 Servlet API 添加到项目依赖。NetBeans 中右键项目 -> Properties -> Libraries -> Add Library,选择 Java EE API(或合适版本)。或将 javax 改为 jakarta 的相应包名。

  4. Q:Tomcat 部署时报错,StandardWrapperValve.invoke 分配异常、ClassNotFoundException

    通常是 Tomcat 找不到你的 servlet 类文件。确认 web.xml 的类名与包名一致;或将编译产物打成 JAR 放置到 Tomcat 的 lib 目录,让类加载器可见。

  5. Q:Can’t import javax.servlet.annotation.WebServlet

    请确认 Tomcat 版本并多尝试构建。可在 web.xml 头部添加如下声明以启用 3.0 规范:

    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://www.java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  6. Q:没用到的 import 头

    可以删除,没有影响。

  7. Q:头部报错 incorrect package

    如果创建时未设置包名,将位于 default package,不需要 package 语句;若自定义了包名,需要在头部使用 package xxx; 声明,例如:package servlet;

  8. Q:类名与文件名不匹配

    Java 要求 public 类名与文件名一致。请检查类名与文件名是否一致。


后记#

这一章记录了使用 NetBeans 在 Tomcat 中创建 servlet 程序的一些简单细节。

【WEB】使用NetBeans创建Servlet
https://hoyue.fun/web_servlet.html
作者
Hoyue
发布于
2023-04-30
最后更新于
2023-05-17
许可协议
CC BY-NC-SA 4.0
评论