Response

ServletContext对象

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

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

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

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

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

  • ServletContext对象获取

    • ServletConfig对象,方法 getServletContext()

    • 继承HttpServlet类,继承GenericServlet类定义方法 getServletContext()

    ServletContext context = getServletContext();

对象的作用

获取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("资源相对路径")

域对象

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

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

  • 向域对象存储数据: setAttribute(String key, Object value)
  • 取出域对象数据: Object getAttribute(String key)
  • 移除域对象数据: removeAttribute(String key)

ServletContext对象的空指针异常

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

统计访问的次数

练习域对象ServletContext的使用

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

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

 

注解开发取代web.xml(不写配置文件)

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

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

@WebServlet(urlPatterns = "/test")

xml有弱点,如果配置过多,比较乱,还消耗资源。

缺点:可拓展性低。

Response对象概述

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

ServletResponse接口,HttpServletResponse接口继承自ServletResponse

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

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

 

Response设置响应行

  • 设置状态码: setStatus(int 状态码)

response.setStatus(500);   // 设置响应的状态码

补充:

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)

Response设置响应体

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

 

  • getWriter() 返回值是打印流PrintWrite
/*
 * response对象方法getWriter()
 * 打印流的响应体
 * write() 使用字符串数据,没有差别, 输出是整数,查询编码表
 * print() 无论是什么,原样打印
 */


 

  • 响应中的中文乱码问题

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

/*
响应数据没有写回客户端
写在response对象的缓冲区,使用的编码是iso8859-1拉丁文
设置response对象缓冲区的编码表
方法:setCharacterEncoding("编码表")

通知浏览器用utf-8解码
 */

 

  • getOutputStream() 返回字节输出流OutputStream

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

重定向

/*
 * 接收浏览器的请求
 * 对浏览器进行响应:
 *   浏览器进行重新的定向
 *   302状态码
 *   重定向资源的地址: 响应头
 *
 *   Sun: 定义个方法实现重定向
 */

 注意1.sendRedirect()重定向后不要再写代码。2.getOutputStream()与getWriter()互斥(response中有缓冲区,一个字节流,一个字符流,冲突)。

文件的下载

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

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

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

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

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

全下载

response.setHeader()下载设置。

解决下载的文件名含中文的问题(a.jpg下载后名字为美女.jpg):

    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")) {
        // 火狐浏览器
        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();

验证码案例

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

String str ="abcdefABCDE1234567890";

Random.nextInt( str.length() )产生整数随机数,指定长度

str.charAt(索引)

package com.itheima.code;

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 {
    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);
    }

}

网页:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
  <!-- 
     实现验证码效果
     本质图片: img src=属性值是服务器资源CodeServlet
  -->
<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();
        // alert(code.src);
        // 事件修改src, 需要修改一下参数,不然拿的是缓存,验证码不会改变
        code.src="/WEB03/code?a="+date;
    }
</script>
</body>
</html>

详细过程:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值