Response对象

Response对象

1.1 ServletContext对象

​ 服务器中的项目,名称叫做WEB应用程序,应用程序也是对象

​ ServletContext (上下文) 对象表示WEB应用程序

​ 一个WEB应用程序只能存在一个ServletContext对象,唯一性

​ 每个应用程序,对应一个ServletContext对象

​ ServletContext是接口,此接口的实现类是tomcat引擎提供

  • ServletContext对象获取

    • ServletConfig对象,方法 getServletContext()
    • 继承HttpServlet类,继承GenericServlet类定义方法 getServletContext()
    ServletContext context = getServletContext();
    

对象的作用

既然 ServletContext 是 贯穿全文 的对象 ,所以项目中的资源 它都能访问到 , 主要 用它获取web项目中文件.

文件保存的位置 :

  1. src下 : 发布到 /WEB-INF/classes/文件名
  2. web目录下: 发布到 /文件名
  3. WEB-INF目录下:发布到 /WEB-INF/文件名

代码中获取路径 , 写法应该是发布后的路径 .

  • 获取WEB应用程序的初始化参数,web.xml配置

    <!-- 配置的是WEB程序的初始化参数-->
    <context-param>
        <param-name>heima</param-name>
        <param-value>java</param-value>
    </context-param>
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
         * 获取ServletContext对象
         * 父类的方法
         * org.apache.catalina.core.ApplicationContextFacade实现接口ServletContext
         */
        ServletContext context = getServletContext();
        System.out.println(context);
        //context对象,获取配置文件中的初始化参数
        String value = context.getInitParameter("heima");
        System.out.println(value);
    }
    
  • 获取WEB应用程序下任意资源的绝对路径

    • 方法: String getRealPath(“资源相对路径”)
    protected voi d doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
         * 获取ServletContext对象
         * 父类的方法
         * org.apache.catalina.core.ApplicationContextFacade实现接口ServletContext
         */
        ServletContext context = getServletContext();
        System.out.println(context);
        //context对象,获取配置文件中的初始化参数
        String value = context.getInitParameter("heima");
        System.out.println(value);
    
        //context对象,方法getRealPath获取任意资源的绝对路径
        //获取web目录下的a.txt绝对路径
        String aPath = context.getRealPath("a.txt");
        System.out.println(aPath);
    
        //获取web目下WEB-INF目录下的b.txt绝对路径
        String bPath = context.getRealPath("WEB-INF/b.txt");
        System.out.println(bPath);
    
        //获取src目录下的c.txt绝对路径
        String cPath = context.getRealPath("WEB-INF/classes/c.txt");
        System.out.println(cPath);
    
        //获取WEB03 module下的d.txt绝对路径,获取不到
    }
    
  • 域对象

    ServletContext对象是一个容器,可以存储数据.

    对象有个作用域问题,ServletContext作用域是整个WEB应用程序

    • 向域对象存储数据: setAttribute(String key, Object value)
    • 取出域对象数据: Object getAttribute(String key)
    • 移除域对象数据: removeAttribute(String key)
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
         * 域对象的存储和取出
         */
        ServletContext context = getServletContext();
        //域对象存储数据,键值对
        context.setAttribute("heima","java");
        //取出域对象存储的键值对
        Object value = context.getAttribute("heima");
        System.out.println(value);
    }
    

1.2ServletContext对象的空指针异常

ServletContext对象通过父类的方法getServletContext()获取

在这里插入图片描述
正常情况:

  1. Tomcat引擎,创建Servlet对象,调用init方法,引擎创建ServletConfig对象,
  2. 在调用init的方法时候,把ServletConfig对象传进去
  3. cofig会赋值给成员变量
  4. 在doGet方法调用getServletContext的时候,先调用getServletConfig(),然后再调用getServletContext.

非正常情况:

  1. 因为重写了init方法,导致引擎创建的ServletConfig对象,传到了重写的init方法里
  2. init方法里面没有东西,在调用getServletContext()时候,因为成员config没赋值,在调用getServletConfig()就会抛空

1.3 统计访问的次数

练习域对象ServletContext的使用

第一次访问Servlet的时候,数据1存储到域对象

第二次访问,从域中取出数据++,存储回去

