JavaWeb三大组件
Servlet
服务器端组件,用于处理HTTP请求和响应的任务。
使用Tomcat运行
Servlet类
- javax .servlet.GenericServlet:所有Servlet类的父类
包含:- 一个抽象的service 方法
- 几个辅助方法用于日志操作和从应用和Servlet 配置中获取信息
- java.servlet.http.HttpServlet:继承了GenericServlet, 并实现了只接受HTTP 请求的service 方法。如下表
方法 | Servlet方法 | 目的 |
---|---|---|
GET | doGet() | 从指定的URL中获取资源 |
HEAD | doHead() | 与GET类似,唯一的区别在于该请求只返回页面的头部数据 |
POST | doPost() | 通常用于处理Web表单提交 |
PUT | doPut() | 存储URL中提供的实体 |
DELETE | doDelete() | 删除由URL标识的资源 |
OPTIONS | doOptions() | 返回支持的HTTP方法 |
TRACE | doTrace() | 用于诊断目的 |
写空方法返回405错误
初始化和销毁方法
- init()
- 调用init 方法时, Servlet 中的所有属性都已经设置完成,并提供了对ServletConfig 和javax.servlet.ServletContext 对象的访问
- init 方法将在Web应用程序启动后,第一个请求到达Servlet 时调用
- destroy()
- destroy 在Servlet 不再接受请求之后立即调用。
- 总是应该使用destroy 方法清理Servlet 待有的资源
配置Servlet
<?xml version="l . 0" encoding=" UTF-8"?>
<web-app xmlns= "http://xmlns.jcp.org/xml/ns/javaee"
xmlns :xsi="http : //www . w3 . org/2001/XMLSchema - instance "
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version=" 3.1">
<display-name>Hello World Applica 七ion</display-name>
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.wrox.HelloServlet</servlet-class>
<load-on-startup>l</load-on-startup>
</servlet>
</web-app>
从上到下依次是
- web-app xmlns:表示Web应用程序的根元素,告诉解析器在解析文档时使用哪个XML规范
- xmlns:xsi:指定了XML Schema实例命名空间
- xsi:schemaLocation:指定XML Schema的位置
<servlet>
:创建一个Servlet 的实例
Servlet映射到URL
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/greeting</url-pattern>
</servlet-mapping>
- 使用了该配置之后,所有访问应用程序相对URL)greeting 的请求都将由helloServlet 处理
<servlet>
和<servlet-mapping>
标签内的<servlet-name>
标签应该一致
Servlet方法
HttpServletRequest
提供了访问和获取HTTP请求信息的方法
-
获取请求参数:
POST /index.jsp?returnTo=productPage HTTP/1.1 Host : www.example.com Content-Length : 48 Content-Type : application/x-www-form-urlencoded addToCart&productld=9781118656464&category=Books
-
确定与请求内容相关的信息
- getContentType 将返回请求的Milv庄(多用途互联网邮件扩展)内容类型
-
读取请求内容
- getlnputStream 将返回一个javax. servlet. ServletlnputStream
适用于二进制格式 - 方法getReader 将返回一个java.io.BufferedReader
适用于UTF-8 或IS0-8859-1 文本
- getlnputStream 将返回一个javax. servlet. ServletlnputStream
-
获取请求特有的数据,例如URL 、URI 和头
以http://www.example.org/application/index.jsp?category=Books
为例- getRequestURL: 返回客户端用于创建请求的完整URL
http://www.example.org/application/index.jsp
- getRequestURI:只返回URL 中的服务器路径部分
/application/index.jsp
- getServletPath:只返回用于匹配Servlet 映射的URL部分
- getHeader:返回指定名字的头数据。如果有多个头使用了相同的名字,该方法将只返回第一个值。
- getHeaderNames:返回请求中所有头数据的名字的枚举
- getlntHeader:如果有某个特定的头的值一直是数字,那么可以调用该方法返回一个数字。
- getDateHeader:对千可以表示有效时间戳的头数据,该方法将返回一个Urux 时间戳(毫秒)。
- getRequestURL: 返回客户端用于创建请求的完整URL
-
会话和Cookies
HttpServletResponse
继承自ServletRequest,提供了对请求中与HITP 协议相关属性的访问
可以使用响应对象完成设置响应头、编写响应正文、重定向请求、设置HITP 状态码以及将Coo如es 返回到客户端等任务。这
-
编写响应正文
输出数据的方法: 不要同时使用- getOutputStream:返回一个javax.servlet.ServletOutputStream
- getWriter:将返回一个java.io.PrintWriter
使用PrintWriter 向客户端返回mML 或者其他基千字符编码的文本
-
设置头和其他响应属性
- 设置头数据:
- 会覆盖现有数据:setHeader 、setintHeader 和setDateHeader
- 不会覆盖现有数据:addHeader 、addlntHeader 或addDateHeader
- 设置HTTP 响应状态码:setStatus:
- 判断当前响应的状态:getStatus
- 设置状态码:sendError表示一条可选的错误消息将会输出到响应数据中,重定向到Web
容器为客户端提供的错误页面,并清空缓存 - 将客户端重定向至另一个URL:sendRedirect
- 设置头数据:
HttpSession
HttpSession
对象在整个用户会话期间都会存在,可以存储和检索与用户会话相关的数据。
Object getAttribute(String name)
:获取在HttpSession
中指定名称的属性值。如果不存在该属性,则返回null
。void setAttribute(String name, Object value)
:将指定名称和值的属性存储到HttpSession
中。如果已经存在具有相同名称的属性,则将其值替换为新值。void removeAttribute(String name)
:从HttpSession
中移除指定名称的属性。Enumeration<String> getAttributeNames()
:获取存储在HttpSession
中的所有属性名称的枚举。long getCreationTime()
:获取HttpSession
创建的时间,以毫秒为单位。String getId()
:获取HttpSession
的唯一标识符。long getLastAccessedTime()
:获取HttpSession
上一次访问的时间,以毫秒为单位。int getMaxInactiveInterval()
:获取HttpSession
的最大不活动时间间隔(以秒为单位),即在用户未活动期间,HttpSession
多长时间后将失效。void setMaxInactiveInterval(int interval)
:设置HttpSession
的最大不活动时间间隔(以秒为单位)。void invalidate()
:使HttpSession
失效,即删除HttpSession
中的所有属性并释放资源。
这些方法允许您在 HttpSession
中存储和获取数据,管理会话的生命周期,并与用户会话状态进行交互。通过使用这些方法,您可以实现用户登录状态管理、购物车功能、用户偏好设置等功能,为用户提供更好的网站体验。
用参数和接受表单提交
初始化参数配置
上下文初始化参数
在web.xml 文件中使用<context-param>
标签声明上下文初始化参数。
应用程序中的所有Servlet 都将共享这些初始化参数,
使用Servlet初始化参数
-
从ServletConfig 对象中获取
-
使用注解完成参数初始化
表单上传文件
将文件上传到Java EE Servlet
-
配置Servlet支持文件上传
@WebServlet( name = "TicketServlet", urlPatterns = {"/tickets"}, loadOnStartup = 1 ) @MultipartConfig(//告诉Web容器为该Servlet 提供文件上传支持。 //location,告诉浏览器应该在哪里存储临时文件 fileSizeThreshold = 5_242_880, // 5MB maxFileSize = 20_971_520L, // 禁止上传大小超过20MB 的文件, maxRequestSize = 41_943_040L // 禁止大小超过40MB 的请求 ) public class TicketServlet extends HttpServlet { ... }
-
接受文件上传
-
方法createTicket 将使用该方法和其他请求参数填充Ticket 对象, 调用另一个私有方法
processAttachment
将该对象添加到数据库中。 -
方法processAttachment将从multipart 请求中获得InputStream写入内存, 并将它复制到对象中。
private void createTicket(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Ticket ticket = new Ticket();
ticket.setCustomerName(request.getParameter("customerName"));
ticket.setSubject(request.getParameter("subject"));
ticket.setBody(request.getParameter("body"));
Part filePart = request.getPart("file");
if (filePart != null) {
Attachment attachment = this.processAttachment(filePart);
if (attachment != null) {
ticket.addAttachment(attachment);
}
}
int id;
synchronized (this) {
id = this.TICKET_ID_SEQUENCE++;
}
this.ticketDatabase.put(id, ticket);
response.sendRedirect("tickets?action=view&ticketid=" + id);//将响应重定向到显示新创建的票据的页面,以便用户查看刚刚创建的票据。
}
private Attachment processAttachment(Part filePart) throws IOException {
InputStream inputStream = filePart.getInputStream();//获取上传文件部分的输入流,用于读取文件内容。
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();//将文件内容写入到内存中。
int read;
final byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
Attachment attachment = new Attachment();
attachment.setName(filePart.getSubmittedFileName());
attachment.setContents(outputStream.toByteArray());
return attachment;
}
多线程
Attachment:它定义了容器在拒绝客户端连接之前,队列中可以包含的最大连接数目。一旦出现可用线程,浏览器将从线程池中借出线程,并将请求传递给
线程,由线程进行处理。
保护共享资源
-
`private volatile int TICKET_ID_SEQUENCE = 1 ;``
volatile
: 这个关键字用于修饰实例变量,表示该变量是“易变的”(volatile)。在多线程环境下,当一个线程修改了该变量的值,其他线程能够立即看到最新的值。
-
synchronized(this) {} id = this. TICKET ID SEQUENCE++; this. ticketDatabase.put(id, ticket) ; }
Filter
过滤器可以把对资源的请求拦截下来,从而实现一-些特殊的功能。比如权限控制、统一编码处理、敏感字符处理。
步骤:
- 创建maven工程,pom中导入tomcat和servlet
- 定义configurator为tomcat7:run
- 定义类,实现Filter接口,并重写其所有方法:
public class FilterDemo implements Filter {
public void init(FilterConfig filterConfig) {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
}
public void destroy() {
}
}
- 配置Filter拦截资源的路径:在类上定义@WebFilter注解:
@WebFilter("/*")
public class FilterDemo implements Filter {
}
- 在doFilter方法中输出一句话,并放行:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
System.out.println("filter被执行了...");
// 放行
chain.doFilter(request, response);
}
FilterChain chain
:这个参数用于调用过滤器链中的下一个过滤器或目标 Servlet。如果不调用这个方法,请求处理将会停止,当前过滤器之后将不会执行任何其他过滤器或 Servlet。
执行流程
执行放行前逻辑->放行->访问资源->执行放行后逻辑
拦截路径配置
@WebFilter("/*")
- 拦截具体的资源: /indexjsp:只有访问index.jsp时才会被拦截。
- 目录拦截: /user/*:访问/user下的所有资源,都会被拦截
- 后缀名拦截: *.jsp:访问后缀名为jsp的资源,都会被拦截
- 拦截所有 /*:访问所有资源,都会被拦截
过滤器链
一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链
实例-登陆验证
- 搭好大框架:
- 创建类,配置路径,写三个方法
- 创建HttpServletRequest变量用于获取 HTTP 请求的特定信息,例如请求的参数、头部、URL 等。
- 判断访问的是否是登录相关资源
- 是:放行
- 获取当前访问的资源路径
- 循环判断当前访问的资源路径中是否含有显示登录界面相关信息
- 不是:进行登录验证
- 是:放行
- 判断用户是否登录:
- 判断session中是否有user
- 判断user是否为null
- 判断是否登陆过
- 登陆过放行
- 没登陆过存储提示信息,跳转登陆页面
req.getRequestDispatcher("/login.jsp").forward(req,response);
forward()
方法,用于将请求转发到指定的目标资源。
Listener
对三个对象进行监听,即application
(ServletContext)、session
(HttpSession)和request
(ServletRequest)。
当这些对象被创建、销毁或者在它们内部的属性被添加、修改或删除时,监听器会自动执行相应的代码。
监听器分类 | 监听器名称 | 作用 |
---|---|---|
ServletContext监听器 | ServletContextListener | 用于对ServletContext对象进行监听(创建、销毁) |
ServletContextAttributeListener | 对ServletContext对象中属性的监听(增删改属性) | |
Session监听器 | HttpSessionListener | 对Session对象的整体状态的监听(创建、销毁) |
HttpSessionAttributeListener | 对Session对象中的属性监听(增删改属性) | |
HttpSessionBindingListener | 监听对象于Session的绑定和解除 | |
HttpSessionActivationListener | 对Session数据的钝化和活化的监听 | |
Request监听器 | ServletRequestListener | 对Request对象进行监听(创建、销毁) |
ServletRequestAttributeListener | 对Request对象中属性的监听(增删改属性) |
使用
- 定义类,实现 ServletContextListener 接口
public class ContextLoaderListener implements ServletContextListener {
/**
* ServletContext对象被创建: 整个web应用发布成功
* @param sce
*/
public void contextInitialized(ServletContextEvent sce) {
// 在此处添加初始化代码
}
/**
* ServletContext对象被销毁: 整个web应用卸载
* @param sce
*/
public void contextDestroyed(ServletContextEvent sce) {
// 在此处添加资源释放代码
}
}
- 在类上添加
@WebListener
注解
java
import javax.servlet.annotation.WebListener;
@WebListener
public class ContextLoaderListener implements ServletContextListener {
// 同上,此处省略内容
}
/ 在此处添加初始化代码
}
/**
* ServletContext对象被销毁: 整个web应用卸载
* @param sce
*/
public void contextDestroyed(ServletContextEvent sce) {
// 在此处添加资源释放代码
}
}
- 在类上添加
@WebListener
注解
java
import javax.servlet.annotation.WebListener;
@WebListener
public class ContextLoaderListener implements ServletContextListener {
// 同上,此处省略内容
}