后面比赛挺多,RW体验赛,西湖论剑,beginCTF,N1CTF,hgame,NSS新春赛,NSS Round17,SICTF,有观赏性大于操作性的,有萌新可以真正去打的。经过慎重考虑,决定java先暂放几天,再回过头去练练老题,也是换换脑子。
目录
Servlet
工作流程:
实现方式:
生命周期:
Tomcat
HttpServletRequest对象
接收请求
请求转发
request域对象
HttpServletResponse对象
响应数据
重定向
请求转发和输出重定向的区别
Cookie对象
创建和发送Cookie
获取Cookie
设置Cookie的过期时间
Cookie的路径
HttpSession对象
JSESSIONID
session域对象
session对象的销毁
ServletContext对象
ServletContext对象的获取
ServletContext域对象
Servlet的三大域对象
Servlet 是 Java Web 应用程序开发中非常重要的组件,它可以接收来自客户端的 HTTP 请求并生成相应的 HTTP 响应。
客户端发送 HTTP 请求到服务器。
服务器接收请求,并根据请求 URL 找到对应的 Servlet。
服务器创建一个 HttpServletRequest 对象和一个 HttpServletResponse 对象,并将它们作为参数传递给 Servlet 的 service() 方法。
在 service() 方法中,Servlet 根据请求类型(GET、POST 等)调用 doGet() 或 doPost() 等方法来处理请求。
处理完成后,Servlet 将生成的响应内容写入 HttpServletResponse 对象,然后将其返回给服务器。
服务器将响应发送给客户端,并关闭连接。
Servlet 可以通过两种方式来实现:继承 HttpServlet 类或实现 Servlet 接口。其中,继承 HttpServlet 类的方式是最常用的方式,它可以大大简化 Servlet 的编写过程。
下面是一个实现 Servlet 接口的示例代码:
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig config) throws ServletException {
// 初始化方法,可选
}
@Override
public void service(ServletRequest req, ServletResponse resp)
throws ServletException, IOException {
// 处理请求的方法
resp.getWriter().println("Hello, Servlet!");
}
@Override
public void destroy() {
// 销毁方法,可选
}
@Override
public ServletConfig getServletConfig() {
// 获取 Servlet 配置信息,可选
return null;
}
@Override
public String getServletInfo() {
// 获取 Servlet 信息,可选
return null;
}
}
Servlet 的生命周期可以分为三个阶段:初始化阶段、服务阶段和销毁阶段。
初始化阶段:在 Servlet 被创建时调用,用于完成一些初始化操作。可以通过实现 init() 方法来实现。
服务阶段:在接收到客户端请求时调用,用于处理请求并生成响应。可以通过实现 service() 方法来实现。
销毁阶段:在 Servlet 被销毁时调用,用于完成一些清理操作。可以通过实现 destroy() 方法来实现。
下面是一个 Servlet 生命周期的示例代码:
public class HelloServlet extends HttpServlet {
@Override
public void init() throws ServletException {
// 初始化方法
System.out.println("Servlet 初始化");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 处理 GET 请求
resp.getWriter().println("Hello, Servlet!");
}
@Override
public void destroy() {
// 销毁方法
System.out.println("Servlet 销毁");
}
}
Tomcat 是一个开源的 Java Web 服务器,是 Apache 软件基金会的 Jakarta 项目的一部分,也是目前最为流行的 Java Web 服务器之一。它实现了 Java Servlet、JavaServer Pages(JSP)和 WebSocket 等规范,提供了一个容器来运行基于 Java 技术的 Web 应用程序。
当客户端发送 HTTP 请求到服务器时,Servlet 容器会创建一个 HttpServletRequest 对象来表示该请求,并将其作为参数传递给 Servlet 的 service() 方法。HttpServletRequest 提供了一系列方法来获取请求的各种信息。
下面是 HttpServletRequest 接收请求的示例代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求的方法
String method = request.getMethod();
// 获取请求的 URL
String url = request.getRequestURL().toString();
// 获取请求的查询字符串
String queryString = request.getQueryString();
// 获取请求的参数
String paramValue = request.getParameter("paramName");
// 获取请求的头部信息
String headerValue = request.getHeader("headerName");
// 获取请求的客户端 IP 地址
String ipAddress = request.getRemoteAddr();
// ... 其他操作
}
请求转发是指将当前的请求转发给另一个资源进行处理,可以是 Servlet、JSP 或其他 Web 资源。使用 HttpServletRequest 的 forward() 方法进行请求转发:
RequestDispatcher dispatcher = request.getRequestDispatcher("/path/to/resource");
dispatcher.forward(request, response);
在请求转发中,原始请求的属性和参数会保留,并且目标资源可以通过 request 对象获取这些数据。
HttpServletRequest 还提供了 request 域对象,它是一个存储和共享数据的容器,在同一次请求中的不同组件之间共享数据。可以通过以下方式向 request 作用域中存储数据:
request.setAttribute("key", value);
其他组件可以通过 request 对象获取该数据:
Object value = request.getAttribute("key");
request 作用域的生命周期只在当前请求内有效,一旦请求结束,request 作用域中的数据将被销毁。
HttpServletResponse 对象代表了服务器对客户端的响应,它提供了一系列方法来设置响应的各种信息。
在 HttpServletResponse 中,我们可以使用 getWriter() 或者 getOutputStream() 方法获取一个输出流来向客户端发送响应数据。
下面是 HttpServletResponse 发送响应数据的示例代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应的编码
response.setCharacterEncoding("UTF-8");
// 设置响应的内容类型
response.setContentType("text/html;charset=UTF-8");
// 向客户端发送响应数据
PrintWriter out = response.getWriter();
out.write("");
out.write("Hello World ");
out.write("");
out.write("Hello World
");
out.write("");
out.write("");
out.close();
}
如果在调用 getOutputStream() 方法之前已经调用了 getWriter() 方法,或者在调用 getWriter() 方法之前已经调用了 getOutputStream() 方法,将会抛出 IllegalStateException 异常。因此,在使用 HttpServletResponse 输出响应数据时,只能使用其中的一个方法,不能两个方法同时使用。
重定向是指将当前请求重定向到另一个 URL 上,可以是同一个 Web 应用程序内的 URL,也可以是其他 Web 应用程序的 URL。使用 HttpServletResponse 的 sendRedirect() 方法进行重定向:
response.sendRedirect("/path/to/resource");
请求转发和重定向是两种常用的 web 应用程序之间的跳转方式。
请求转发是服务器内部的跳转,请求对象、响应对象等信息都会被保留,并且不会改变浏览器地址栏中的 URL。它的过程是,由一个 Servlet 对象调用另一个 Servlet 对象的方法,然后将请求和响应传递给另一个 Servlet 处理。
相比之下,重定向是服务器对浏览器的响应,浏览器接收到响应后会重新向指定的 URL 发起请求,因此会改变浏览器地址栏中的 URL。重定向会丢失原始请求的属性和参数,因为它是两个完全独立的请求。
总之一句话:
请求转发是服务器内部的跳转,保留了浏览器地址栏中的 URL 和原始请求的属性和参数;重定向是服务器对浏览器的响应,改变了浏览器地址栏中的 URL 并且丢失了原始请求的属性和参数。
使用 Cookie 的构造函数创建了一个名为 "username",值为 "Z3r4y" 的Cookie对象。然后使用 setPath()
方法设置Cookie的路径为根路径 "/",表示该Cookie在整个应用程序中都可用。最后,使用 response.addCookie()
方法将Cookie发送到客户端。
Cookie cookie = new Cookie("username", "Z3r4y");
cookie.setPath("/");
response.addCookie(cookie);
使用 request.getCookies()
方法获取客户端发送的所有Cookie,并将它们存储在一个 Cookie 数组中。然后,我们可以遍历数组,逐个获取每个Cookie的名称和值
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
// 处理Cookie的逻辑
}
}
在 Cookie 中,可以通过 setMaxAge(int maxAge)
方法来设置 Cookie 的过期时间。该方法的参数是一个整数值,表示 Cookie 在客户端上存在的时间(以秒为单位)。
当设置这个值为负数时,表示该 Cookie 会在浏览器关闭时自动删除。当设置为0时,表示该 Cookie 立即过期,将被删除。当设置为正数时,表示该 Cookie 在指定的秒数后过期,并将被删除。
需要注意以下几点:
举例:
// 创建一个名为 "username",值为 "Z3r4y" 的Cookie对象
Cookie cookie = new Cookie("username", "Z3r4y");
// 设置Cookie的过期时间为1小时(以秒为单位)
cookie.setMaxAge(3600);
// 发送Cookie到客户端
response.addCookie(cookie);
Cookie 的路径表示 Cookie 在服务器上可用的路径范围。默认情况下,Cookie 的路径是当前请求的路径。可以使用 setPath()
方法来设置 Cookie 的路径。
例如,如果将路径设置为 "/",则该 Cookie 在整个应用程序中都可用。如果将路径设置为 "/path",则该 Cookie 仅在以 "/path" 开头的 URL 中可用。
JSESSIONID 是用来唯一标识会话的标识符,它存储在客户端的 Cookie 中。当客户端与服务器建立起会话时,服务器会为该会话创建一个唯一的 JSESSIONID,并将其存储在名为 "JSESSIONID" 的 Cookie 中,然后将该 Cookie 发送给客户端。在客户端再次向服务器发送请求时,会包含该 Cookie,服务器通过解析该 Cookie 中的 JSESSIONID 来获取对应的 HttpSession 对象。
// 获取 JSESSIONID(从请求中的 Cookie 中获取)
Cookie[] cookies = request.getCookies();
String jsessionId = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("JSESSIONID")) {
jsessionId = cookie.getValue();
break;
}
}
}
通过 request.getSession()
方法获取 HttpSession 对象。如果客户端已经有一个有效的会话(即已存在与 JSESSIONID 相关联的 HttpSession 对象),则返回该 HttpSession 对象;否则,创建一个新的 HttpSession 对象。
// 使用 HttpSession 对象存储和获取会话数据
HttpSession session = request.getSession();
// 存储会话数据
session.setAttribute("username", "John");
// 获取会话数据
String username = (String) session.getAttribute("username");
// 销毁会话
session.invalidate();
当涉及到会话对象的销毁时,有几种情况需要考虑。
1.默认时间到期:会话对象通常具有一个默认的到期时间。这个时间是由服务器配置文件中的会话超时设置决定的。一旦会话超过设定的时间没有活动,服务器将自动将其标记为无效并销毁。具体的默认超时时间可以在服务器配置文件中进行设置。
2.自定义到期时间:除了使用默认的到期时间,还可以在代码中自定义会话的到期时间。可以通过 setMaxInactiveInterval(int interval)
方法来设置会话的最大非活动间隔时间(以秒为单位)。一旦会话超过指定的时间没有活动,服务器将自动将其标记为无效并销毁。示例代码如下:
// 设置会话的最大非活动间隔时间为30分钟
session.setMaxInactiveInterval(1800);
3.立即失效:也可以通过调用 invalidate()
方法来立即使会话对象失效。这会将会话对象标记为无效,并清除与会话相关联的任何数据。示例代码如下:
// 立即使会话对象失效
session.invalidate();
4.关闭浏览器:当客户端关闭浏览器时,会话对象通常会保持有效状态一段时间,具体取决于服务器的配置。在这段时间内如果客户端再次打开浏览器并发送请求,会话对象仍然是有效的。但是,一旦会话超过设定的超时时间或服务器重启,会话将被销毁。
5.关闭服务器:当服务器关闭或重启时,所有会话对象都将被销毁。这意味着与该服务器相关联的所有会话数据都将丢失,并且所有客户端将需要重新建立会话。
通过以下方式来获取ServletContext对象:
1.通过request对象获取ServletContext对象
ServletContext context = request.getServletContext();
2.通过session对象获取ServletContext对象
ServletContext context = session.getServletContext();
3.通过servletConfig对象获取ServletContext对象
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
}
ServletContext域对象是一个全局的域对象,用于在整个Web应用程序中共享数据。
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = getServletContext();
// 设置属性值
String value = "Hello, ServletContext!";
context.setAttribute("key", value);
// 转发到Servlet2
RequestDispatcher dispatcher = request.getRequestDispatcher("/servlet2");
dispatcher.forward(request, response);
}
}
@WebServlet("/servlet2")
public class Servlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = getServletContext();
// 获取属性值
String value = (String) context.getAttribute("key");
response.getWriter().println(value);
}
}
1.request域对象
在一次请求中有效,请求转发有效,重定向失效(因为本质是浏览器发两次请求)
2.session域对象
在一次会话中有效,请求转发和重定向都有效(如果session不变),session销毁后失效。
3.servletContext域对象
在整个应用程序中有效,服务器关闭后失效。