ServletRequest和ServletResponse

课程回顾:Servlet技术

Servlet的概述

1.Servlet在javax.servlet.Servlet接口,有5个方法。
2.接收和响应从客户端发送过来的请求。

Servlet的入门

1.入门的程序
    * 实现Servlet的接口,实现5个方法
    * 编写配置文件web.xml中编写
        <servlet>
            <servlet-name>随便写
            <servlet-class>全路径
        <servlet-mapping>
            <servlet-name>和上面相同
            <url-pattern>访问的路径

Servlet的生命周期

1.总结
    * 第一次访问的时候,Servlet被创建,创建后立即调用init方法进行初始化,调用一次。
    * 提供服务,调用service方法,N次。
    * 服务器关闭的时候,servlet实例被销毁,销毁之前调用destroy方法进行销毁,调用一次。

Servlet接口和实现类的一些关系

1.简便开发Servlet
2.以后的开发步骤
    * 继承HttpServlet,重写doGet和doPost方法
    * 编写配置文件    

自动加载

1.第一次访问的时候,才会创建Servlet实例,配置,服务器在启动的时候,就可以创建Servlet实例对象了!!
2.在<servlet>标签下<load-on-startup> 值0正整数

url-pattern的配置

1.配置有三种方式
    * 完全路径匹配        /demo
    * 目录匹配          /*
    * 扩展名匹配     *.do
2.配置多个Servlet,到底访问哪一个?
    * 优先级   完全路径匹配 > 目录 > 扩展名

WEB的路径的问题

1.相对路径
    * 找到访问资源的位置的关系。
    * WEB开发中很少写相对路径
2.绝对路径
    * http://localhost/day09/demo1
    * /day09/demo1
        * 项目名称前有 / (绝对路径都是以/开头的)
        * 绝对路径分成两种
            * 客户端绝对路径
                * 从客户端出发
                * 包含项目名称
            * 服务器端绝对路径
                * 已经进入到服务器的内部了。
                * 不用编写项目名称

ServletConfig接口

1.和配置文件的相关的接口,init方法
2.方法
    * 获取到servlet-name的名称
    * 获取初始化参数
    * 获取ServletContext域对象

ServletContext对象

1.域对象(传递数据) ,域的作用的范围不同的,ServletContext域的范围,代表的是整个WEB的应用!!
2.Servlet的特点
    * 服务器启动的时候创建,服务器关闭的就销毁了!!
    * 被WEB所有的资源所共享!!
    * 与天地同寿!!

3.作用
    * 获取全局的初始化参数(全局:所有的Servlet中都可以通过ServletContext来获取初始化参数)
    * 实现数据的共享
    * 读取资源的文件
        * getResourceAsStream("服务器绝对路径,不包含项目名称")
        * getRealPath("服务器绝对路径,不包含项目名称")

今天内容:ServletRequest和ServletResponse

ServletResponse对象概述

1.概述
    * ServletResponse对象,代表的响应的对象(从服务器端到客户端),记住:从服务器向客户端输出一些内容,都找response对象!
    * ServletResponse子对象,是HttpServletResponse(一般情况下都使用HttpServletResponse)
    * 都是接口,实现类是Tomcat服务器创建的!!

2.看文档(掌握的一些方法)
    * ServletOutputStream getOutputStream()             -- 获取字节是输出流(重点)
    * PrintWriter getWriter()                       -- 获取字符的输出流(重点)
    * void setCharacterEncoding(String charset)         -- 设置编码,设置response对象的缓冲区的编码(重点)

    * void setContentType(String type)                  -- 设置头(Content-Type),解决浏览器打开文件时采用的编码(重点)

    * void addCookie(Cookie cookie)                     -- 回写Cookie(今天不讲)
    * void addHeader(String name, String value)         -- 设置响应头
        * 一个头,对应多个值!!
    * void addDateHeader(String name, long date)        -- 设置响应vv头
        * 设置日期的头信息

    * void sendRedirect(String location)                -- 重定向的功能(重点)
        * String location  要重定向的地址,不用设置302的状态码
        * location  客户端绝对路径(包含项目名称!!)

    * void setHeader(String name, String value)             -- 设置响应头(重点)
        * 一个头,对应的一个值!!(常用)
    * void setStatus(int sc)                            -- 设置状态码

重定向的案例

1.重定向的代码怎么编写?重定向到底有什么样的作用?重定向应用在哪?
2.重定向的理论
    * 先班长借钱,班长没钱(给我一个暗号(状态吗 302),但是回一个地址(冲订单的一个地址,使用头信息location)),浏览器获取到了302,和location的头,直接就去访问location的地址了!!
    * 两次请求,两次响应!!   

3.重定向应用在哪?
    * 完成的页面的跳转!! 

4.开始重定向的案例
    * 头信息
        * location          --设置重定向的地址
        * 302状态码        -- 必须要返回的

5.登陆的重定向的案例
    * 需求:编写登陆的页面,输入用户名和密码,把表单提交到后台的Servlet程序中。在后台接收到用户输入的内容,进行判断,如果用户名和密码都是admin,登陆成功了,跳转到成功的页面!!如果有一个不是admin,跳转回登陆的页面!!

6.代码
    * 前台页面
        <h3>登陆页面</h3>
        <form action="/day10/login" method="post">
            姓名:<input type="text" name="username" /><br/>
            密码:<input type="password" name="password" /><br/>
            <input type="submit" value="登陆" />
        </form>

    * 后台代码
        /**
         * 表单提交编写完成了!!
         *  分析
         *  * 先接收用户输入的数据(没学过!!只能先使用一下)
         *  * 进行判断,用户名和密码是否都是admin,
         *  * 如果是,说明登陆成功,跳转到成功的页面
         *  * 如果不是,说明登陆失败,跳转到登陆页面
         */

        // 接收数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 进行判断
        if("admin".equals(username) && "admin".equals(password)){
            // 登陆成功
            // 成功页面
            response.sendRedirect("/day10/response/suc.html");
        }else{
            // 登陆失败
            response.sendRedirect("/day10/response/login.html");
        }

