- (一)response
- 一、案例1:记录网站的登录成功人数
- 1.1、需求说明
- 1.2、知识点-ServletContext
- 1.3、response
- 1.3.1、response对象操作响应行
- 1.3.2、response对象操作响应头
- 1.3.3、response对象操作响应体
- 1.4、资源跳转-重定向
- 1.5、网站的登录成功人数
- 二、案例2:读取WEB工程下的资源文件
- 2.1、需求说明
- 2.2、案例代码实现-JavaSE
- 三、案例3:文件下载
- 3.1、需求说明
- 3.2、案例代码实现
- 四、案例4:点击切换验证码
- 4.1、需求说明
- 4.2、案例原型准备
- 4.2.1 生成图片验证码工具:(无需手写,直接使用)
- 4.3、案例代码实现
- (二) request
- 一、案例一:用户注册
- 1.1、流程分析
- 1.2、代码实现
- 1.3、代码优化
- 1.3.1、问题:每一个表单参数就要写一个getParameter(),不利于开发
- 1.3.2、问题:将生日改为日期类型
- 1.3.3、问题:中文乱码
- 1.4、request对象
- 1.4.1、request继承树
- 1.4.2、request操作请求体
- 1.4.3、request和response的执行流程
- 二、案例二:用户注册信息回显前端
- 2.1、流程分析
- 2.2、代码实现(重定向)
- 2.3、代码优化(转发)完整代码
- 2.3.1、问题:不同用户间回显信息冲突问题
- 2.4、讲解:请求转发和重定向的区别
登录成功后,5秒后跳转到某个页面,在页面中显示您是第x位登录成功的用户.
1.2、知识点-ServletContext是什么? 是一个项目中独一无二的身份证对象
可以存取数据, 范围: 在整个WEB工程都可以获取到
生命周期
何时创建: 服务器启动
何时销毁: 服务器正常关闭
如何获取:
作用:
1.获取web.xml文件中的配置信息
2.域对象
ServletContext对象
域对象:在域作用范围内进行数据共享。就相当于map集合
| 方法名 | 描述 |
|---|---|
| setAttribute(String name,Object object) | 向ServletContext中存数据 相当于 map.put(key , value) |
| getAttribute(String name) | 从ServletContext中取数据 相当于map.get(key) |
| removeAttribute(name) | 从ServletContext中移除数据 相当于map.remove(key) |
(1)创建案例 servlet
(2)web.xml文件内容体为:
添加部分:
完整代码:
servlet index.html index.htm index.jsp default.html default.htm default.jsp encoding UTF-8 DemoServlet2 DemoServlet2 com.zql.DemoServlet2 DemoServlet2 /demo2
(3)创建类DemoServlet1
package com.zql;
import java.io.IOException;
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;
@WebServlet("/demo1")
public class DemoServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用servletContext获得对象
ServletContext context = this.getServletContext();
ServletContext context2 = request.getServletContext();
System.out.println(context == context2);
//获取web.xml参数值
String encoding = context.getInitParameter("encoding");
System.out.println(encoding);
//使用设置值
context.setAttribute("name", "Daniel");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(4)创建类DemoServlet2
package com.zql;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用servletContext取对象
ServletContext context = this.getServletContext();
String name = (String) context.getAttribute("name");
System.out.println(name);
//使用移除数据
context.removeAttribute("name");
//重新查看是否有数据
String name1= (String) context.getAttribute("name");
System.out.println("移除后的值为"+name1);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
显示为:
1.访问:http://localhost:8080/servlet2/demo1
2.访问:http://localhost:8080/servlet2/demo2
在Servlet API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。
ServletResponse: 普通响应接口 , 不能处理HTTP协议
HttpServletResponse: 专门HTTP协议的响应接口
1.3.1、response对象操作响应行Response对象封装了响应行、头、体三部分信息,我们可以通过调用response对象的方法,来轻松控制服务器向浏览器写响应信息
状态码:
200:响应成功
404:路径找不到
500:服务器内部代码问题
302:重定向
304:缓存
setStatus(int status);
该方法用于设置HTTP响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而HTTP版本由服务器确定,因此,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。
若未设置状态码,且服务器运行正常,Web服务器会默认产生一个状态码为200的状态行。
response.setStatus(444);1.3.2、response对象操作响应头
当Servlet向客户端发送响应消息时,由于HTTP协议的响应头字段有很多种,为此,在HttpServletResponse接口中,定义了一系列设置HTTP响应头字段的方法,如表4-1所示。
表1-1设置响应消息头字段的方法
方法声明
| 方法声明 | 功能描述 |
| void addHeader(String name, String value) //IDEA自定义响应头 response.addHeader("name","Daniel"); //浏览器F12查看 Response Header View source Content-Length:0 Date:Mon,20 Jun 2022 06:57:37 GMT name:Daniel | 这两个方法都是用来设置HTTP协议的响应头字段,其中,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。不同的是,addHeader()方法可以增加同名的响应头字段,而setHeader()方法则会覆盖同名的头字段 |
| void setHeader(String name, String value) | |
| void setCharacterEncoding(String charset) | 该方法用于设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码部分。 |
| void setContentType(String type) | 该方法用于设置Servlet输出内容的MIME类型,对于HTTP协议来说,就是设置Content-Type响应头字段的值。例如,如果发送到客户端的内容是jpeg格式的图像数据,就需要将响应头字段的类型设置为“image/jpeg”。需要注意的是,如果响应的内容为文本,setContentType()方法的还可以设置字符编码,如:text/html;charset=UTF-8 |
| void addIntHeader(String name,int value) | 这两个方法专门用于设置包含整数值的响应头。避免了使用addHeader()与setHeader()方法时,需要将int类型的设置值转换为String类型的麻烦 |
| void setIntHeader(String name,int value) | |
| void setContentLength(int len) | 该方法用于设置响应消息的实体内容的大小,单位为字节。对于HTTP协议来说,这个方法就是设置Content-Length响应头字段的值 无需手动设置,由服务器自行设置 |
响应体信息无限,所以一般用来传递大量数据。
getOutputStream()
向响应体输出二进制字节流信息。
getWriter()
向响应体输出字符流信息。
注意事项:
1.一山不容二虎 (这个流不能同时使用) 除非你用了 if else判断
2.中文乱码问题
添加代码:
//response.setCharacterEncoding("utf-8");//无法确定不同用户使用的浏览器默认编码
response.setContentType("text/html;charset=utf-8");//乱码解决方案
if(false) {
ServletOutputStream out = response.getOutputStream();
out.write("我是正确的".getBytes()); //第一种页面显示
}else {
response.getWriter().write("我是错误的");//第二种页面显示
//也可以写标签js 中文会出现乱码
}
1.4、资源跳转-重定向
资源跳转有两种:
1.重定向
2.转发
重定向
1.立即重定向
System.out.println("demo4开始执行了");
response.sendRedirect("/servlet2/index.html");
index.html
Insert title here 重定向过来了
2.延迟重定向:
response.setContentType("text/html;charset=utf-8");
System.out.println("demo4开始执行了");
//response.sendRedirect("/servlet2/index.html");
response.getWriter().write("5秒后会跳转到index.html页面");
response.setHeader("refresh", "5;url=/servlet2/index.html");
1.5、网站的登录成功人数
(1)流程分析
(2)案例代码实现(见4.5)
(3)改动部分:
if(user != null) {
resp.getWriter().write("登录成功即将跳转到index页面");
count++;
this.getServletContext().setAttribute("count", count);
resp.setHeader("refresh", "5;url=/login/index");
}else {
resp.getWriter().write("登录失败");
}
(4)完整代码:
package com.zql.servlet;
import java.io.IOException;
import java.sql.SQLException;
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 com.zql.pojo.User;
import com.zql.service.UserService;
@WebServlet("/login")
public class UserServlet extends HttpServlet{
private int count = 0;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
try {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+"-----------"+password);
UserService service = new UserService();
User user = service.login(username,password);
if(user != null) {
resp.getWriter().write("登录成功即将跳转到index页面");
count++;
this.getServletContext().setAttribute("count", count);
resp.setHeader("refresh", "5;url=/login/index");
}else {
resp.getWriter().write("登录失败");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
(5)额外建类(servlet包下Index)
package com.zql.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/index")
public class Index extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
Object count = this.getServletContext().getAttribute("count");
response.getWriter().write("您是第"+count+"登录成功的用户");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
最终登录成功显示:
在web项目中分别在不同地方创建4个txt文件,分别取读取里边的内容
package com.zql;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class Demo {
public static void main(String[] args) throws Exception {
getFile("src/a.txt");
getFile("webContent/WEB-INF/b.txt");
getFile("webContent/c.txt");
getFile("d.txt");
}
public static void getFile(String file) throws Exception {
//String path = "";
//File file = new File(path);
BufferedReader bfd = new BufferedReader(new FileReader(file));
System.out.println(bfd.readLine());
}
}
2.2、案例代码实现-JavaSE
package com.zql;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Demo12 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//getFile("");
String path = this.getServletContext().getRealPath("/");
System.out.println(path);
getFile(path+"WEB-INF/classes/a.txt");
getFile(path+"WEB-INF/b.txt");
getFile(path+"c.txt");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void getFile(String file) throws Exception {
BufferedReader bfd = new BufferedReader(new FileReader(file));
System.out.println(bfd.readLine());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
结果显示为:
强制下载响应头设置
// 必须写在getOutputStream()之前 正文-配置 filename是下载名
//下载名会直接显示在下载的窗口中
引用代码:
response.setHeader("Content-Disposition", "attachment;filename="+filename);
3.1、需求说明
分别使用超链接和自定义Servlet程序,进行网站资源的下载。
超链接下载:
直接在网页看到图面和文档中内容, 是在浏览器上进行显示的
自定义下载:
3.2、案例代码实现我们要把它下载到本地磁盘上
案例结构:
(1)在WebContent下面创建down内含图片,文本,压缩包文件(随便找些);
(2)创建down.html
Insert title here 1.jpg 2.zip 3.txt
1.jpg
(3)创建下载类
package com.zql;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/download")
public class DownLoad extends HttpServlet {
@SuppressWarnings("resource")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = this.getServletContext().getRealPath("/down/");
String filename = request.getParameter("filename");
//System.out.println(path+file);
response.setHeader("Content-Disposition", "attachment;file="+filename);
FileInputStream fis = new FileInputStream(new File(path+filename));
OutputStream os = response.getOutputStream();
int len = 0;
byte[] obj = new byte[1024];
while((len = fis.read())!= -1 ) {
os.write(obj, 0, len);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(4) 访问:http://localhost:8080/servlet3/down.html
四、案例4:点击切换验证码 4.1、需求说明在访问登录页面时,需要生成验证码。从而防止用户使用程序恶意操作。
验证码: 本质就是一张图片
作用: 防止用户进行恶意操作 (登录 / 注册) 用户输入验证码的时间 也就给服务器进行喘气的时间
验证码的难易程度: 取决于网站的流量多少
4.2、案例原型准备 4.2.1 生成图片验证码工具:(无需手写,直接使用)package com.zql.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/vs")
public class VerifyCodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//生成图片
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 高和宽
int height = 30;
int width = 60;
String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
//2 创建一个图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//3 获得画板
Graphics g = image.getGraphics();
//4 填充一个矩形
// * 设置颜色
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
g.setColor(Color.WHITE);
g.fillRect(1, 1, width-2, height-2);
// * 设置字体
g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 25));
//5 写随机字
for(int i = 0 ; i < 4 ; i ++){
// 设置颜色--随机数
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 获得随机字
int index = random.nextInt(data.length());
String str = data.substring(index, index + 1);
// 写入
g.drawString(str, width/6 * (i + 1), 20);
}
//6 干扰线
for(int i = 0 ; i < 3 ; i ++){
// 设置颜色--随机数
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 随机绘制先
g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width),random.nextInt(height));
// 随机点
g.drawOval(random.nextInt(width), random.nextInt(height), 2, 2);
}
//end 将图片响应给浏览器
ImageIO.write(image, "jpg", response.getOutputStream());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
4.3、案例代码实现
(1) 使用之前写好的成功登录页面套件见4.5
(2)添加 (4.2.1) 代码,位置如下:
(3)找到对应验证码位置(F12找)
并且添加如下:
(4)编写js
(5)完整https://blog.csdn.net/weixin_42171159/article/details/login.html
会员登录 会员登录USER LOGINCopyright © 2022-2099 Daniel version
最终效果显示(点击可变换):
所需资源下载
(1) 导入sql:
CREATE DATABASE register;
USE register;
CREATE TABLE USER(
uid VARCHAr(32) PRIMARY KEY,
username VARCHAr(100) UNIQUE,
PASSWORD VARCHAr(100),
email VARCHAr(100),
NAME VARCHAr(100),
sex VARCHAr(10),
birthday TIMESTAMP
);
INSERT INTO USER VALUES ('00a','Daniel','123','Daniel@163.com','管理员','man','2022-01-01 05:50:50');
(2)案例结构:
(3)静态资源
(4)jar包
(5)工具类和xml
(6) https://blog.csdn.net/weixin_42171159/article/details/register.html 代码添加对应name 和form标签方式
会员登录 会员注册USER REGISTERCopyright © 中公商城 版权所有





