JavaWeb学习笔记-06请求和响应

Posted Moon&&Dragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb学习笔记-06请求和响应相关的知识,希望对你有一定的参考价值。

请求和响应

1、Servlet执行原理


1、浏览器根据请求的地址(ip/协议/端口)建立与服务器的连接

2、浏览器将请求数据打包

3、容器将请求解析,封装成俩个对象

请求-HttpServletRequest – 封装的请求数据

响应-HttpServletResponse – 返回给服务器

4、容器根据具体的请求地址—找到对应的servlet创建对象

5、容器将请求和响应作为参数传递,调用对应的请求方法

6、数据写入到输出流

7、容器将响应对象打包发给浏览器

8、浏览器读取到响应的数据,渲染页面

在浏览器中输入地址后:

在这里插入图片描述

2、响应-Response


response 对象 负责将信息传递给用户 。Response对象用于动态响应客户端请求,并将动态生成的响应结果返回到客户端浏览器中,使用Response对象可以直接 发送信息给浏览器,重定向浏览器到另一个URL或设置cookie的值 等。

设置Response响应类型以及编码:

// 设置响应的内容和编码
response.setContentType("text/html;charset=utf-8");
// 单独设置编码
response.setCharacterEncoding("utf-8");

获取字符输出流:

  • 字符输出流可以直接打印在页面,可以 输出html标签

    // 获取字符输出流对象  
    PrintWriter pw = response.getWriter();
    // 通过字符输出流对象把数据写入
    pw.print("<h1>我的第一行Servlet</h1>");
    // 关闭流
    pw.close();
    
  • 注意:如果输出的html标签没有识别,检查响应类型是否设置为“text/html”

获取字节输出流:

  • 如果想要响应一个文件给浏览器,通过字符输出流会导致字节错误,所以响应也有单独的字节输出

    // 获得字节输出流
    ServletOutputStream os = resp.getOutputStream();
    // 字节输出流输出
    os.write(94);
    // 关闭流
    os.close();
    
  • 可以通过输入流读取文件,再通过response获得的输出流写出文件

    @WebServlet("/out")
    public class MyServlet extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 获取硬盘文件
            FileInputStream in = new FileInputStream("/Users/xiaolong/Desktop/IDEA_Demo/javaweb_demo/demo1/target/classes/db-config.properties");
            // 获得字节输出流
            ServletOutputStream os = resp.getOutputStream();
            // 字节输出流输出
            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = in.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            // 关闭流
            os.close();
            in.close();
        }
    }
    
    

3、Response案例


案例一:通过response响应给浏览器下载文件

  • 编写servlet

    @WebServlet("/out")
    public class MyServlet extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 获得文件路径
            String realPath = "/Users/xiaolong/Desktop/IDEA_Demo/javaweb_demo/demo1/target/classes/db-config.properties";
            // 获取文件名称(截取地址最后的"/"后面的内容,如果不加1,最后一个"/"会在字符前面)
            String fileName = realPath.substring(realPath.lastIndexOf("/")+1);
            // 设置响应头,让浏览器支持下载,下载的文件名字就是前面截取到的
            resp.setHeader("content-disposition", "attachment;filename="+fileName);
            // 通过地址获取文件转为输入流
            FileInputStream in = new FileInputStream(realPath);
            // 获得字节输出流
            ServletOutputStream os = resp.getOutputStream();
            // 字节输出流输出
            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = in.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            // 关闭流
            os.close();
            in.close();
        }
    }
    
  • 浏览器访问/out结果:

在这里插入图片描述

会以我们定义的名字下载文件

案例二:每俩秒随机刷新验证码

  • 编写servlet

    @WebServlet("/img")
    public class VerificationCodeServlet extends HttpServlet {
        // 图片的宽高
        private static final Integer WIDTH = 100;
        private static final Integer HEIGHT = 50;
    
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 在内存中创建一张图片
            BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            // 通过创建的图片获得画笔
            Graphics g = bufferedImage.getGraphics();
            // 设置画笔颜色
            g.setColor(Color.white);
            // 使用画笔画背景
            g.fillRect(0, 0, WIDTH, HEIGHT);
            // 获取随机数字内容
            String vc = getRandomVc();
            // 设置画笔颜色
            g.setColor(Color.RED);
            // 设置字体
            g.setFont(new Font(null, Font.BOLD, 30));
            // 画验证码
            g.drawString(vc, 9, 35);
            // 设置响应头,2秒自动刷新
            resp.setHeader("refresh","2");
            // 设置响应类型
            resp.setContentType("image/jpeg");
            // 将图片通过ImageIO和响应的输出流传出到浏览器
            ImageIO.write(bufferedImage, "jpg", resp.getOutputStream());
        }
    
        /**
         * 获取四位数随机数字字符串
         *
         * @return
         */
        private String getRandomVc() {
            return new Random().nextInt(8999) + 1000 + "";
        }
    }
    
  • 浏览器访问/img结果:

    在这里插入图片描述

