response功能:设置响应消息

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

  规则:判断定义的路径是给谁用的。判断请求从哪发出。使用动态虚拟目录

  给客户端浏览器使用:需要加虚拟目录(项目的访问路径)。重定向、<A>、<form>

<!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>
原文地址:https://www.cnblogs.com/rijiyuelei/p/12419437.html