Featured image of post Servlet接口

Servlet接口

servlet三种方法的实现

项目结构概览

通常,Java Web 项目的结构会类似于如下的目录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
your-webapp/
├── src/                (Java源代码)
│   └── com/
│       └── example/
│           └── HelloWorldServlet.java
├── webapp/             (Web应用的根目录,所有静态文件和配置文件放在这里)
│   ├── WEB-INF/        (存放配置文件及不对外暴露的内容)
│   │   ├── web.xml     (Servlet配置文件)
│   │   └── classes/    (编译后的.class文件)
│   └── index.html      (可以访问的首页)
└── lib/                (项目依赖的jar包)

主要文件夹的功能说明:

src/:存放你的源代码文件(Java文件)。

webapp/:这是 Web 应用的根目录,包含所有可以公开访问的资源,比如 HTML、CSS、JavaScript 文件等。

WEB-INF/:这是一个特殊的目录,存放 web 应用的配置文件和服务器无法直接访问的资源。

WEB-INF/web.xml:部署描述符文件,用来配置 Servlet、过滤器等组件的映射关系(当不使用注解时)。

WEB-INF/classes/:存放编译后的 .class 文件。你开发的 Java 代码经过编译后会放在这个文件夹里。

WEB-INF/lib/:存放依赖的 .jar 包。

文件放置位置说明

Java 源代码(Servlet)的位置

源代码 (HelloWorldServlet.java) 应该放在 src 目录下的包结构中,例如:

src/com/example/HelloWorldServlet.java 这遵循标准的 Java 包管理机制,方便代码管理和构建。

编译后的 .class 文件

编译后的 Servlet 类 (HelloWorldServlet.class) 应该被放在 WEB-INF/classes/ 目录下,对应的包路径下。编译时,你的构建工具(如 Maven、Gradle,或 IDE)会将源代码编译后的 .class 文件自动放在这里。例如:

WEB-INF/classes/com/example/HelloWorldServlet.class 这保证了 Servlet 能被服务器识别和加载,但外部用户无法直接访问 .class 文件。

web.xml 文件

如果你没有使用注解来配置 Servlet(如 @WebServlet),你需要手动配置 WEB-INF/web.xml 文件来映射 Servlet。例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<web-app>
    <servlet>
        <servlet-name>HelloWorldServlet</servlet-name>
        <servlet-class>com.example.HelloWorldServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloWorldServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

这样配置后,当用户访问 http://localhost:8080/your-webapp/hello,会触发 HelloWorldServlet。

HTML 页面

如果有静态 HTML 文件(如 index.html),你可以直接将它们放在 webapp 根目录中,比如:

webapp/index.html 这可以让你在访问 http://localhost:8080/your-webapp/ 时直接看到这个页面。

文件的组织结构实例

假设你的 HelloWorldServlet 实现位于 com.example 包中,那么完整的项目结构会像这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
your-webapp/
├── src/
│   └── com/
│       └── example/
│           └── HelloWorldServlet.java  (Servlet源码)
├── webapp/
│   ├── WEB-INF/
│   │   ├── web.xml                    (Servlet配置)
│   │   └── classes/
│   │       └── com/
│   │           └── example/
│   │               └── HelloWorldServlet.class (Servlet编译后的类文件)
│   └── index.html                     (可以直接访问的首页)
└── lib/                                (项目依赖的jar包)

运行步骤

编译Java代码:

将 src/com/example/HelloWorldServlet.java 编译并输出到 WEB-INF/classes/ 目录中。可以使用构建工具如 Maven 或者手动通过 javac 命令来编译:

1
javac -d webapp/WEB-INF/classes src/com/example/HelloWorldServlet.java

启动服务器:

启动 Web 容器(如 Apache Tomcat),并将整个 your-webapp/ 目录作为 Web 应用部署。 访问 Servlet:

使用浏览器访问 http://localhost:8080/your-webapp/hello,你应该能够看到Hello, World!的响应。

总结

源代码应该放在 src 目录中。 编译后的 .class 文件需要放在 WEB-INF/classes 中的正确包结构下。 静态资源如 HTML 文件直接放在 webapp 根目录中,供浏览器访问。 web.xml 文件配置 Servlet 的映射关系,放在 WEB-INF 目录下。 这样做符合 Java Web 项目标准,并且能够让 Tomcat 或其他 Servlet 容器正确运行你的 Servlet。

servlet三种方法的实现。

  1. 项目结构规划 按照典型的 Java Web 应用结构,项目的目录应该如下:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
your-webapp/
├── src/                (Java源代码)
│   └── com/
│       └── example/
│           ├── HelloWorldServlet.java    (继承HttpServlet实现)
│           ├── AnnotationServlet.java    (注解@WebServlet实现)
│           └── GenericServletExample.java (继承GenericServlet实现)
├── webapp/
│   ├── WEB-INF/
│   │   ├── web.xml                       (配置Servlet映射)
│   │   └── classes/                      (编译后的.class文件)
│   └── index.html                        (可以直接访问的首页)
└── lib/                                   (项目依赖的jar包)
  1. Servlet 实现的三种方法

