1.定义
Servlet 是运行在服务器上的 Java 程序,用于处理客户端的 HTTP 请求并生成响应。
工作流程:
- 客户端(如浏览器)发送 HTTP 请求到服务器。
- Servlet 容器(如 Tomcat)将请求转发给对应的 Servlet。
- Servlet 处理请求并生成响应。
- Servlet 容器将响应返回给客户端。
2.Servlet 的核心方法
Servlet 通过实现 javax.servlet.Servlet
接口或继承 HttpServlet
类实现。以下是常用的核心方法:
-
生命周期方法:
init()
:在 Servlet 被初始化时调用,执行一次。service()
:每次请求时调用,根据请求类型调用doGet()
或doPost()
。destroy()
:在 Servlet 被销毁前调用,执行一次。
-
常用 HTTP 方法:
doGet(HttpServletRequest req, HttpServletResponse resp)
:处理 GET 请求。doPost(HttpServletRequest req, HttpServletResponse resp)
:处理 POST 请求。
3.创建第一个 Servlet
Servlet 执行原理
servlet方法
_Servlet_3.0注解配置
Request原理
-
Request 和 Response 对象的原理:
- 它们由服务器创建,供开发者使用。
- Request 对象用于获取请求信息(如客户端发送的数据)。
- Response 对象用于设置和发送响应信息(如返回给客户端的内容)。
简单理解:
- Request 是客户端发给服务器的请求载体。
- Response 是服务器给客户端的响应载体。
Request原理通常涉及计算机网络和Web开发中的请求(Request)机制,主要指客户端向服务器发送请求,服务器根据请求返回响应的过程。具体来说,这个原理可以应用于HTTP请求、API请求等多个场景。以下是关于请求原理的一些关键点:
1. HTTP请求的基本过程
- 客户端发起请求:当用户在浏览器中输入网址,或某个应用程序调用Web API时,客户端通过网络向服务器发送HTTP请求。
- DNS解析:浏览器会先通过域名解析系统(DNS)将域名转换为IP地址,找到目标服务器的地址。
- TCP连接建立:客户端与服务器之间通过三次握手建立TCP连接,确保数据的可靠传输。
- 发送HTTP请求:客户端构造一个HTTP请求,并通过TCP连接发送给服务器。HTTP请求包含请求行(如请求方法GET、POST等)、请求头、请求体(可选)等。
- 服务器处理请求:服务器接收到请求后,解析请求信息并处理,可能会访问数据库、执行程序等。
- 服务器响应:服务器处理完请求后,通过HTTP响应返回结果,响应中包含状态码、响应头和响应体(如HTML页面、JSON数据等)。
- 客户端处理响应:客户端接收到服务器的响应后,进行展示、存储或进一步操作。
2. 请求方法(HTTP Methods)
HTTP定义了多种请求方法,常见的有:
- GET:请求服务器获取资源,通常不包含请求体,数据通过URL传递。
- POST:向服务器提交数据,通常用于提交表单数据或上传文件。
- PUT:用于更新资源,通常将新的数据替换掉原有的资源。
- DELETE:删除指定资源。
- PATCH:对资源进行部分更新。
3. 请求头(Request Headers)
请求头包含了请求的相关信息,如:
- User-Agent:标识发出请求的客户端软件(浏览器、App等)。
- Accept:指示客户端可以处理的响应内容类型。
- Content-Type:请求体的类型,通常用于POST请求,指明请求体的数据格式。
- Authorization:携带身份验证信息,用于验证客户端身份。
4. 请求体(Request Body)
请求体用于携带请求数据,通常用于POST、PUT等方法。当需要向服务器发送大量数据(如提交表单、上传文件等)时,数据会包含在请求体中。
5. 状态码(Status Code)
服务器对请求的响应通常包含一个HTTP状态码,表示请求的处理结果:
- 2xx:成功处理(如200 OK、201 Created)。
- 3xx:重定向(如301 Moved Permanently、302 Found)。
- 4xx:客户端错误(如400 Bad Request、404 Not Found)。
- 5xx:服务器错误(如500 Internal Server Error、502 Bad Gateway)。
获取请求行代码
package com.example.demo2;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import javax.ws.rs.GET;
import java.io.IOException;
@WebServlet("/ServletDemoo")
public class ServletDemoo extends HttpServlet {
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取请求参数: get
System.out.println(request.getMethod());
// 2获取虚拟目录
System.out.println(request.getContextPath());
// 3.获取Servlet路径
System.out.println(request.getServletPath());
//4.获取get方式请求参数
System.out.println(request.getQueryString());
//5.获取请求URI
System.out.println(request.getRequestURI());
//6.获取请求URL
System.out.println(request.getRequestURL());
//7.获取协议版本
System.out.println(request.getProtocol());
//8.获取客户机的IP地址
System.out.println(request.getRemoteAddr());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
访问地址
http://localhost:8080/demo2_war_exploded/ServletDemoo?name=zhangsan
运行截图
获取请求头代码
Servlet处理get请求并提取客户端发送的关键信息
package com.example.demo;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/requestDemo3")
public class RequestDemo3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 暂时不处理POST请求,可以根据需求补充逻辑
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 演示获取请求头数据: User-Agent
String agent = request.getHeader("user-agent"); // 获取浏览器的 User-Agent 信息
// 判断 agent 的浏览器版本
if (agent.contains("Chrome")) {
// 谷歌浏览器
System.out.println("谷歌来了...");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
System.out.println("火狐来了...");
} else {
// 其他浏览器
System.out.println("其他浏览器来了...");
}
}
}
请求地址
运行截图
获取请求体数据
后端代码
package com.example.demo2;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.BufferedReader;
import java.io.IOException;
@WebServlet("/demo2_war_exploded/demo2/requestDemo5")
public class RequestDemo5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 返回提示信息
response.getWriter().write("请通过POST方法提交表单");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求编码,防止中文乱码
BufferedReader br = request.getReader();
// 2. 读取数据
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line); // 打印读取到的数据
}
}
}
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<form action="demo2_war_exploded/demo2/requestDemo5" method="post">
<!-- 输入用户名 -->
<input type="text" placeholder="请输入用户名" name="username"><br>
<!-- 输入密码 -->
<input type="text" placeholder="请输入密码" name="password"><br>
<!-- 提交按钮 -->
<input type="submit" value="注册">
</form>
</body>
</html>
访问路径
http://localhost:8080/demo2_war_exploded/demo2_war_exploded/demo2/requestDemo5
控制台截图
Request请求转发
服务器在内部进行资源跳转
访问一容器 ,一容器去访问二容器的方法
代码
package com.example.demo2; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet(name = "Servlet9", value = "/Servlet9") public class Servlet9 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("servlet9被访问了"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
package com.example.demo2; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet(name = "Servlet9", value = "/Servlet9") public class Servlet9 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("servlet9被访问了"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
访问8接口的同时9也被访问了
运行截图
共享数据
示例代码
package com.example.demo2;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servlet8", value = "/Servlet8")
public class Servlet8 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet8 被访问了");
// 设置一个请求标志,避免重复转发
Object isForwarded = request.getAttribute("isForwardedByServlet8");
if (isForwarded == null) {
// 设置标志,表示该请求已经由 Servlet8 转发
request.setAttribute("isForwardedByServlet8", true);
request.setAttribute("message", "这是从 Servlet8 转发的请求");
// 转发到 Servlet9
request.getRequestDispatcher("/Servlet9").forward(request, response);
} else {
// 如果请求已经被转发,直接返回响应,避免递归
response.getWriter().write("请求已由 Servlet8 转发,不能再次转发!");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
package com.example.demo2;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servlet9", value = "/Servlet9")
public class Servlet9 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet9 被访问了");
// 获取从 Servlet8 中设置的请求参数
Object message = request.getAttribute("message");
if (message != null) {
// 如果从 Servlet8 转发过来,则输出消息
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h1>Servlet9 接收到的消息:</h1>");
response.getWriter().write("<p>" + message + "</p>");
} else {
// 如果不是从 Servlet8 转发过来,直接响应
response.getWriter().write("直接访问了 Servlet9,没有转发消息!");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
访问地址截图
控制台运行截图
获取Servletcontext
ServletContext
是一个共享对象,用于在整个 Web 应用程序中存储共享的数据或获取全局配置。
package com.example.demo2;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/getServletContextFromRequest")
public class GetServletContextFromRequest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 通过 request 获取 ServletContext
ServletContext servletContext = request.getServletContext();
// 打印 ServletContext 对象信息
System.out.println("通过 request 获取 ServletContext: " + servletContext);
// 输出其他信息
System.out.println("服务器信息: " + servletContext.getServerInfo());
}
}
访问地址截图
运行截图