4、请求-Request


Request对象,又称为请求对象,它 连接着Web服务器和Web客户端程序。用来 获取客户端在请求一个页面或者传送一个Form时提供的所有信息,包括能够标识浏览器和用户的HTTP变量、存储在客户端Cookie信息以及附在URL后面的值、查询字符串或页面中Form段HTML控件内的值、Cookie、客户端证书、查询字符串等。

设置Request请求编码:

// 为了防止浏览器发送的信息乱码,一般在使用请求前,都会设置编码
request.setCharacterEncoding("utf-8");

获得Request请求携带的内容:

request.getParameter("标签属性name的值"); // 返回单个参数
request.getParameterValues("标签属性name的值");      // 返回多个参数
// 字符串 ---> 数字
Intager.parseInt(s);
// 设置请求编码
request.setCharacterEncoding("utf-8");
// 获得请求参数
String userName = request.getParameter("userName");
String password = request.getParameter("password");
// 获得多个参数
String[] ins = request.getParameterValues("ins");

get请求和post请求:

  • get请求不安全的,携带的数据会在浏览器地址栏显示
  • get请求携带得到 参数是有限的,一般就是浏览器地址栏的长度
  • post请求是安全的,它是将参数封装成包
  • 所以post请求可以携带的参数理论上 是无限的

注意:

  • 在重写servlet方式的时候要注意
  • 如果使用的get请求,那么一定要 重写的是doGet方法
  • 如果使用的post请求,那么一定要 重写的是doPost方法
  • 重写service可以 处理所有的请求

5、Request案例


案例: 模拟登陆

  • 登陆一个页面,肯定需要浏览器传入用户名和密码,所以简单的写一个html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>登陆</h1>
    <!-- form表单的action地址就是我们servlet注册的地址,方式我们这里使用get -->
    <form action="login" method="get">
        <label for="un">账号:</label>
        <!-- 输入框一定要写name属性,请求就是通过name的值来获取参数 -->
        <input type="text" id="un" name="username"><br>
        <label for="pw">密码:</label>
        <!-- 密码也是,要写上name -->
        <input type="password" id="pw" name="password"><br>
        <button>登陆</button>
    </form>
    </body>
    </html>
    
  • 有了html页面,然后编写servlet业务

    /**
     * @author 晓龙
     * @createTime 2021年04月20日 17:10:00
     */
    @WebServlet("/login")
    public class LoginServlet extends HttpServlet {
        // 模拟的数据库存在的数据
        private static final String USER = "xiaolong";
        private static final String PWD = "1234";
    
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 设置请求和响应编码
            req.setCharacterEncoding("utf-8");
            resp.setContentType("text/html;charset=utf-8");
    
            // 获取请求参数--账号和密码
            String username = req.getParameter("username");
            String password = req.getParameter("password");
    
            // 获取响应字符输出
            PrintWriter writer = resp.getWriter();
            // 判断账号和密码(这里就直接写定,如果登入我们这个就登陆成功,正常是去数据库查询)
            if (USER.equals(username)) {
                // 如果账户正确,则判断密码
                if (PWD.equals(password)) {
                    // 密码正确,响应登陆成功
                    writer.println("<h1>登陆成功!</h1>");
                } else {
                    // 密码错误,响应密码错误
                    writer.println("<h1>密码错误!</h1>");
                }
            } else {
                // 账号不正确,响应账号不存在
                writer.println("<h1>账号不存在!</h1>");
            }
    
            // 关闭响应字符流
            writer.close();
    
        }
    }
    
  • 启动项目,访问login.html填写表单测试即可

以上是关于JavaWeb学习笔记-06请求和响应的主要内容,如果未能解决你的问题,请参考以下文章

JAVAWEB学习笔记22

Tomcat和Servlet的学习笔记总结

javaweb复习笔记总结

JavaWeb学习笔记

JavaWeb学习笔记之Servlet九大内置对象

JavaWeb学习笔记-13过滤器