页面定时刷新(refresh)

1.学习一个头信息就可以了。
2.响应的头信息
    * refresh
    * response.setHeader("refresh","5;url=/day10/xxx/xxx.html");
3.模拟页面的定时的跳转
4.代码
    <body onload="run()">

    <h3>页面将在<span id="spanId">5</span>秒后跳转!!</h3>

    </body>
    <script type="text/javascript">
        // 页面在一加载的时候,开始执行了!!
        // 页面一加载完成,run方法就会执行,开始读秒的操作!!
        var x = 5;
        function run(){
            var span = document.getElementById("spanId");
            // innerHTML
            span.innerHTML = x;
            x--;
            // 每隔一秒减一次 window
            window.setTimeout("run()", 1000);
        }
    </script>

禁用浏览器的缓存

1.不用记!!查询文档就可以了!!
2.禁用浏览器的缓存。
3.演示禁用缓存的代码
    * 模拟的例子:模拟页面显示当前的时间。
    * 需要使用3个头信息来完成禁用缓存!!

4.三个头信息中有一个头信息值是日期类型的。
    * 方法还需要改变
    * setDateHeader(String name,long m)

5.头的开始的字母是C E P
    // 设置3个头信息  C E P
    response.setHeader("Cache-Control", "no-cache");
    // 日期格式
    response.setDateHeader("Expires", -1);
    // 字符串
    response.setHeader("Pragma", "no-cache");

向页面输出中文乱码的问题

1.目的:输出中文,先获取输出的流。response对象提供了两个方式!!
    * ServletOutputStream getOutputStream()             -- 获取字节是输出流
    * PrintWriter getWriter()                       -- 获取字符的输出流

2.使用字节的输出流,输出中文的乱码的问题
    * 使用字节流输出中文的时候,有可能乱码!!
        * 获取byte数组的编码和浏览器打开文件的编码不一致造成的!!
        * 解决这个问题
            * 目的:把编码保证一致!!
                * 获取byte数组指定一个编码(编码一)!!
                    * "哈罗我的".getBytes("UTF-8")
                 * 设置浏览器默认打开文件的编码(编码二)!!
                    * response.setHeader("Content-Type", "text/html;charset=UTF-8");
                * 编码一和编码二一致,就不会产生乱码的问题!!

