(JavaWeb)S4HTTP响应消息,response对象,ServletContext对象

HTTP协议

请求消息:客户端给服务端的数据

  • 数据格式

      1. 请求行
      2. 请求头
      3. 请求空号
      4. 请求体
    

响应消息:服务端发给客户端的数据

  • 数据格式

      1. 响应行
      2. 响应头
      3. 响应空号
      4. 响应体
    
HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Content-Length: 101
Date: Tue, 14 Apr 2020 02:37:40 GMT

<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  hello,123123
  </body>
</html>

响应行

HTTP/1.1 200 OK
  1. 组成:协议/版本 响应状态 状态描述

  2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态

     1. 状态码都是3位数字
     2.  分类:
     	1. 1XX:服务器接收客户端消息,没有接受完成,等待一段时间后,发送1XX状态码
     	2. 2XX:成功。如:200
     	3. 3XX:重定向。如:302(重定向)	,304(访问缓存)
     	4. 4XX:客户端错误。
     		1. 404(请求路径无对应资源)
     		2. 405(请求方式无对应的doXX方法)
     	6. 5XX:服务器错误。如500(服务器内部异常)
    

响应头

Content-Type: text/html;charset=utf-8
Content-Length: 101
Date: Tue, 14 Apr 2020 02:37:40 GMT
  1. 格式:头名称:值
  2. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
  3. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
    * 值:in-line默认,在当前页面内打开
    * attachment;filename=XX:以附件形式打开响应体。文件下载

响应体

<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  hello,123123
  </body>
</html>
传输的数据

Reponse对象

功能:设置响应消息

设置响应行

setStatus(int sc)

设置响应头

setHeader(String name, String value) 

设置响应体

  1. 设置输出流
    1. 字符输出流:PrintWriter getWriter()
    2. 字节输出流:ServletOutputStream getOutputStream()
  2. 使用输出流,将数据输出到浏览器

案例:

重定向:资源跳转的方式

@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo1访问了!!");
        // 访问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);
    }
}

在这里插入图片描述
简单实现

public class ResponseDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo1访问了!!");
//        // 访问responseDemo1自动访问responseDemo2
//        // 1. 设置状态码为302
//        response.setStatus(302);
//        // 2. 设置响应头Location
//        response.setHeader("location","/Day15/responseDemo2");
//        // 简单的重定向方法
        response.sendRedirect("/Day15/responseDemo2");
    }
* 重定向特点:redirect
	1. 重定向地址栏路径改变
	2. 重定向能访问其他服务器资源
	3. **重定向是两次请求**,不可以使用request共享数据
* 转发特点:forward 
	1. 转发地址栏路径不变
	2. 转发只能访问当前服务器资源
	3. 转发是一次请求,可以使用request共享数据
* 面试题:forward 和 redirect区别

* 路径写法:
	1. 分类
		1. 相对路径:不可以确定唯一资源,以.开头
			* 规则:访问当前资源和目标资源的相对位置关系
		2. 绝对路径:可以确定唯一资源,以/开头的路径
			* 规则:判断定义的路径是给谁用的?
				1. 给客户端浏览器:加虚拟目录(项目的访问路径)
						建议虚拟目录动态获取request.getContextPath();
						<a> <from>
				2. 给客户端用:不加虚拟目录 。如转发

服务器输出字符数据到浏览器

步骤
  1. 获取字符输出流
  2. 输出数据
注意
  1. 乱码问题

    1. PrintWriter pw = response.getWriter();默认获取流是ISO-8859-1
    2. 设置流的默认编码
    3. 告诉浏览器使用的编码
    4. 在获取流之前设置码
@WebServlet("/responseDemo3")
public class ResponseDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取流之前设置编码
//        response.setCharacterEncoding("utf-8");
        // 告诉浏览器,服务器发送消息的数据编码,建议使用的编码
//        response.setHeader("content-type","text/html;charset=utf-8");
        // 简单设置编码
        response.setContentType("text/html;charset=utf-8");
        // 1. 获取输出流
        PrintWriter pw = response.getWriter();
        // 2. 输出数据
        pw.write("<h1>hello asdqqqqqqq!</h1>");
        pw.write("你好!!");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

服务器输出字节数据到浏览器

步骤
  1. 获取字节输出流
  2. 输出数据
@WebServlet("/responseDemo4")
public class ResponseDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置头
        response.setContentType("text/html;charset=utf-8");
        // 1. 获取字节流
        ServletOutputStream outputStream = response.getOutputStream();
        // 2. 输出数据
        outputStream.write("你好".getBytes("utf-8"));

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

验证码案例

  1. 本质:图片
  2. 目的:放置恶意表单注册