public void init() throws ServletException {
    ServletContext context = getServletContext();
    context.setAttribute("count",1);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletContext context = getServletContext();
    Integer count = (Integer) context.getAttribute("count");
    response.getWriter().print("welcome "+count);
    count++;
    context.setAttribute("count",count);
}

1.4 注解开发取代web.xml

@WebServlet,注解添加到自己定义的Servlet中的类声明上即可

注解的属性 urlPatterns,属性值就是浏览器的访问地址

@WebServlet(urlPatterns = "/test")

1.5 Response对象概述

负责对浏览器进行响应的对象

ServletResponse接口,HttpServletResponse接口继承自ServletResponse

使用的是子接口HttpServletResponse,此接口对象由Tomcat引擎提供

可以实现对客户端的响应, 响应行,响应头,响应体

1.6 Response设置响应行

  • 设置状态码: setStatus(int 状态码)
response.setStatus(500);

1.7 Response设置响应头

HTTP协议的响应头,数据格式键值对 k:v

包含指导性信息,指导客户端

  • addHeader(String key,String value)
  • addIntHeader(String key,int value)
  • addDateHeader(String key,long l)
  • setHeader(String key,String value)
  • setIntHeader(String key,int value)
  • setDateHeader(String key,long l)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * response对象设置响应头
     */
    response.addHeader("heima","java");
  /*  response.addIntHeader("heima2",5);
    response.addDateHeader("date",System.currentTimeMillis());*/
    /*
     * addHeader() 添加,实现一个键对应多个值
     * setHeader() 设置,原来的键覆盖
     */
    response.setHeader("heima","java2222");
}

1.8 Response设置响应体

HTTP的响应体,就是页面的正文部分

  • getWriter() 返回值是打印流PrintWrite

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
         * response对象方法getWriter()
         * 打印流的响应体
         * write() 使用字符串数据,没有差别, 输出是整数,查询编码表
         * print() 无论是什么,原样打印
         */
         PrintWriter pw =  response.getWriter();
         pw.write(100);
         pw.print(100);
         out.print("<script>alert('删除成功!');location.href='UserServlets?opr=list';</script>");
    }
    

响应中的中文乱码问题

产生乱码原因: 编码和解码不一致

响应数据,没有直接写回客户端,写在response对象缓冲区,使用的编码是iso8859-1 拉丁文

设置对象缓冲区编码表,并告诉浏览器以utf-8码表去显示数据

response.setContentType("text/html;charset=UTF-8");
  • getOutputStream() 返回字节输出流OutputStream

    返回字节流,响应非文本类型的数据

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
         * response对象的方法getOutputStream,响应非文本类型的数据
         */
        //获取图片的绝对路径
        String aFile = getServletContext().getRealPath("a.jpg");
        FileInputStream fis  = new FileInputStream(aFile);
        OutputStream out = response.getOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fis.read(bytes))!=-1){
            out.write(bytes,0,len);
        }
        fis.close();
    }
    

1.9 重定向

在这里插入图片描述

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * 接收浏览器的请求
     * 对浏览器进行响应:
     *   浏览器进行重新的定向
     *   302状态码
     *   重定向资源的地址: 响应头
     *
     *   Sun: 定义个方法实现重定向
		response的方法 :
  		sendRedirect("路径") : 由于是重新定向 , 再次发起的请求来自于服务器外部, 所有需要添加 项目名称
                        举例 : "/WEB03/servlet2"
     */
    //response.setStatus(302);
    //response.setHeader("location","/WEB03/servlet2");
    response.sendRedirect("/WEB03/servlet2");
}

2.0 文件的下载

客户端浏览器从服务器下载文件

超链接,连接的地址是服务器端文件的路径

文件: 浏览器识别文件,不是下载,就是直接打开运行

​ 浏览器不识别文件,直接下载

编写服务器端代码,告诉浏览器下载,不要打开