方法 1: 继承 HttpServlet

步骤:继承 HttpServlet,重写 doGet()doPost() 方法来处理 HTTP 请求。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.example;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

public class HelloWorldServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello, World from HttpServlet!</h1>");
    }
}

配置 web.xml(用于映射 URL 到 Servlet):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<web-app>
    <servlet>
        <servlet-name>HelloWorldServlet</servlet-name>
        <servlet-class>com.example.HelloWorldServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloWorldServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

方法 2: 使用注解 @WebServlet 步骤:直接通过 @WebServlet 注解来配置 Servlet,而不需要修改 web.xml 文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.example;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/annotation")
public class AnnotationServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello, World from AnnotationServlet!</h1>");
    }
}

注解配置:使用 @WebServlet 注解可以省去 web.xml 配置。只需编译后在 Tomcat 上部署即可访问 /annotation。

方法 3: 继承 GenericServlet 步骤:继承 GenericServlet,重写 service() 方法,处理所有请求类型。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.example;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;

public class GenericServletExample extends GenericServlet {
    @Override
    public void service(ServletRequest request, ServletResponse response) 
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello, World from GenericServlet!</h1>");
    }
}

配置 web.xml:

1
2
3
4
5
6
7
8
<servlet>
    <servlet-name>GenericServletExample</servlet-name>
    <servlet-class>com.example.GenericServletExample</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>GenericServletExample</servlet-name>
    <url-pattern>/generic</url-pattern>
</servlet-mapping>

项目结构和文件配置

源代码目录 (src/):存放 Servlet 的源代码文件。

  • HelloWorldServlet.java、AnnotationServlet.java、GenericServletExample.java 放在 src/com/example/ 目录下。

webapp/WEB-INF/web.xml:

  • web.xml 中配置 HelloWorldServlet 和 GenericServletExample 的映射。
  • AnnotationServlet 不需要 web.xml 配置。

HTML 文件 (index.html):

  • 可以在 webapp/ 目录中添加一个简单的 index.html 文件作为测试入口页面。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
    <title>Servlet Test</title>
</head>
<body>
    <h1>Welcome to the Servlet Test</h1>
    <ul>
        <li><a href="hello">HelloWorldServlet (HttpServlet)</a></li>
        <li><a href="annotation">AnnotationServlet (@WebServlet)</a></li>
        <li><a href="generic">GenericServletExample (GenericServlet)</a></li>
    </ul>
</body>
</html>

编译与部署

编译步骤: 手动编译 Java 源文件:

在项目根目录中,使用 javac 编译源代码,并将生成的 .class 文件放入 WEB-INF/classes 对应的目录结构中。例如:

1
javac -d webapp/WEB-INF/classes src/com/example/HelloWorldServlet.java src/com/example/AnnotationServlet.java src/com/example/GenericServletExample.java

目录结果检查:

编译后的 .class 文件应位于 webapp/WEB-INF/classes/com/example/ 目录下,结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
your-webapp/
├── webapp/
│   ├── WEB-INF/
│   │   ├── web.xml
│   │   └── classes/
│   │       └── com/
│   │           └── example/
│   │               ├── HelloWorldServlet.class
│   │               ├── AnnotationServlet.class
│   │               └── GenericServletExample.class
│   └── index.html

部署步骤:

将项目部署到 Tomcat:

  • 将整个 your-webapp 目录打包为 .war 文件,或者直接将 webapp/ 目录拷贝到 Tomcat 的 webapps 文件夹下。

启动 Tomcat:

  • 启动 Tomcat 服务器,项目会自动部署。

访问 Servlet:

  • 通过浏览器访问不同的 URL 来测试不同的 Servlet:
  • http://localhost:8080/your-webapp/hello (访问 HelloWorldServlet)
  • http://localhost:8080/your-webapp/annotation (访问 AnnotationServlet)
  • http://localhost:8080/your-webapp/generic (访问 GenericServletExample)

测试与验证

通过访问不同的 URL,验证每个 Servlet 是否能够正常处理请求,并返回相应的响应。 检查浏览器中是否显示:

“Hello, World from HttpServlet!"(方法1)

“Hello, World from AnnotationServlet!"(方法2)

“Hello, World from GenericServlet!"(方法3)

问题

运行时出现问题

1
2
3
4
5
PS C:\app\cod_tool\program_tool\jet\idea_fil\demo909010> javac -d webapp/WEB-INF/classes src/main/java/root.demo909010/HttpServletcn.java              
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en
error: file not found: src\main\java\root.demo909010\HttpServletcn.java
Usage: javac <options> <source files>
use --help for a list of possible options

