1. 响应对象response
1. 原理
(1)response和request对象是由服务器创建,管理,销毁的
(2)继承体系
ServletResponse(接口)<----继承---- HttpServletResponse(接口) <----实现----org.apache.catalina.connector.ResponseFacade@3bec9d4
ServletRequest(接口)<--------继承<-------HttpServletRequest(接口)<--------实现 org.apache.catalina.connector.RequestFacade@6049a827
(3)当服务器收到浏览器的请求后,服务器会创建Servlet对象,也会去创建请求和响应对象,请求对象会把浏览器的请求信息封装到请求对象里面,然后服务器通过调用service()方法,然后把请求和响应对象传给该方法,所以就可以在service()方法里面取出这两个对象来用。如果你要设置响应信息,你就把响应的数据设置到响应对象里面,服务器在正式响应浏览器之前,会从响应对象里面取出响应的数据,给浏览器响应回去
2. response设置响应消息之设置响应行
(1)方法:setStatus(int code):设置响应状态码
(2)重定向
1. 状态码:302
2. 特点:
1. 两次请求,两次响应
2. 地址栏发生变化
3. 不仅可以访问内部资源,也可以访问外部资源
3. 方法
1.1 设置状态码302:response.setStatus(302)
1.2 设置响应头:response.setHeader("location","https://www.baidu.com")
2. 以上两个步骤可以合为一个:response.sendRedirect("https://www.baidu.com")
(3)重定向的代码示例
@WebServlet(name = "ServletDemo01", value = "/demo01")
public class ServletDemo01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应状态码
response.setStatus(302);
//重定向,跳转到本地页面
response.setHeader("location","/1115/home.jsp");
//重定向合为一步,跳转外部页面
response.sendRedirect("https://www.baidu.com");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
3. response设置响应消息之设置响应体
(1)响应体响应的是数据,需要通过流的形式,获取输出流写出数据
(2)为了防止乱码,需要设置一下服务器对字符流的编码
1.1 在获取流之前告诉服务器用的是什么编码:response.setCharacterEncoding("utf-8")
1.2 告诉浏览器我们用的是什么编码 ,好让浏览器用响应的编码去解码:response.setHeader("content-type","text/html;charset=utf-8")
2. 两步可以合成一步:response.setContentType("text/html;charset=utf-8");//作用:设置字符打印输出流的编码,并告诉浏览器用相应的编码去解码
(3)获取流的方法
1. PrintWriter getWriter():获取发送字符数据的对象
2. ServletOutputStream getOutputStream():获取发送字节数据的对象
(4)代码示例
@WebServlet(name = "ServletDemo02", value = "/demo02")
public class ServletDemo02 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决中文乱码,设置编码集
response.setContentType("text/html;charset=utf-8");
//获取字符输出流
PrintWriter writer = response.getWriter();
//输出数据
writer.write("<h1 style='color:red'>你好,response对象~</h1>");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
=======================================================================================
@WebServlet(name = "ServletDemo03", value = "/demo03")
public class ServletDemo03 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取访问服务器的IP地址
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
//读取WEB/INF下的timg.jpg图片
String realPath = this.getServletContext().getRealPath("/WEB-INF/timg.jpg");
FileInputStream is = new FileInputStream(realPath);
//通过响应对象获取字节流并响应给浏览器
ServletOutputStream os = response.getOutputStream();
int len = 0;
byte[] bytes = new byte[1024 * 8];
while ((len = is.read(bytes)) != -1){
os.write(bytes,0,len);
os.flush();
}
is.close();
os.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
4. 案例:写一个验证码给网页
(1)Servlet代码
@WebServlet(name = "CheckCodeServlet", value = "/checkcode")
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创造图片
int width = 100;
int height = 60;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//美化图片
Graphics graphics = image.getGraphics(); //获取画笔
graphics.setColor(Color.PINK); //设置颜色
graphics.fillRect(0,0,width,height); //填充背景
graphics.setColor(Color.blue); //设置颜色
graphics.drawRect(0,0,width-1,height-1); //画边框
//生成随机验证码
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
graphics.setColor(Color.cyan);
graphics.setFont(new Font("宋体",Font.PLAIN,30));
Random random = new Random();
for (int i = 1; i <= 4; i++) {
int index = random.nextInt(str.length());
char c = str.charAt(index);
graphics.drawString(c+"",(width/5)*i,height/2);
}
//画干扰线
graphics.setColor(Color.YELLOW);
for (int i = 0; i < 10; i++) {
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
graphics.drawLine(x1,y1,x2,y2);
}
//响应图片
ImageIO.write(image,"png",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
(2)页面代码
<%--
Created by IntelliJ IDEA.
User: wzr
Date: 2020/11/15
Time: 14:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div align="center">
<form action="/1115/#" method="get">
用户名<input type="text" name="username">
<br>
密码<input type="password" name="password">
<br>
验证码<input type="text" name="check">
<br>
<img src="/1115/checkcode" id="checkCode" onclick="change()">
<br>
<a href="javascript:void(0)" onclick="change()">看不清,换一张</a>
<br>
<input type="submit" value="提交">
</form>
</div>
</body>
</html>
<script>
var change = function () {
var img = document.getElementById("checkCode");
//拼接一个随机参数,让服务器每次都响应
img.src = "/1115/checkcode?time=" + new Date().getTime();
}
</script>
2. 请求对象request
1. 原理
(1)request请求对象,里面封装了请求的信息
2. 获取请求行信息
GET /MyServlet/index.jsp?name=zhangsan&age=23 HTTP/1.1
1. request.getMethod();//获取请求方式
2. request.getContextPath();//获取项目名称
3. request.getRequestURI();//获取URI
4. request.getRequestURL();//获取URL
5. request.getRemoteAddr();//获取IP地址
6. request.getQueryString();//获取请求参数(GET)
7. request.getProtocol();//获取协议版本
@WebServlet(name = "ServletDemo04", value = "/demo04")
public class ServletDemo04 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//http://localhost:8080/1115/demo04?username=zhangsan&password=123456
//1. request.getMethod();//获取请求方式
String method = request.getMethod();
System.out.println(method); //GET
//2. request.getContextPath();//获取项目名称(上下文路径)
String contextPath = request.getContextPath();
System.out.println(contextPath); // /1115
//3. request.getRequestURI();//获取URI
String requestURI = request.getRequestURI();
System.out.println(requestURI); // /1115/demo04
//4. request.getRequestURL();//获取URL
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURL); //http://localhost:8080/1115/demo04
//5. request.getRemoteAddr();//获取IP地址
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr); //0:0:0:0:0:0:0:1
//6. request.getQueryString();//获取请求参数
String queryString = request.getQueryString();
System.out.println(queryString); //username=zhangsan&password=123456
//如果请求参数中有中文:String decode = URLDecoder.decode(queryString, "utf-8")
//7. request.getProtocol();//获取协议版本
String protocol = request.getProtocol();
System.out.println(protocol); //HTTP/1.1
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
3. 获取请求头信息
1. request.getHeader("user-agent");//获取请求头的值
2. request.getHeader("Referer");//获取来访者地址
@WebServlet(name = "ServletDemo05", value = "/demo05")
public class ServletDemo05 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. request.getHeader("user-agent");//获取请求头的值
String userAgent = request.getHeader("User-Agent");
System.out.println(userAgent); //Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
//2. request.getHeader("Referer");//获取来访者地址
String referer = request.getHeader("Referer");
System.out.println(referer); //null
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
4. 获取请求体信息
(1)请求体:用于封装POST请求的请求参数
(2)方法
1. 获取字符数据:getReader();返回一个高效的字符流。我们通过一次读取一行的方法来获取请求参数数据,然后拆分字符串获取我们想要的数据
2. 获取字节数据:getInputStream(); 后期上传文件时讲解
@WebServlet(name = "ServletDemo06", value = "/demo06")
public class ServletDemo06 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedReader reader = request.getReader();
String s = reader.readLine();
System.out.println(s); //name=zhangsan&pwd=12345
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
5. 通用的方式获取请求参数
1. request.getParameter(name):通过请求参数的名称来获取值
2. request.getParameterValues(name):通过请求参数的名称,来获取值的数组,一般用于复选框
3. request.getParameterMap():获取所有参数的map集合
【注意】
1. tomcat 8.0 以上GET请求的中文参数不乱码,tomcat已经处理了,我们不用处理
2. POST请求特有的方式处理中文乱码:request.setCharacterEncoding("utf-8");
<%--
Created by IntelliJ IDEA.
User: wzr
Date: 2020/11/15
Time: 15:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div align="center">
<form action="/1115/demo07" method="post">
用户名<input type="text" name="username">
<br>
密码<input type="password" name="password">
<br>
爱好<<br>
篮球<input type="checkbox" name="hobby" value="lq">
足球<input type="checkbox" name="hobby" value="zq">
排球<input type="checkbox" name="hobby" value="pq">
<input type="submit" value="提交">
</form>
</div>
</body>
</html>
=======================================================================================
@WebServlet(name = "ServletDemo07", value = "/demo07")
public class ServletDemo07 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. request.getParameter(name):通过请求参数的名称来获取值
String username = request.getParameter("username");
System.out.println(username); //zhangsan
String password = request.getParameter("password");
System.out.println(password); //123456
//2. request.getParameterValues(name):通过请求参数的名称,来获取值的数组,一般用于复选框
String[] hobbies = request.getParameterValues("hobby");
System.out.println(Arrays.toString(hobbies)); //[zq, pq]
//3. request.getParameterMap():获取所有参数的map集合
Map<String, String[]> parameterMap = request.getParameterMap();
System.out.println(parameterMap); //org.apache.catalina.util.ParameterMap@782f1fa
Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
for (Map.Entry<String, String[]> entry : entries) {
String key = entry.getKey();
String[] value = entry.getValue();
System.out.println(key + "-->" + Arrays.toString(value));
}
/**
* username-->[zhangsan]
* password-->[123456]
* hobby-->[zq, pq]
*/
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
6. 请求转发
(1)请求转发与重定向的比较
1. 请求转发
1. 一次请求一次响应
2. 地址栏不发生变化
3. 只能访问内部站点资源
4. 可以访问WEB-INF下的资源
2. 重定向
1. 两次请求两次响应
2. 地址栏发生变化
3. 即能访问内部站点资源,又可以访问外部站点资源
4. 不能访问WEB-INF下的资源
(2)方法
request.getRequestDispatcher("/xxxxx").forward(request, response)
@WebServlet(name = "ServletA", value = "/a")
public class ServletA extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("A收到了请求");
System.out.println("下来给B");
request.getRequestDispatcher("/b").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
=======================================================================================
@WebServlet(name = "ServletB", value = "/b")
public class ServletB extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("B收到了请求");
System.out.println("下来给C");
request.getRequestDispatcher("/c").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
=======================================================================================
@WebServlet(name = "ServletC", value = "/c")
public class ServletC extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("C收到了请求");
System.out.println("下来给WEB-INF下的D");
request.getRequestDispatcher("/WEB-INF/D.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
=======================================================================================
<%--
Created by IntelliJ IDEA.
User: wzr
Date: 2020/11/15
Time: 16:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>D.jsp</h1>
</body>
</html>
7. ServletRequest域对象
(1)ServletRequest也是一个域对象,称为请求域
(2)范围:一次请求和响应的范围
@WebServlet(name = "ServletDemo08", value = "/demo08")
public class ServletDemo08 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("name","zhangsan");
//内部转发
request.getRequestDispatcher("/demo09").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
=======================================================================================
@WebServlet(name = "ServletDemo09", value = "/demo09")
public class ServletDemo09 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = (String) request.getAttribute("name");
System.out.println(name); //zhangsan
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
3. 关于路径的书写
1. 请求转发不需要写上下文路径
2. 项目中页面路径和重定向路径,需要加上上下文路径