3.使用字符的输出流,输出中文的乱码问题
     * 使用字符流输出中文,必须会产生乱码的!
        * Tomcat服务器7以下版本都使用的是ISO-8859-1编码!!
        * 解决问题
            * 手动设置response缓冲区的编码,设置UTF-8(编码一)
                * void setCharacterEncoding("UTF-8") 
            * 设置浏览器打开文件采用的编码。(编码二)
                * response.setHeader("Content-Type", "text/html;charset=UTF-8");
            * 编码一和编码二一致,不会产生乱码!!

4.总结,输出中文的乱码的问题,分成两种情况
    * 字节
        * 获取byte数组的时候,设置指定的编码
            * "哈罗我的".getBytes("UTF-8")
        * 设置浏览器打开文件时采用的编码
            * response.setHeader("Content-Type", "text/html;charset=UTF-8");

    * 字符
        * 设置response对象的缓冲区的编码
            * void setCharacterEncoding("UTF-8") 
        * 设置浏览器打开文件时采用的编码
            * response.setHeader("Content-Type", "text/html;charset=UTF-8");

        * 字符流的简便的方式
            * response.setContentType("text/html;charset=UTF-8");       

文件下载

1.记住一句话,两个头一个流
2.两个响应头
    * Content-Type      -- 值就不能自己手写了,有方法可以来获取文件的格式(MIME类型)
    * Content-Disposition   -- 以附件的形式打开,值的写法是固定的。attachment;filename=  +文件的名称(中文会乱码)

3.一个流
    * 先获取到要下载的文件的输入流

4.代码
    * 前台代码
        <h3>文件的下载</h3>
        <h4><a href="/day10/download?filename=girl.jpg">girl.jpg</a></h4>
        <h4><a href="/day10/download?filename=girl7.jpg">girl7.jpg</a></h4>
        <h4><a href="/day10/download?filename=w.jpg">w.jpg</a></h4>

    * 后台代码
        // 接收参数(接收文件名称)
        String filename = request.getParameter("filename");

        // 设置两个头信息
        String type = this.getServletContext().getMimeType(filename);
        response.setContentType(type);
        response.setHeader("Content-Disposition", "attachment;filename="+filename);

        // 要下载的文件的文件名称已经获取到了 filename=girl.jpg  filename=w.jpg

        // 目的:需要找到该文件名称的文件,获取该文件的输入流
        // 获取该文件的路径
        // path是download的绝对磁盘路径
        String path = this.getServletContext().getRealPath("/download");
        System.out.println("文件夹的路径:"+path);
        // 拼接成文件的路径
        String filepath = path+"/"+filename;
        System.out.println("文件的路径:"+filepath);
        // 文件的输入已经获取到了
        InputStream in = new FileInputStream(filepath);
        // 获取输出流
        OutputStream os = response.getOutputStream();
        // 拷贝
        int len = 0;
        byte [] b = new byte[1024];
        while((len = in.read(b)) != -1){
            os.write(b, 0, len);
        }
        in.close();
        os.close();

验证码

1.验证码画图!!
2.注意
    * 验证码的程序不能在前台完成校验!!只能后台校验!!
    * 有可能有中文?中文的数据也是提前准备好的。

3.分析过程
    /**
     * 1.获取画布对象
     * 2.获取画笔对象
     *  2.1 画布默认是黑色的,目的给画布设置成灰色!!
     *  2.2 画实心的矩形,大小和画布一样大,覆盖的效果。
     * 3.准备好数据
     *  3.1 通过随机的方式获取数据,通过画笔的对象把数据画到图片上就可以了。
     * 4.把内存中的图片输出到客户端上
     */