@WebServlet("/yzms")
public class YanZhengMaServlet 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_INT_RGB);
        // 2. 美化图片
        // 2.1 填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.pink);// 设置画笔颜色
        g.fillRect(0,0,width,height);
        // 2.2 画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width-1,height-1);
        
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrsduvwxyz1234567890";
        // 创建随机脚标
        Random ran = new Random();
        for (int i = 1; i < 5; i++) {
            int index = ran.nextInt(str.length());
            // 获取字符
            char ch = str.charAt(index);// 随机字符


            // 2.3 写验证码
            g.drawString(ch+"" ,width/5*i,height/2);
        }
        // 2.4 画干扰线
        g.setColor(Color.GREEN);
        // 随机生成坐标点
        int x1 = ran.nextInt(width);
        int x2 = ran.nextInt(width);
        int y1 = ran.nextInt(height);
        int y2 = ran.nextInt(height);
        for (int i = 0; i < 10; i++) {
            int x11 = ran.nextInt(width);
            int x22 = ran.nextInt(width);
            int y11 = ran.nextInt(height);
            int y22 = ran.nextInt(height);
            g.drawLine(x11,y11,x22,y22);
        }
        // 3. 将图片输出到页面
        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 () {
            var img = document.getElementById("1");
            img.onclick = function () {
                // 加时间戳
                var date = new Date().getTime();
                img.src = "/Day15/yzms?" + date;
            }
            var a = document.getElementById("2");
            a.onclick = function () {
                // 加时间戳
                var date = new Date().getTime();
                img.src = "/Day15/yzms?" + date;
            }
        }
    </script>
</head>
<body>
    <img id="1" src="/Day15/yzms" />
    <a id="2" href="#">看不清换一张</a>
</body>
</html>

ServletContext对象

  1. 基本概念:代表整个web应用,可以和程序的容器(服务器)来通信
  2. 获取:
    1. 通过request获取
      request.getServletContext();
    2. 通过HTTPServlet
      this.getServletContext();

功能:

  1. 获取文件的 MIME 类型:

     MIME :是一种文件数据类型
     	格式:大类型/小类型 	text/html  	image/jpeg
     获取:
    
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         /*
         * 1. 获取文件的 MIME 类型:

		    MIME :是一种文件数据类型
			    格式:大类型/小类型 	text/html  	image/jpeg
		    * 获取
        2. 域对象:共享数据
        3. 获取文件真实路径(服务器路径)
         *
         * */

        //2. 通过request对象获取
        ServletContext context = request.getServletContext();
        //3. 定义文件名称
        String filename = "a.jpg";
        // 4. 获取MIME类型
        String mimeType = context.getMimeType(filename);
        System.out.println(mimeType);
    }
  1. 域对象:共享数据

    1. setAttribute(String name,Object values)
    2. getAttribute(String name)
    3. removeAttribute(String name)
    • ServletContext对象范围:所有用户,所有请求的数据
  2. 获取文件真实路径(服务器路径)

    1. 方法:String getRealPath(String path);

案例 文件下载

文件下载需求:

1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 获取文件名称
        String filename = request.getParameter("filename");
        // 2. 使用字节输入流加载进内存
        // 2.1 找到文件服务器路径
        ServletContext servletContext = this.getServletContext();
        String realPath = servletContext.getRealPath("/image/" + filename);
        // 2.2 用字节流关联
        FileInputStream fis = new FileInputStream(realPath);


        //3. 设置response的响应头
        // 3.1 设置响应头类型
        String mimeType = servletContext.getMimeType(filename);
        response.setHeader("content-type",mimeType);
        //3.2 设置响应头打开方式
        response.setHeader("content-disposition","attachment;filename=" + filename);
        // 4. 将输入流数据写到输出流
        ServletOutputStream sos = response.getOutputStream();
        byte[] buff = new byte[1024 * 8];
        int len = 0;
        while((len = fis.read(buff)) != -1){
            sos.write(buff,0,len);
        }
        fis.close();
    }

    <a href="/Day15/image/1.jpg">图片1</a>
    <a href="/Day15/image/1.avi">视频</a>
    <hr>
    <a href="/Day15/downloadServlet?filename=1.jpg">图片1</a>
    <a href="/Day15/downloadServlet?filename=1.avi">视频</a>
    <hr>
    <a href="/Day15/downloadServlet?filename=九尾.jpg">图片1</a>
    <a href="/Day15/downloadServlet?filename=1.avi">视频</a>

在这里插入图片描述

可以使用以下步骤实现: 1. 在登录请求中,验证用户的用户名和密码是否正确。 2. 如果验证通过,则使用 response 对象将用户的头像图片发送给浏览器,浏览器可以通过访问该 URL 来下载图片。 3. 如果验证不通过,则返回错误信息给用户。 以下是示例代码: ```java @WebServlet("/login") public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if (username.equals("admin") && password.equals("admin123")) { // 如果用户名和密码验证通过 // 将用户的头像图片发送给浏览器 response.setContentType("image/jpeg"); FileInputStream fis = new FileInputStream("path/to/image.jpg"); OutputStream os = response.getOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { os.write(buffer, 0, len); } fis.close(); os.flush(); os.close(); } else { // 如果用户名或密码不正确 response.setContentType("text/plain;charset=UTF-8"); response.getWriter().write("用户名或密码不正确"); } } } ``` 在上面的代码中,我们首先读取了用户提交的用户名和密码,然后进行验证。如果验证通过,我们设置 response 对象的 content type 为 "image/jpeg",表示我们将要发送的是一张图片。然后使用 FileInputStream 读取图片文件,将图片的内容写入 response 对象的 output stream 中,最后关闭 FileInputStream 和 OutputStream。如果验证不通过,我们设置 content type 为 "text/plain;charset=UTF-8",表示我们将要发送的是一段纯文本内容,然后使用 response.getWriter() 获取一个 PrintWriter 对象,将错误信息写入 PrintWriter 中,最后关闭 PrintWriter。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值