1.设置响应行
格式:HTTP/1.1 200 ok
设置状态码:setStatus(int sc):传入一个int型的状态码就把状态码设置了
2.设置响应头:setHeader(String name,String value)
响应行+响应头实现重定向
package cn.itcast.web.servlet;
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;
/**
* @author 旗木五五开
* @create 2020-03-06 9:59
* 重定向
*/
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("1被访问");
// 访问responseDemo1会自动跳转到responseDemo2
// 1.设置状态码为302
response.setStatus(302);
// 2.设置响应头:头名称:location,值:资源路径
response.setHeader("location","/day15/responseDemo2");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
package cn.itcast.web.servlet;
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;
/**
* @author 旗木五五开
* @create 2020-03-06 10:01
*/
@WebServlet("/responseDemo2")
public class ResponseDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("2被访问");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
回车确定后1变2
控制台输出
简单的重定向response.sendRedirect
package cn.itcast.web.servlet;
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;
/**
* @author 旗木五五开
* @create 2020-03-06 9:59
* 重定向
*/
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("1被访问");
response.sendRedirect("/day15/responseDemo2");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
重定向的特点:redirect
①地址栏发生变化
②重定向可以访问其他 站点(服务器)的资源
③重定向是两次请求:不能使用request域来共享数据
package cn.itcast.web.servlet;
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;
/**
* @author 旗木五五开
* @create 2020-03-06 9:59
* 重定向
*/
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("1被访问");
request.setAttribute("sm","request");
response.sendRedirect("/day15/responseDemo2");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
package cn.itcast.web.servlet;
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;
/**
* @author 旗木五五开
* @create 2020-03-06 10:01
*/
@WebServlet("/responseDemo2")
public class ResponseDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("2被访问");
Object sm = request.getAttribute("sm");
System.out.println(sm);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
转发的特点:forward
①转发地址栏路径不变
②转发只能访问当前服务器下的资源
③转发是一次请求:可以使用request域来共享数据
路径写法
相对路径:通过路径不可以确定唯一资源。
规则:不以/开头的,以 . 开头路径。不写默认./当前路径 ../后退一级的目录。jsp页面不推荐使用相对路径
如:./index.html index.html
规则:找到当前资源 和目标资源的 相对位置关系
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>找到当前资源 和目标资源的 相对位置关系</h1>
<p>
当前资源:localtion
http://localhost/day15/localtion.html
</p>
<p>
目标资源:requestDemo2
http://localhost/day15/responseDemo2
</p>
<a href="./responseDemo2">
responseDemo2
</a>
<a href="responseDemo2">
responseDemo
</a>
</body>
</html>
绝对路径:通过路径可以确定唯一资源。以/开头的
如:http://localhost/day15/responseDemo2或者 /day15/responseDemo2
规则:判断定义的路径是给谁用的。判断请求从哪发出。使用动态虚拟目录
给客户端浏览器使用:需要加虚拟目录(项目的访问路径)。重定向、、
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>绝对路径</h1>
<a href="/day15/responseDemo2">
responseDemo2
</a>
</body>
</html>
给服务器使用:不需要加虚拟目录。转发
package cn.itcast.web.servlet;
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;
/**
* @author 旗木五五开
* @create 2020-03-07 17:32
*/
@WebServlet("/responseDemo3")
public class ResponseDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/responseDemo2").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
动态的获取虚拟目录request.getContextPath()
html不行,jsp可以
package cn.itcast.web.servlet;
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;
/**
* @author 旗木五五开
* @create 2020-03-06 9:59
* 重定向
*/
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 调用request请求头方法
String contextPath = request.getContextPath();
// 拼接 虚拟目录 资源路径
response.sendRedirect(contextPath+"/responseDemo2");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
3.设置响应体:通过流的方式
使用步骤:
1.获取输出流
字符输出流:只能输出字符
PrintWiter getWiter():打印流
有两种输出数据的方式
write方法,
print方法:自动刷新(不刷新把数据写出缓冲区的效果)
但是这个方法是response获取的,上面两个方法都可以自动刷新。response在一次响应完成之后会自动销毁,获取的流也会被自动关闭。
package cn.itcast.web.servlet;
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;
import java.io.PrintWriter;
/**
* @author 旗木五五开
* @create 2020-03-07 19:03
*/
@WebServlet("/responseDemo4")
public class ResponseDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取字符输出流
PrintWriter pw = response.getWriter();
// 2.输出数据
pw.write("<h1>hello response</h1>");
/*
数据会被浏览器解析展示到页面上
*/
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
解决中文乱码:乱码的原因:编码解码用的字符集不一致
浏览器打开默认的字符集和当前操作系统的语言环境有关系,现在用的是中文的Windows操作系统。打开浏览器默认的字符集(编码表)就是GBK(国标扩展码)或GB2312(国标码)都是中文的码表。
由此可知服务器用的不是GB2312
服务器用的是啥呢
解决方法:获取去流对象之前,设置默认编码
text/html;charset=utf-8 文本数据/值类型HTML;字符设置=utf-8
package cn.itcast.web.servlet;
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;
import java.io.PrintWriter;
/**
* @author 旗木五五开
* @create 2020-03-07 19:03
*/
@WebServlet("/responseDemo4")
public class ResponseDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取流对象之前,设置默认编码
/*光写这行代码不够,如果浏览器用的不是GBK还是会乱码。需要2*/
response.setCharacterEncoding("GBK");
// 2.设置响应体,告诉浏览器,服务器发送的消息体数据的编码。建议浏览器使用该编码解码
/*这一行代码可以代替1,一行代码干两件事*/
response.setHeader("content-type","text/html;charset=utf-8");
// 2的简单的形式,设置编码-----------------用这个
response.setContentType("text/html;charset=utf-8");
// 获取字符输出流
PrintWriter pw = response.getWriter();
// 输出数据
pw.write("<h1>hello response</h1>");
/*
数据会被浏览器解析展示到页面上
*/
pw.write("你好 response");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
字节输出流:能输出任何数据
ServletOutputStream getOutputStream():当做OutputStream来使用
package cn.itcast.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 旗木五五开
* @create 2020-03-07 21:14
*/
@WebServlet("/responseDemo5")
public class ResponseDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 解决乱码同上
response.setContentType("text/html;charset=utf-8");
// 1.获取直接输出流
ServletOutputStream sos = response.getOutputStream();
// 2.输出数据
/*字节流输出字符数据 getBytes()获取字节数组 括号内可以设置编码*/
sos.write("hello 你好".getBytes("utf-8"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
2.使用输出流,将数据输出到客户端浏览器
验证码
本质:图片
目的:防止恶意表单注册
图片是怎么来的?
第一种:在文件夹中放很多图片随机显示(第一种,一万张图片,通过穷举的方式能把一万张图片弄完)
第二种:在程序中动态的生成,一张图片,输出到页面上(随机生成,要列举出来所有的情况基本不可能)程序都采用的这种方式
package cn.itcast.web.servlet;
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;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* @author 旗木五五开
* @create 2020-03-07 21:37
*/
@WebServlet("/checkCodServlet")
public class CheckCodServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 100;
int height = 50;
// 1.创建一个对象,在内存中代表一张图片。
/*参数宽、高、图片类型*/
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
// 2.美化图片
// 2.1填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置颜色,大小写没有区别
g.fillRect(0, 0, width, height);//填充
/*x和y在图片中是左上角那个点,从左到右,从上到下*/
// 2.2给图片画一个边框
g.setColor(Color.BLUE);//设置颜色,大小写没有区别
/*不减1,右边和下边就会画到外面,无法显示*/
g.drawRect(0, 0, width - 1, height - 1);
// 验证码内容
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// 随机角标
Random ran = new Random();
// 2.3写验证码
for (int i = 1; i <= 4; i++) {
// 最大值
int index = ran.nextInt(str.length());
// 获取字符
char ch = str.charAt(index);
g.drawString(ch + "", width / 5 * i, height / 2);
}
// 2.4画干扰线
g.setColor(Color.GREEN);//颜色
// 画线
for (int i = 0; i < 10; i++) {
// 随机生成坐标点
int x1 = ran.nextInt(width);
int y1 = ran.nextInt(width);
int x2 = ran.nextInt(width);
int y2 = ran.nextInt(width);
// 线段
g.drawLine(x1,y1,x2,y2);
}
// 3.将图片输出到页面展示。因为现在图片在内存中要输出它需要一个对象
/*将内存中的一张图片写到页面,任意的流中。参数图片对象,图片后缀名,OutputStream*/
/*后缀名是为了输出到对应的文件使用的,页面上无所谓*/
ImageIO.write(image, "jpg", response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
开发中使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
/*
* 分析:
* 点击超链接或者图片,切换图片
* 1.给超链接和图片绑定单机事件
* 2.重新设置图片的src属性值
* 页面加载完后
* */
window.onload = function () {
// 1.给图片绑定单机事件
var img = document.getElementById("checkCode");
// 2.绑定单机事件
img.onclick=function () {
/*
* 因为两次请求图片路径一样会被浏览器当做缓存
* */
//所以+时间戳
var date=new Date().getTime();
img.src="/day15/checkCodServlet?"+date;
}
// 给超链接绑定单机事件
var t=document.getElementById("change");
t.onclick=function () {
/*
* 因为两次请求图片路径一样会被浏览器当做缓存
* */
//所以+时间戳
var date=new Date().getTime();
img.src="/day15/checkCodServlet?"+date;
}
}
</script>
</head>
<body>
<img id="checkCode" src="/day15/checkCodServlet" alt="">
<a id="change"href="javascript:void(0)"> 看不清换一张</a>
</body>
</html>
今天比昨天晚,却比明天早