4.代码
    int width = 120;
    int height = 30;
    // 先获取画布的对象
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    // 获取画笔对象
    Graphics g = image.getGraphics();
    // 设置颜色
    g.setColor(Color.GRAY);
    // 画实心的矩形,覆盖效果
    g.fillRect(0, 0, width, height);

    // 设置颜色
    g.setColor(Color.BLUE);
    g.drawRect(0, 0, width-1, height-1);

    g.setColor(Color.YELLOW);
    // 设置字体
    g.setFont(new Font("隶书", Font.BOLD, 18));

    // 准备好一些数据,把数据画到画布上
    String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";

    Random random = new Random();
    int x = 20;
    int y = 20;
    // 随机获取4个字符,显示画布上
    for (int i = 0; i < 4; i++) {
        // 随机获取字符
        int index = random.nextInt(words.length());
        // 获取该位置的字符
        char ch = words.charAt(index);
        // System.out.println(ch+"");
        // 向 画布上写字符串
        g.drawString(ch+"", x, y);
        x += 20;
    }

    // 画干扰线
    g.setColor(Color.GREEN);
    int x1,y1,x2,y2;
    for (int i = 0; i < 4; i++) {
        x1 = random.nextInt(width);
        y1 = random.nextInt(height);
        x2 = random.nextInt(width);
        y2 = random.nextInt(height);
        g.drawLine(x1, y1, x2, y2);
    }

    // 先输出到客户端上
    ImageIO.write(image, "jpg", response.getOutputStream());

ServletRequest对象的概述

ServletRequest对象的概述

1.request对象代表的请求的对象(从客户端到服务器端),把客户端的一些信息封装到request对象中。
2.想获取到客户端的内容,需要找request对象。
3.ServletRequest也是一个接口,子接口是HttpServletRequest接口。实现类由Tomcat服务器提供的实现类。

4.方法
    * Object getAttribute(String name)          -- 获取域对象中的值(重点)
    * String getParameter(String name)          -- 获取请求的参数(获取一个值 text  password  radio)(重点)
    * Map<String,String[]> getParameterMap()    -- 获取请求的参数(返回的Map集合的key是name的名称,值是用户输入的值) (重点)
    * String[] getParameterValues(String name)   -- 获取请求的参数(获取的表单中的复选框的值) 

    * String getRemoteAddr()                -- 获取ip地址
    * void removeAttribute(String name)         -- 删除值
    * void setAttribute(String name, Object o)      -- 存入值(重点)
    * void setCharacterEncoding(String env)     -- 设置request对象的缓冲区的编码(重点)

    * String getHeader(String name)             -- 获取请求头的信息(重点)

获取客户端的一些信息

1.学习有一些方法,但是非常非常多的,不用记。简单介绍一遍,以后用了,查询文档就可以了!!
2.方法和获取的内容
    * http://localhost:8080/day10/AServlet?username=xxx&password=yyy

     * String getScheme():获取协议,http
    * String getServerName():获取服务器名,localhost
     * String getServerPort():获取服务器端口,8080
     * String getContextPath():获取项目名,/day10
     * String getServletPath():获取Servlet路径,/AServlet
     * String getQueryString():获取参数部分,即问号后面的部分。username=xxx&password=yyy
     * String getRequestURI():获取请求URI,等于项目名+Servlet路径。/day10/AServlet
     * String getRequestURL():获取请求URL,等于不包含参数的整个请求路径。http://localhost:8080/day10/AServlet
    
3.需要大家记住一个方法
* request.getContextPath() – 获取的项目名称

获取请求头的信息

1.请求头,重要的几个?
    * referer           -- 记住当前网页的来源,作用:防止盗链
    * user-agent        -- 判断浏览器的版本

2.获取头的方法
    * request.getHeader("头");

3.user-agent的头的作用
    * 代码    String agent = request.getHeader("user-agent");
    * 作用
        * 可以判断浏览器
        * 文件下载的时候,弹出的窗口显示中文的话,会乱码的!!解决乱码的问题。
            * 根据不同的浏览器,采用不能编码来解决。

4.referer的头
    * 记住当前网页的来源
    * 防止盗链(有代码)

获取请求的参数(表单)

1.获取请求的参数,提供了三个方法。
2.方法
    * String getParameter(String name)          -- 获取请求的参数(获取一个值 text  password  radio)
    * Map<String,String[]> getParameterMap()    -- 获取请求的参数(返回的Map集合的key是name的名称,值是用户输入的值) 
    * String[] getParameterValues(String name)   -- 获取请求的参数(获取的表单中的复选框的值) 
3.演示方法

