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三种方法的实现。
- 项目结构规划
按照典型的 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包)
|
- 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:
访问 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
|