从给出的错误信息来看,Java编译器javac无法找到指定的源文件src\main\java\root.demo909010\HttpServletcn.java。

文件路径错误:提供的文件路径可能不正确或者文件名有误。

文件不存在:指定的Java源文件可能并不在src\main\java\root.demo909010\目录下。

大小写敏感:文件系统是大小写敏感的,所以你需要确保文件路径和文件名的大小写完全匹配。

当前工作目录错误:可能当前的工作目录并不是命令行中显示的C:\app\cod_tool\program_tool\jet\idea_fil\demo909010>。

在初次修改之后

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
PS C:\app\cod_tool\program_tool\jet\idea_fil\demo909010> javac -d webapp\WEB-INF\classes src\main\java\root\demo909010\HttpServletcn.java 
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en
src\main\java\root\demo909010\HttpServletcn.java:4: error: package javax.servlet does not exist
import javax.servlet.ServletException;
                    ^
src\main\java\root\demo909010\HttpServletcn.java:5: error: package javax.servlet.http does not exist
import javax.servlet.http.HttpServlet;
                         ^
src\main\java\root\demo909010\HttpServletcn.java:6: error: package javax.servlet.http does not exist
import javax.servlet.http.HttpServletRequest;
                         ^
src\main\java\root\demo909010\HttpServletcn.java:7: error: package javax.servlet.http does not exist
import javax.servlet.http.HttpServletResponse;
                         ^
src\main\java\root\demo909010\HttpServletcn.java:11: error: cannot find symbol
public class HttpServletcn extends HttpServlet {
                                   ^
  symbol: class HttpServlet
src\main\java\root\demo909010\HttpServletcn.java:12: error: cannot find symbol
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
                         ^
  symbol:   class HttpServletRequest
  location: class HttpServletcn
src\main\java\root\demo909010\HttpServletcn.java:12: error: cannot find symbol
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
                                                     ^
  symbol:   class HttpServletResponse
  location: class HttpServletcn
src\main\java\root\demo909010\HttpServletcn.java:13: error: cannot find symbol
            throws ServletException, IOException {
                   ^
  symbol:   class ServletException
  location: class HttpServletcn
8 errors

从错误信息来看,编译器无法找到javax.servlet和javax.servlet.http这两个包中的类。这通常意味着缺少Servlet API的依赖。

缺少Servlet API依赖:你的项目中没有包含Servlet API的jar文件,或者编译器没有找到这个jar文件。

类路径(Classpath)问题:即使你的项目中有Servlet API的jar文件,但是编译器没有将其包含在类路径中。

我使用的idea会自动把servlet放在一个外部库里面

在这种情况下,IDEA已经自动将Servlet API作为一个外部库添加到了项目中,那么在IDEA内部进行编译和运行时通常不会出现问题,因为IDEA会自动处理类路径(Classpath)。

然而,如果在命令行手动编译Java文件,需要确保手动指定正确的类路径,以便编译器可以找到Servlet API和其他依赖项。

以下是一些步骤,以确保在命令行编译时正确设置类路径:

查找IDEA配置的类路径:

打开IDEA,进入“File”菜单,选择“Project Structure”(快捷键通常是Ctrl+Alt+Shift+S)。

在“Project Structure”窗口中,选择“Modules”。

选择你的模块,然后查看“Dependencies”标签页。

在这里,可以看到所有已添加的库,包括外部库。对于Servlet API,通常会看到它的路径和版本。

手动设置类路径:

在命令行中,使用-cp或-classpath选项来指定类路径。你需要包括Servlet API的jar文件路径,以及可能需要的其他库。

如果不确定具体的路径,可以从IDEA的“Project Structure”中复制。

例如,如果在IDEA中看到Servlet API的外部库路径是C:\Users\YourUsername.m2\repository\javax\servlet\javax.servlet-api\4.0.1\javax.servlet-api-4.0.1.jar,那么命令行编译命令应该类似于:

1
javac -cp "C:\Users\YourUsername\.m2\repository\javax\servlet\javax.servlet-api\4.0.1\javax.servlet-api-4.0.1.jar";webapp/WEB-INF/classes -d webapp/WEB-INF/classes src/main/java/root/demo909010/HttpServletcn.java

注意,在Windows中,类路径的元素之间是用分号;分隔的,而在Unix/Linux/macOS中是用冒号:分隔的。

最终使用这个命令解决:

1
javac -cp "C:\app\cod_tool\web_tool\tomcat\tomcat9\tomcat9\lib\servlet-api.jar" -d src\main\webapp\WEB-INF\classes src\main\java\root\demo909010\GenericServletcn.java
Licensed under CC BY-NC-SA 4.0
Good Morning, and in case I don't see you, good afternoon, good evening, and good night!
使用 Hugo 构建
主题 StackJimmy 设计