4.代码
    * 前台代码
        <h3>注册页面</h3>
        <form action="/day10/reg" method="get">
            姓名:<input type="text" name="name" /><br/>
            密码:<input type="password" name="password" /><br/>
            爱好:<input type="checkbox" name="love" value="java" />java
                <input type="checkbox" name="love" value="lq" />篮球
                <input type="checkbox" name="love" value="dbj" checked/>大宝剑
                <br/>
            <input type="submit" value="注册" />  
        </form>

    * 后台代码
        // 解决的是post中文乱码的问题
        // request.setCharacterEncoding("UTF-8");

        // 先接收用户名
        String name = request.getParameter("name");

        // 需要自己重新构造
        name = new String(name.getBytes("ISO-8859-1"),"UTF-8");

        String password = request.getParameter("password");
        System.out.println(name+" : "+password);
        // 获取爱好
        String [] loves = request.getParameterValues("love");
        System.out.println("爱好:"+Arrays.toString(loves));

        // 其他的处理了
        System.out.println("====================================");

        // 通过getParameterMap方法获取表单中的值
        Map<String, String []> map = request.getParameterMap();
        // map的key(name的名称 -- name  password  love)
        // map的value(用户输入的值 meimei 123  java dbj)
        Set<String> keys = map.keySet();
        // 获取到每一个key值
        for (String key : keys) {
            String [] values = map.get(key);
            System.out.println(key+" : "+Arrays.toString(values));
        }

获取请求中文乱码问题

1.提交中文,会产生乱码的问题。目的:需要解决中文乱码的问题。
2.解决request获取请求参数的中文乱码的问题
    * post
        * 设置request缓冲区的编码就ok了。
        * 表单的html页面是UTF-8编码,把数据传入Tomcat服务器中。Tomcat创建的request对象。默认的编码是ISO-8859-1
        * 不支持中文。request缓冲区的默认的编码是ISO-8859-1
        * 支持设置,设置request缓冲区的编码就可以了。
            * void setCharacterEncoding("UTF-8) 

    * get
        * 自己手动解决乱码的问题。
        * name = new String(name.getBytes("ISO-8859-1"),"UTF-8");

3.总结
    * request获取请求参数的中文乱码的问题,分成两种请,分成post和get方式
    * post和get解决方案是不同的
        * post
            * 设置request缓冲区的编码就可以了
            * setCharacterEncoding("UTF-8) 
        * get
            * 先获取到用户输入的值,手动自己转编码
            * name = new String(name.getBytes("ISO-8859-1"),"UTF-8");

request域对象

1.域对象:通过域对象传递数据。
2.方法
    * setAttribute()
    * getAttribute()
    * removeAttribute()

3.范围的不同
    * ServletContext域对象,范围是最大的,(代表整个WEB的应用,在WEB项目中,所有的资源都共享ServletContext域对象)
    * request域对象,域的范围比较小了,代表的是一次请求的范围!!(发送请求,得到响应,就是一次请求的范围!!)

4.有什么作用?
    * 用来传递数据,会传递什么数据?
    * 以后:在会servlet中获取数据,需要把数据展示到页面上。提示的信息!!

转发和重定向的区别

1.会编写转发的代码,理解转发的含义。
2.掌握转发和重定向的区别(什么使用转发,什么使用重定向)

3.转发:和重定向的功能比较类似的,转发也可以完成页面的跳转的功能!!
4.转发代码怎么写?
    * 重定向 response.sendRedirect("路径");
    * 转发,找request对象,提供了一个方法
        * RequestDispatcher getRequestDispatcher(String path)  ,返回的是RequestDispatcher一个对象
        * RequestDispatcher提供了一个方法,void forward(ServletRequest request, ServletResponse response)  
            * forward帮咱们转发的功能!!
    * 代码怎么写?
        * request.getRequestDispatcher("").forward(request,response)        -- 转发的代码的编写!!

5.转发和重定向路径的写法
    * 重定向的地址(客户端的绝对路径,包含项目名称)
    * 转发的路径(服务器端的绝对路径,不包含项目名称) 

6.转发和重定向区别
    * 共同点:都可以完成页面跳转的功能!
    * 不同点
        * 重定向是两次请求,两次响应,转发是一次请求,一次响应,就可以request域来传递一些数据!!
        * 重定向的地址栏会发生变化,转发的地址栏不会发生变化。
        * 重定向可以定向到任何的页面(项目的中的页面,网络上的资源),转发只能在服务器的内部完成跳转!!
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值