天天看点

javaWeb之Response

重定向的原理图:
    response是专门给客户端响应数据的响应对象.
    Http协议规定: 响应数据也要分成三部分:  
        响应行:    主要学习设置状态码.

        响应头:    主要学习重定向(重点)     //掌握
            //你找张三借钱, 张三没钱, 张三找李四沟通, 借钱给你(请求转发).
            //你找张三借钱, 张三没钱, 张三告诉你思聪有钱, 你去找他(重定向).

        响应体: 主要是给客户端响应页面上要展示的数据(验证码).

    功能:
        public void setStatus(int sc);      //200, 302, 404, 500
            //: 请求成功.
            //: 请求重定向.
            //: 访问的资源不存在.
            //: 服务器内部错误.

        public void setHeader(String name, Stirng value);
            //设置响应头信息. name表示属性名, value表示属性值.

            //响应重定向的路径
            //response.setHeader("location","http://www.itcast.cn");

    重定向原理步骤:
        ) 浏览器访问Servlet1, 但是该请求Servlet1实现不了, 想交给别的Servlet对象来实现.
        ) 在Servlet1中完成如下设置:
            A: 设置状态码, 通知浏览器找其他资源.
                response.setStatus();
            B: 设置响应头, 告诉浏览器访问新资源的路径.
                response.setHeader("location", "/项目名/servlet名");
        ) 浏览器识别服务器返回的状态码.
            马上准备访问新资源.
            //取出新资源的路径, 马上访问新资源.
        ) 浏览器向新资源(新的Servlet对象)发出请求.
        ) 新的Servlet对象响应浏览器的请求.



 重定向的实现
    需求: 使用浏览器访问"/responseServlet1", 通过重定向跳转到: 黑马官网.

    实现方式:
        方式一:  分解式
            //) 响应状态码.
            response.setStatus();

            //) 响应重定向的路径
            response.setHeader("location","http://www.itcast.cn");

        方式二: 合并式
            response.sendRedirect("http://www.itcast.cn");


 重定向和请求转发的区别:
     相对于浏览器而言, 是几次请求几次响应?
        重定向: n次请求, n次响应.
        请求转发: 一次请求, 一次响应.

     浏览器地址和窗体内容是否一致?
        重定向:        一致.
        请求转发:   不一致.

     页面跳转是在服务器内部, 还是服务器外部?
        重定向:        可以是服务器内部, 也可以是服务器外部.
        请求转发:   只能在服务器内部. (思路: 把request对象当做容器)

     关于是否可以跳转项目外部的路径.
        重定向:        response.sendRedirect("/项目名/servlet名");
        请求转发:   request.getRequestDispatcher("/servlet名").forward(request,response);

     如果需要将request当做容器使用, 谁合适?
        重定向:        不合适.
        请求转发:   更合适.


 页面定时刷新到新网页
    应用场景:
        ) 访问的资源不存在, s 后跳转到首页.
        ) 支付成功, s 后跳转到首页.

    实现方式:
        通过设置refresh响应头信息来完成这个功能.

    格式:
        response.setHeader("refresh","秒数;url=网址");
        //注意: 路径可以是外部路径也可以是内部路径.

    例如:
        response.setHeader("refresh","5;url=http://www.itcast.cn");


 向浏览器输出中文
    应用场景:
        浏览器显示的内容, 下载文件等.

    response: //以流的形式, 将内容输出给浏览器.
        response.getWriter();       //获取响应体的字符输出流.
        response.getOutputStream(); //获取响应体的字节输出流.

    注意:
        ) 字符流和字节流不能同时使用.
        ) 复制文件建议用: 字节流.  
           手动生成响应内容建议用: 字符流.
        ) 不需要关流, tomcat会自动调用close(),flush()方法. 

    案例:
        需求: 向浏览器输出: "你们真的很棒!"
        //字符流实现
        //方式一: 字符流, 合并式     //推荐使用
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("你们真的很棒!");

        //方式二: 字符流 分解式
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        response.getWriter().println("你们真的很棒!");

        //方式三:
        response.getOutputStream().write("你们真的很棒!".getBytes("gbk"));

 验证码代码
    作用: 防止暴力破解.

    页面上的验证码生成:
        验证码一般是一个图片, 而这个图片是在Java程序中动态生成的.
        需要使用Java中GUI的技术完成.

    页面显示图片的原理:
        ) 浏览器向服务器发送请求, 例如请求: html
            /*
                文本A;
                文本B;
                图片C;
                图片D:
            */
        ) 服务器把该页面响应给浏览器.
        ) 浏览器按照从上往下的顺序解析页面.
            是文本, 就自动解析.
            是图片, 会再次向服务器发送请求, 加载该图片.

    代码实现:
        //以后用到了, 直接复制即可.
         //给浏览器绘制一个: 带验证码的图片即可.
        int width = ;
        int height = ;

        // 创建一张图纸(宽, 高, 颜色类型).
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 获取画笔.
        Graphics g = bi.getGraphics();

        // 设置图片的背景色.
        // 选定颜色.
        g.setColor(Color.white);
        // 选定填充的大小
        g.fillRect(, , width, height);

        // 设置验证码的边框
        // 选定颜色
        g.setColor(Color.red);
        // 选定绘制的方式(大小)
        g.drawRect(, , width - , height - );

        // 获取生成的验证码, 在控制台中输出
        String str = "";

        // 生成随机的字符(生成个), 然后显示在该图片上.
        // 获取数据源(数字, 字母)
        String data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        // 创建随机数对象.
        Random r = new Random();
        // 因为要生成个, 所以用循环改进.
        for (int i = ; i < 4; i++) {
            // 设置字体大小及随机字体颜色.
            g.setFont(new Font("楷体", Font.BOLD, ));
            g.setColor(new Color(r.nextInt(),r.nextInt(),r.nextInt()));
            // 把字符绘制到页面上.
            String s = "" + data.charAt(r.nextInt(data.length()));
            g.drawString(s,  + i * , );
            str += s;
        }

        // 绘制干扰线
        for (int i = ; i < 10; i++) {
            g.setColor(new Color(r.nextInt(),r.nextInt(),r.nextInt()));
            g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));
        }

        // 把图纸显示在浏览器中(图纸, 图片格式, 字节输出流(网页面中写数据的)).
        ImageIO.write(bi, "jpg", response.getOutputStream());

        System.out.println(str);



 JSP简介
    需求: 使用servlet向浏览器输出一个百度超链接页面.
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("<html>");
        response.getWriter().println("<head><titile>百度超链接</title></head>");
        response.getWriter().println("<body>");
        response.getWriter().println("<a href='http://www.baidu.com'>百度</a>");
        response.getWriter().println("</body>");
        response.getWriter().println("</html>");


        //缺点: 由于使用字符串拼接, 阅读困难, 维护困难, 开发困难.
        //可以通过: JSP解决该问题.

    JSP概述:
        Java Server Pages, Java服务器页面, 其本质就是一个Servlet.
        //是一门动态语言, 里边既可以写html代码, 也可以写css代码,
        //可以写js代码, 也可以写Java代码.


 在JSP中嵌入Java代码(JSP的快速入门)
    //写在.jsp文件中即可, 例如: helloworld.jsp文件中即可.

    方式一: 脚本表达式, 向浏览器输出内容.
        //类似于输出语句.
        格式:
            <%=变量名或者值 %>
        例如:
            <%="hello world" %>
            <%= %>
            <%=true %>

    方式二: 脚本片段, 类似于: 方法中一段代码.
        <%
            for(int i=; i<=10; i++) {
        %>
            <h3><%=i %><h3>
        <%
            }
        %>

    方式三: 脚本声明, 声明当前类的成员变量, 成员方法, 内部类等.
        <%!
            int x = ;

            public int add(int x,int y) {
                return x + y;
            }

            class InnerClass{}
        %>

        成员变量: <%=x %><br>
        成员方法:  +  = <%=add(,) %>

        <%
            request.setAttribute("money",);
        %>
        薪资: <%=request.getAttribute("money") %>


    原理:
        ) 浏览器访问服务器上的.jsp文件.
        ) .jsp文件会被解析成.java文件(存在tomcat\work文件夹中)
        ) .java文件会被编译成.class文件(虚拟机只认识.class文件)
        ) 浏览器加载该.class文件到内存, 将内容显示到页面上.

    /*
        C:\Users\用户名\.IntelliJIdea2016.3\system\tomcat\项目名称\work\Catalina\localhost\ROOT\org\apache\jsp
        C:\Users\16055\.IntelliJIdea2017.2\system\tomcat\Unnamed_javaProject_big14_4\work\Catalina\localhost\day12\org\apache\jsp
    */


 JSP中的内置对象
    常见面试题: 请写出JSP的内置对象.
        page(当前页面), request, session(当前会话), application,
        pageContext, response, config, out, exception

        四大域容器:
            page, request, session, application
        推理法:    
            response, config
        联想法:
            out, exception, pageContext
        /*
            1. .jsp底层是一个Servlet类.
            2. .jsp文件有 9 大内置对象.
        */



 EL表达式
    EL: Expression Language(表达语言的意思), 是为了使JSP写起来更加简单.
        //如果使用自定义类型的值, 需要导包: 
        //<%@page import="com.itheima.domain.Product"%>

    作用:
        快速获取域容器中的数据(request容器, context容器).

    格式:
        ${域对象.类名.属性名}

    例如:
        ${requestScope.product.name}


 项目的准备工作
    ) 完成数据表的创建及表数据的添加动作.
    ) 把要使用的jar包拷贝到: web-inf\lib中.
    ) 把c3p-config.xml文件复制到src文件夹中.
    ) 新建包:
        com.itheima.utils
        com.itheima.domain
        com.itheima.web
        com.itheima.service
        com.itheima.dao
    ) 把JDBCUtils工具类拷贝到:utils包中.
    ) 新建JavaBean类.


 登陆案例的分析
    优化的地方:
        如果登陆失败: 
            使用请求转发跳转到 login.jsp页面, 显示错误信息.
        如果登陆成功:
            使用重定向跳转到首页: index.jsp


 获取参数封装到JavaBean中.
    BeanUtils的原理(作用):
        将map中的数据复制到指定的JavaBean中.





    ) 登陆注册案例
        准备工作: 
            ) 复制jar包.
            ) 新建文件夹(分层)
            ) 拷贝c3p-config.xml文件 和 JDBCUtils工具类.
            ) 新建实体类.

        登陆案例:
            ) 新建index.jsp页面,  里边写一句话<h1>欢迎登陆本网站</h1>
            ) 新建login.jsp页面, 关联 /项目名/loginServlet  这个servlet对象.
                //里边写的是form表单, 包裹<table>, 表格里边是: 用户名, 密码, 提交按钮(登陆)
            ) 在com.itheima.web包下新建LoginServet类, 并在其doGet()方法中完成如下功能:
                A: 获取用户通过浏览器提交过来的数据.
                    request.getParameter("参数名");
                B: 将用户提交过来的数据封装成: User对象.
                    //可以通过BeanUtils工具类实现.
                    User user = new User();
                    BeanUtils.populate(user, request.getParameterMap());
                C: 调用Service层的功能, 将该对象传输过去校验, 并接收返回结果.
                    UserService us = new UserService();
                    User loginUser = us.login(user);
                D: 编写Service层的代码.
                    UserDao ud = new UserDao();
                    User loginUser = ud.login(user);
                E: 编写Dao层的代码.
                    //创建QueryRunner对象, 去数据库查找该数据, 并返回.
                    //结果集的处理方式用: BeanHandler
                F: 在LoginServlet类中, 根据Service层的返回结果做校验.   
                    User用户存在:
                        //重定向页面到: 首页(index.jsp)
                        response.sendRedirect("/项目名/index.jsp");

                    User用户不存在:
                        //给页面一个反馈信息: 用户名或者密码错误

                        //版本一: 请求跳转页面到: 登陆页面(login.jsp), 让用户接着登陆

                        //版本二: 请求跳转页面到: 注册页面(register.jsp), 让用户注册账号


        注册案例:

           

继续阅读