一、请求与响应
Servlet最主要的作用就是处理客户端请求,并向客户端做出响应。为此,针对Servlet的每次请求,Web服务器在调用service()之前,都会创建两个对象,分别是HttpServletRequest和HttpServletResponse。HttpServletRequest其中,HttpServletResponse用于封装HTTP请求消息,简称response对象。request对象和 response对象在请求 Servlet过程中至关重要。浏览器访问Servlet的交互过程,如图所示
需要注意的是,在Web服务器运行阶段,每个都只会创建一个实例对象,然而,每次HTTP请求,Web服务器都会调用所请求Servlet实例的service(HttpServletRequest request,HttpServletResponse response)重新创建一个request对象和一个response对象。
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest
对象,代表响应的一个HttpServletResponse;
-
如果要获取客户端请求过来的参数:找HttpServletRequest
-
如果要给客户端响应一些信息:找HttpServletResponse
1、HttpServletResponse对象
(1)、发送状态码相关的方法
当Servlet向客户端回送响应消息时,需要在响应消息中设置状态码。
a、setStatus(int status)方法
该方法用于设置HTTP响应消息的状态码,并生成响应状态行。**由于响应状态行中的状态描述信息直接与状态码相关,而HTTP版本由服务器确定,因此,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。**需要注意的是,正常情况下,Web服务器会默认产生一个状态码为200的状态行。
b、setError(int sc)方法
该方法用于发送表示错误信息的状态码,例如,404状态码表示找不到客户端请求的资源。在response对象中,提供了两个重载的sendError(int sc)方法,具体如下:
public void sendError(int code) throws java.io.IOException
public void sendError(int code, String message) throws java.io.IOException
在上面重载的两个方法中,第一个方法只是发送错误信息的状态码,而第二个方法除了发送状态码外,还可以增加一条用于提示说明的文本信息,该文本信息将出现在发送给客户端的正文内容中。
(2)、发送响应消息头相关的方法
(3)、发送响应体相关的方法
2、HttpServletResponse应用
(1)、中文输出乱码问题
在HttpServletResponse对象中,提供了两种解决乱码的方案
第一种:
//设置HttpServletRespponse使用utf-8编码
response.setCharacterEncoding("utf-8");
//通知浏览器使用utf-8解码
response.setHeader("Content-Type","text/html;charset=utf-8");
第二种:
response.setContentType("text/html;charset=utf-8");
实例:
运行
(2)、网页定时跳转
response调用setHeader()方法实现实现网页刷屏并跳转
xml配置
servlet02.java
运行,10秒后跳转
(3)、网页自动刷新页面
在setHeader()方法中设置时间,实现页面刷新功能。
xml配置
servlet03.java
运行
(4)、禁止浏览器缓存页面
HttpServletResponse设置http响应头控制浏览器禁止缓存当前文档内容,设置代码如下:
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
response.setDateHeader("expries", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
}
(5)、请求重定向
重定向和转发的区别
-
相同点:页面都会实现跳转
-
不同点:转发的时候,url地址栏不会发生变化;重定向的时候,url地址栏会发生变化。
3、HttpServletRequest应用
(1)、获取请求参数
使用HttpServletRequest获取客户端的请求参数,相关方法如下:
-
String getParameter(String name):通过指定名称获取参数值;
-
String[] getParameterValues(String name):通过指定名称获取参数值数组,有可能一个名字对应多个值,例如表单中的多个复选框使用相同的name时;
-
Enumeration getParameterNames():获取所有参数的名字;
-
Map getParameterMap():获取所有参数对应的Map,其中key为参数名,value为参数值。
(2)、请求参数的中文乱码问题
设置流的字符编码格式,因为使用post请求的时候,把请求体包装成了流,需要设置和前端口页面一样的字符编码格式,这时候需要用到request.setCharacterEncoding(“utf-8”)
ServletReq01.java
index.jsp
运行
(3)、获取网络连接信息
ServletReq02.java
运行
(4)、通过Request对象传递数据
Request对象不仅可以获取一系列数据,还可以通过属性传递数据。在ServletRequest接口中,定义了一系列操作属性的方法:
void setAttribute(String name,Object o) |
该方法用于将一个对象与一个名称关联后存储进ServletRequest对象中。需要注意的是,如果ServletRequest对象中已经存在指定名称的属性,setAttribute()方法将会删除原来的属性,然后再添加新的属性(如果传递给setAttribute()方法的属性值对象为null,则删除指定名称的属性,等同与removeAttribute()方法)。 |
void removeAttribute(String name) |
该方法用于从ServletReques对象中删除指定名称的属性 |
Object getAttribute(String name) |
该方法用于从ServletRequest对象中返回指定名称的属性对象 |
Enumeration getAttributeNames(String name) |
该方法用于返回一个包含ServletRequest对象中的所有属性名的Enumeration对象,在此基础上可以对ServletRequest对象中的所有属性进行遍历处理。 |
4、RequestDispatcher应用
(1)、请求转发
请求转发步骤:
-
浏览器——>访问Servlet1——>Web服务器(servlet容器)
-
Servlet1——>forward()——>Servlet2
-
Servlet2——>返回响应结果——>浏览器
实例:
RequestForwardServlet.java
ResultServlet.java
forward将servlet请求转发到ResultServlet
运行
(2)、请求包含
请求包含步骤
请求包含指的是使用include()方法将Servlet请求转发给其他Web资源进行处理,与请求转发不同的时,在请求包含返回的响应消息中,既包含了当前Servlet的响应消息,也包含了其他Web资源所作出的响应消息图示:
当请求处理完毕后,回送给客户端的响应结果既包含当前Servlet的响应结果,也包含其他Web资源的响应结果。
实例
IncludingServlet.java
IncludedServlet.java
运行
二、会话
1、Cookie对象
(1)、简介
Cookie是一种会话技术,用于将会话过程中的数据保存到用户的浏览器中,从而使浏览器和服务器可以更好地进行数据交互。
cookie:一般会保存在本地的用户目录下 appdata;
(2)、作用
-
使用Cookie,解决了不同请求间的数据共享问题。
-
我们把请求需要的共享的请求数据存储再浏览器端,避免用户进行重复的数据书写操作。
-
Cookie技术是浏览器端的数据存储技术。解决了不同请求需要使用相同的请求数据的问题。
(3)、特点
-
不安全
-
适合存储键值对形式的少量数据
-
他是浏览器端的数据存储技术,但存储的数据声明在服务器端。
注意:
-
一个Cookie只能保存一个信息;
-
一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
-
Cookie大小有限制4kb;
-
300个cookie浏览器上限
(4)、Cookie类的构造方法
public Cookie (java.lang.String name,java.lang.String value)
-
参数 name 用于指定 Cookie 的名称
-
value 用于指定 Cookie 的值
注意: Cookie 一旦创建,名称不能更改,值可以更改
(5)、Cookie的创建
具体操作:
-
创建Cookie对象,绑定数据
-
new Cookie(String name,String value);
-
-
发送Cookie对象
-
response.addCookie(Cookie cookie);
-
-
获取Cookie,拿到数据
-
Cookie[] request.getCookies();
-
CookieServlet.java
运行,可以看到cookies信息
设置Cookie有效期代码:
Cookie c2 = new Cookie("timingKey", "5minutes"); // 定时存储:将请求中的timingKey参数存放到cookie中
c2.setMaxAge(1000*60*5); // 存储5分钟,5分钟后这个Cookie失效
(6)、Cookie的获取
使用如下代码获取所有Cookie信息,然后遍历一下即可
Cookie[] cookies = req.getCookies(); // 获取所有Cookie信息
2、Session
(1)、简介
Session是另一种记录浏览器状态的机制,Cookie保存在浏览器中,Session保存在服务器中。用户使用浏览器访问服务器的时候,服务把用户的信息,以某种形式记录在服务器,这就是Session。
(2)、特点
-
session用于存储一次会话中多次请求的数据,存储在服务器端。
-
session可以存储任意类型任意大小的值,Cookie只能存储String类型。
(3)、使用场景:
-
保存一个登录用户的信息;
-
购物车信息;
-
在整个网站中经常会使用的数据,我们将它保存在Session中;
(3)、Session和cookie的区别:
-
session将数据存储与服务器端,Cookie存储在客户端。
-
session没有数据大小限制,Cookie有数据大小限制。
-
session数据安全,Cookie数据相对不安全
(4)、Session创建
-
获取HttpSession对象
-
HttpSession session = request.getSession();
-
-
使用HttpSession独享
-
Object getAttribute(String name);
-
String name = (String)session.getAttribute(String name);
-
-
void setAttribute(String name,Object value);
-
session.setAttribute(String name,Object value);
-
-
void removeAttribute(String name);
-
session.removeAttribute(String name);、
-
-
注意:session的默认失效时间为30分钟
三、JSP
Java Server Pages : Java服务器端页面,也和Servlet一样,用于动态Web技术
1、JSP本质
JSP本质是一个Servlet
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JSPService
public void _jspService(.HttpServletRequest request,HttpServletResponse response)
2、JSP基本语法
(1)、JSP表达式
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式%>
--%>
<%= new java.util.Date()%>
(2)、JSP脚本片段
<%--jsp脚本片段--%>
<%
int sum = 0;
for (int i = 1; i <=100 ; i++) {
sum+=i;
}
out.println("<h1>Sum="+sum+"</h1>");
%>
(3)、脚本片段的再实现
<%
int x = 10;
out.println(x);
%>
<p>这是一个JSP文档</p>
<%
int y = 2;
out.println(y);
%>
<hr>
<%--在代码嵌入HTML元素--%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>Hello,World <%=i%> </h1>
<%
}
%>
(4)、JSP声明
<%!
static {
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void kuang(){
System.out.println("进入了方法Kuang!");
}
%>
(5)、JSP指令
<%@page args.... %>
<%@include file=""%>
<%--@include会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>
<hr>
<%--jSP标签
jsp:include:拼接页面,本质还是三个
--%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="/common/footer.jsp"/>
3、九大内置对象
-
PageContext 存东西
-
Request 存东西
-
Response
-
Session 存东西
-
Application 【SerlvetContext】 存东西
-
config 【SerlvetConfig】
-
out
-
page ,不用了解
-
exception
4、JSP标签
<!-- JSTL表达式的依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
5、JSTL标签
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和Java代码一样
6、EL表达式
EL表达式: ${ }
获取数据
执行运算
获取web开发的常用对象
JSTL标签库使用步骤:
-
引入对应的 taglib
-
使用其中的方法
-
在Tomcat 也需要引入 jstl的包,否则会报错:JSTL解析错误
四、JavaBean组件
1、JavaBean
(1)、简介
JavaBean组件是一些可移植、可重用并可组装到应用程序中的Java类,类必须是具体的和公共的。
JavaBean的编码规范:
-
对数据类型“protype”的每个可读属性,Bean下必须有下面签名的一个方法:public proptype getProperty(){}
-
对数据类型“protype”的每个可写属性,Bean下必须有下面签名的一个方法:public void setProperty(proptype x){}
-
定义一个不带任何参数的构造函数。
(2)、作用
用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、 Servlet、其他JavaBean、 applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。
(3)、特点
-
可以实现代码的重复利用;
-
易编写、易维护、易使用;
-
可以在任何支持Java的平台上工作,而不需要重新编译;
-
可以通过网络传输;
-
可以与其他Java类同时使用
(4)、JavaBean特定的写法
-
必须要有一个无参构造
-
属性必须私有化
-
必须有对应的get/set方法
(5)、编写JavaBean遵循的原则
编写JavaBean就是编写一个类,这个类创建的对象称为JavaBean
-
必须具备一个不带参数的构造方法,显式地定义这样一个构造方法或者省略所有的构造方法都能满足这项要求。
-
成员变量也称为属性,JvaBean不应该有公开的成员变量,使用存取方法读取和修改属性,而不允许对字段直接访问。属性的名字建议以小写英文字母开头。
-
属性的值通过getXxx()和setXxx()方法来访问。如果类有String类型的属性title,读取title的方法是返回String的getTitle(),修改title的方法是setTitle(String title)。
-
布尔型的属性的读取方法可以使用getXxx(),也可以使用isXxx()。
-
JavaBean需要声明在包里面,package保留字给类起一个包名。
2、、JavaBean属性
-
简单属性(Simple)
-
索引属性(Indexed)
-
绑定属性(Bound)
-
约束属性(Constrained)
3、在JSP中使用JavaBean
JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分别为:
-
<jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件。
-
<jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
-
<jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。
四、过滤器Filter
Filter:过滤器 ,用来过滤网站的数据;
-
处理中文乱码
-
登录验证….
导包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1.3-b03</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
实现Filter接口,重写对应的方法即可
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器启动,就以及初始化了,随时等待过滤对象出现!
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
//Chain : 链
/*
1. 过滤中的所有代码,在过滤特定请求的时候都会执行
2. 必须要让过滤器继续同行
chain.doFilter(request,response);
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter执行前....");
chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
System.out.println("CharacterEncodingFilter执行后....");
}
//销毁:web服务器关闭的时候,过滤器会销毁
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
在web.xml中配置 Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.kuang.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是 /servlet的任何请求,会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
<!--<url-pattern>/*</url-pattern>-->
<!-- 别偷懒写个 /* -->
</filter-mapping>
五、监听器
实现一个监听器的接口;(有n种监听器)
编写一个监听器,实现监听器的接口
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//统计网站在线人数
public class OnlineCountListener implements HttpSessionListener {
//创建session监听
//一旦创建session就会触发事件
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer OnlineCount = (Integer) ctx.getAttribute("OnlineCount");
if(OnlineCount==null){
OnlineCount = new Integer(1);
}else{
int count = OnlineCount.intValue();
OnlineCount = new Integer(count+1);
}
ctx.setAttribute("OnlineCount",OnlineCount);
}
//销毁session监听
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer OnlineCount = (Integer) ctx.getAttribute("OnlineCount");
if(OnlineCount==null){
OnlineCount = new Integer(0);
}else{
int count = OnlineCount.intValue();
OnlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount",OnlineCount);
}
}
web.xml中注册监听器
<listener>
<listener-class>com.bilibili.Filter.listener.OnlineCountListener</listener-class>
</listener>