Servlet页面

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * 编写程序,通知浏览器请你下载,不要打开
     * 指导浏览器干什么,响应头
     * 浏览器下载是HTTP协议规定
     */
     
	 /*Firefox浏览器下载中文文件的时候采用的是Base64的编码.
	  *IE浏览器,谷歌浏览器等,下载中文文件的时候采用的URL的编码.
	  *可以使用工具类“DownloadUtils.java”进行处理
	  */
	//根据User-Agent获取什么浏览器
    String agent = request.getHeader("User-Agent");
    String filename="美女.jpg";
    if (agent.contains("MSIE")) {
        // IE浏览器
        filename = URLEncoder.encode(filename, "utf-8");
        filename = filename.replace("+", " ");
    } else if (agent.contains("Firefox")) {
        // 火狐浏览器,这个对象java8以后就没有了
        BASE64Encoder base64Encoder = new BASE64Encoder();
        filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
    } else {
        // 其它浏览器
        filename = URLEncoder.encode(filename, "utf-8");
    }
    //设定接收程序处理数据的方式
    response.setHeader("Content-Disposition","attachment;filename="+filename);
    String aFile = getServletContext().getRealPath("download/a.jpg");
    FileInputStream fis = new FileInputStream(aFile);
    OutputStream out = response.getOutputStream();
    int len = 0;
    byte[] bytes = new byte[1024];
    while ((len = fis.read(bytes))!=-1){
        out.write(bytes,0,len);
    }
    fis.close();
}

html页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        a:link{color: black}
        a:visited{color: black}
    </style>
</head>
<body>
 <!--
     超链接,实现文件下载
     连接的地址,写服务器端需要下载文件的路径
 -->
 <a href="/WEB03/download/a.flv">a.flv</a><br>
 <a href="/WEB03/download/a.jpg">a.jpg</a><br>
 <a href="/WEB03/download/a.mp3">a.mp3</a><br>
 <a href="/WEB03/download/a.mp4">a.mp4</a><br>
 <a href="/WEB03/download/a.txt">a.txt</a><br>
 <a href="/WEB03/download/a.zip">a.zip</a><br>
 <a href="/WEB03/download/a.pdf">a.pdf</a><br>

<hr>
<!-- 超链接,连接地址不是文件,Servlet中-->
<a href="/WEB03/downLoad">a.jpg</a>  <br>

<!--<form action="#" method="get">
     <input type="text" name="a"> <input type="submit">
</form>-->
</body>
</html>

2.1 response对象注意事项

  1. 重定向,不要在写代码,没有意义

    不能多次重定向

  2. getWriter()字符流和getOutputStream()字节流互斥,只能选择一个使用

    response对象缓冲区,临时存储数据

    缓冲区到底是字节的,还是字符的呢?

2.2 验证码案例

在这里插入图片描述

验证码的本质是个图片,图片里面是个随机生成字符串

String str =“abcdefABCDE1234567890”;

Random.nextInt( str.length() )产生整数随机数

str.charAt(索引)

html

<img src="/WEB03/code" onclick="fnChange()" id="code">

<script type="text/javascript">
    function fnChange() {
        /*
         *  页面打开的时候,请求服务器资源/WEB03/code
         *  点击图片js函数中,发了请求/WEB03/code
         *
         *  请求的资源没有变化,服务器端程序也没有变化
         *  浏览器拿缓存吧
         *
         *  每次请求不一样就行,添加参数
         */
        //点击图片,修改src的属性值
        var code = document.getElementById("code");
        var date = new Date().getTime();
        code.src="/WEB03/code?a="+date;
    }
</script>

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;

@WebServlet(urlPatterns = "/code")
public class CodeServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //  创建画布
        int width = 120;
        int height = 40;
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //  获得画笔
        Graphics g = bufferedImage.getGraphics();
        //  填充背景颜色
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);
        //  绘制边框
        g.setColor(Color.red);
        g.drawRect(0, 0, width - 1, height - 1);
        //  生成随机字符
        //  准备数据
        String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
        //  准备随机对象
        Random r = new Random();
        //  声明一个变量 保存验证码
        String code = "";
        //  书写4个随机字符
        for (int i = 0; i < 4; i++) {
            //  设置字体
            g.setFont(new Font("宋体", Font.BOLD, 28));
            //  设置随机颜色
            g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));

            String str = data.charAt(r.nextInt(data.length())) + "";
            g.drawString(str, 10 + i * 28, 30);

            //  将新的字符 保存到验证码中
            code = code + str;
        }
        //  绘制干扰线
        for (int i = 0; i < 6; i++) {
            //  设置随机颜色
            g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));

            g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
        }

        //  将验证码 打印到控制台
        System.out.println(code);

        //  将验证码放到session中
        //request.getSession().setAttribute("code_session", code);

        //  将画布显示在浏览器中
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    }

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

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值