zoukankan      html  css  js  c++  java
  • [Java拾遗四]JavaWeb基础之Servlet_Request&&Response

    今天来回顾下之前学过Servle的Resquest以及Response的知识.
    1,Request和Response技术:

        rr的作用:
            request是请求,封装用户的请求信息.若想获取请求信息,找request就行了
            response是响应,封装服务器的响应信息,若想往页面写东西,找response就可以了
        rr的体系结构:
            request
            在servlet中有一个service(ServletRequest,ServletResponse)  抽象方法
            在HttpServlet中实现了service(ServletRequest,ServletResponse)
            并且重载了service(HttpServletRequest,HttpServletResponse)
           
            request的实现类 org.apache.catalina.connector.RequestFacade
            response的实现类 org.apache.catalina.connector.ResponseFacade
           
            request的体系
                ServletRequest(接口)
                    |
                    |
                HttpServletRequest(接口)
                    |
                    |
                RequestFacade(类 tomcat)
               
           response的体系
               ServletResponse(接口)
                    |
                    |
                HttpServletResponse(接口)
                    |
                    |
                ResponseFacade(类 tomcat)
    2,Response
       (1)作用:响应
            http响应的格式:
                响应行 响应头 响应体
        (2)简单介绍api
            操作响应行:
                响应行的格式:
                    协议/版本 状态码 状态码说明
                    HTTP/1.1 200 OK
                常用的方法:
                    setStatus(int)
                    sendError(int)
                    sendError(int,msg)
            操作响应头:
                响应头的格式:
                    key:name
                    key:name1,name2  --多个值的时候用逗号隔开
                常用的方法:
                    setHeader(string,string)
                    setIntHeader(string,int)
                    addHeader(string,string)
                    setDateHeader(string,long)
            操作响应体:
                响应题就是展示的内容
                    getOutputStream()
                    getWriter()
        (3)详解api
           a, 状态码:
                1xx:正在请求中
                2xx:完成请求响应
                    200:成功完成
                3xx:还需浏览器进一步操作
                    302:还需跳转
                    304:浏览器去读缓存
                4xx:用户请求错误
                    404:路径不存在
                5xx:服务器错误:
                    500:服务器错误

            常用方法:
                对于非错误的状态码
                    setStatus(int):例如 setStatus(304)
                对于的错误的状态码
                    sendError(int)
                    sendError(int,msg):返回错误的信息
            b,操作响应头:
                响应头的格式:
                    key:name
                    key:name1,name2  --多个值的时候用逗号隔开
                常用方法:
                    setHeader(String key,String name):给响应设置指定的头信息
                    addHeader(String key,String name1):若存在则追加,反之则设置
                   
                    setIntHeader(String key,int value):给响应设置指定的头信息(int类型的)
                    addIntHeader(String key,int value):若存在则追加,反之则设置
                   
                    setDateHeader(String key,Long long):给相应头设置毫秒值的
            案例:
                重定向:
                    302:还需要跳转
                    需要用到location
                    代码实现:
                        setStatus(302);
                        setHeader("location","跳转的路径");
                    开发中时使用
                        sendRedirect(跳转的路径);
                刷新:
                    response.setHeader("refresh","3;url=跳转的路径");
                   
                重定向和刷新最后的效果是一样的,同样是发送了两次请求
    代码案例:
    使用location跳转:

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setStatus(302);
        //设置跳转路径
        response.setHeader("location","/dayaugmentum10/loca2");
    }

    使用refresh跳转:

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setHeader("refresh", "3;url=/augmentum/1.html");
    }


       c,操作响应体:
            常用的方法:
            ServletOutputStream getOutputStream():字节流
            PrintWriter getWriter():字符流
           
            通过流对象.println(任意内容);
        字符乱码的处理
            设置响应信息的编码格式
                response.setCharacterEncoding("utf-8"):
           
            设置响应信息的编码格式并且通知浏览器用什么编码打开
                response.setHeader("content-type","text/html;charset=utf-8");
                开发中使用
                response.setContentType("text/html;charset=utf-8"); ☆
               
            在页面添加
            <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
        注意事项(针对流)
            字节流和字符流是互斥的.
            tomcat会帮我们关闭流
        验证码:
            作用:防止恶意暴力破解密码

     1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     2     // 使用java图形界面技术绘制一张图片
     3 
     4     int charNum = 4;
     5     int width = 30 * 4;
     6     int height = 30;
     7 
     8     // 1. 创建一张内存图片
     9     BufferedImage bufferedImage = new BufferedImage(width, height,
    10             BufferedImage.TYPE_INT_RGB);
    11 
    12     // 2.获得绘图对象
    13     Graphics graphics = bufferedImage.getGraphics();
    14 
    15     // 3、绘制背景颜色
    16     graphics.setColor(Color.YELLOW);
    17     graphics.fillRect(0, 0, width, height);
    18 
    19     // 4、绘制图片边框
    20     graphics.setColor(Color.BLUE);
    21     graphics.drawRect(0, 0, width - 1, height - 1);
    22 
    23     // 5、输出验证码内容
    24     graphics.setColor(Color.RED);
    25     graphics.setFont(new Font("宋体", Font.BOLD, 20));
    26 
    27     // 随机输出4个字符
    28     Graphics2D graphics2d = (Graphics2D) graphics;
    29      String s = "ABCDEFGHIGKLMNOPQRSTUVWXYZ01234567890";
    30     Random random = new Random();
    31     
    32     String msg="";
    33     int x = 5;
    34     for (int i = 0; i < 4; i++) {
    35         int index = random.nextInt(26);
    36         String content = String.valueOf(s.charAt(index));
    37         msg+=content;
    38         double theta = random.nextInt(45) * Math.PI / 180;
    39         graphics2d.rotate(theta, x, 18);
    40         graphics2d.drawString(content, x, 18);
    41         graphics2d.rotate(-theta, x, 18);
    42         x += 30;
    43     }
    44 
    45     // 6、绘制干扰线
    46     graphics.setColor(Color.GRAY);
    47     for (int i = 0; i < 5; i++) {
    48         int x1 = random.nextInt(width);
    49         int x2 = random.nextInt(width);
    50 
    51         int y1 = random.nextInt(height);
    52         int y2 = random.nextInt(height);
    53         graphics.drawLine(x1, y1, x2, y2);
    54     }
    55 
    56     // 释放资源
    57     graphics.dispose();
    58 
    59     // 图片输出 ImageIO
    60     ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    61 
    62 
    63 }
    验证码模版


    3,Request
        请求.若想获取请求信息,找我就可以了
        请求的格式:
            请求行 请求头 请求体
        (1)api简介
            a,请求行
                格式:请求方式 资源路径 协议/版本
                例如:GET /augmentum/1.html HTTP/1.1
                常用方法:
                    getMethod()
                    getRequestURI()
                    getProtocol()
                    getQueryString()
           b, 请求头
                格式:
                    key:name1[,name2]
                常用方法:
                    String getHeader(key)
                    Enumeration getHeaders(key)
                    Enumeration getHeaderNames();
                   
                    getIntHeaders(key)
           c, 请求体
                只有post才有请求体,存放就是post请求的参数
                例如 username=tom&password=123&hobby=eat&hobby=sleep
                常用方法:
                    String getParameter(key)
                    Enumeration getParameterNames()
                    Map<String,String[]> getParameterMap();
                    String[] getParameterValues(key);
               
        (2)api详解
            a,请求行:
                常用方法:
                    getMethod():获取请求的方式
                    getRequestURI():获取的从项目名开始到请求参数参数之前(?)
                    getProtocol():获取协议和版本
                    getQueryString():以字符串的形式获取请求参数
                    结果:   
                        GET
                        /augmentum/row
                        HTTP/1.1
                        login=tom&password=123

                        GET /augmentum/form.html HTTP/1.
                常见的请求方式:post和get
                    区别:
                      1.get请求的参数会出现在地址栏上,post不会,post相对安全
                      2.get请求参数的大小有限制,post理论上没有.
                      3.只有post有请求体.
                获取用户信息:
                    getRemoteAddr():获取用户ip
                    getRequestURL():获取请求路径(带协议的路径 URL)
                    getContextPath():获取项目名
                    结果:
                        192.168.40.1xx
                       
    http://192.168.40.97/augmentum/row
                        /augmentum

     1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     2     /*//获取请求方式
     3     String method = request.getMethod();
     4     System.out.println(method);
     5     //获取请求资源路径
     6     String uri = request.getRequestURI();
     7     System.out.println(uri);
     8     //获取协议版本
     9     String pro = request.getProtocol();
    10     System.out.println(pro);
    11     //获取get请求的请求参数
    12     String s = request.getQueryString();
    13     System.out.println(s);*/
    14     
    15     //获取用户ip
    16     String addr = request.getRemoteAddr();
    17     System.out.println(addr);
    18     //获取请求路径
    19     String url = request.getRequestURL().toString();
    20     System.out.println(url);
    21     //获取项目名
    22     String contextPath = request.getContextPath();
    23     System.out.println(contextPath);
    24 }

            b,请求头:
                格式:
                    key:name1[,name2]
                常用方法:
                    String getHeader(key):获取指定的头信息
                    int getIntHeader(key):
                    long getDateHeader(key):

                    Enumeration getHeaders(key):以Enumeration形式获取指定头的信息
                    Enumeration getHeaderNames();返回所有的请求头的名称
                防盗链
                    使用的 referer请求头

        String referer = request.getHeader("referer");
        if (referer==null) {
            System.out.println("地址栏来的 可以访问");
        }else if(referer.startsWith("http://localhost/augmentum")){
            System.out.println("站内访问");
        }else{
            System.out.println("站外访问");
        }
    }

            c,请求体:
                只有post请求才有,用来存放请求参数.
                get请求和post通用的方法:
                获取用户参数:
                    String getParameter(key):获取指定的参数信息
                    String[] getParameterValues(key):以string[]的格式返回指定的参数信息
                   
                    Map<String,String[]> getParameterMap();以map的形式返回所有的参数
                    Enumeration getParameterNames();以Enumeration形式返回所有的参数名称
                   
                    例如:
                        姓名:tom
                        爱好:[drink, sleep]
                        ----------------------
                        username:[tom]
                        password:[1234]
                        hobby:[drink, sleep]
                        ----------------------
                        username:[tom]
                        password:[1234]
                        hobby:[drink, sleep]

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取姓名
        String username = request.getParameter("username");
        System.out.println("姓名:"+username);
        //获取爱好
        String[] hobby=request.getParameterValues("hobby");
        System.out.println("爱好:"+Arrays.toString(hobby));
        //获取所有
        System.out.println("----------------------");
        Map<String,String[]> map=request.getParameterMap();
        for (String name : map.keySet()) {
            System.out.println(name+":"+Arrays.toString(map.get(name)));
        }
        System.out.println("----------------------");
        //获取所有的参数名称
        Enumeration<String> params = request.getParameterNames();
        while(params.hasMoreElements()){
            
            String name = params.nextElement();
            System.out.println(name+":"+Arrays.toString(request.getParameterValues(name)));
        }
    }

           d,域对象:
                request:
                    一次请求中,响应之前.
                    请求串,请求链
                    request.getRequestDispatcher("转发路径").forward(request,response)
                    服务器内部跳转
                    客户端的路径:   /工程名/编写的路径
                    服务器的内部路径:   /编写的路径
                常用方法:
                    xxxAttribute()
                    setAttribute(String,Object);
                    Object getAttribute(String)
                    removeAttribute()
               

        请求转发与重定向的区别
           1.请求转发是服务器内部跳转,地址栏不会发生改变
            重定向地址栏会发生改变。

            2.请求转发,只有一次请求,一次响应.
            重定向,有两次请求,两次响应。

            3.请求转发存在request域,可以共享数据.
            重定向不存在request域。

            4.请求转发只能在服务器的内部跳转,简单说,只能访问本站内资源。
            重定向可以访问站外资源,也可以访问站内资源.

            5.请求转发是由request 发起的 . request.getRequestDispatcher().forward()
            重定向是由response 发起的  response.sendRedirect();

            6.请求转发与重定向时路径写法不一样.
            重定向要跳转的路径是从浏览器在次发起的,是浏览器端路径,写法: /工程名/资源
            请求转发是服务器内部跳转,这时它与浏览器无关 写法:/资源
    可用如下图来表示:
    reqAndResp

    请求的中文乱码:
        浏览器地址栏使用utf-8编码
        tomcat7使用的iso8859-1编码
       
        参数使用utf-8编码,tomcat使用iso-8859-1进行解码出现了乱码.
        解决的思路:
            把接受的参数先iso-8859-1编码,然后使用utf-8进行解码
            对于post请求和get请求可以通过
                new String(name.getBytes("iso8859-1"),"utf-8");
            对于post请求还可以使用
                request.setCharacterEncoding("utf-8");
           
            乱码解决过程       
            String s="赵四";
            String s1=URLEncoder.encode(s,"utf-8");
            String s2=URLDecoder.decode(s1, "iso8859-1");
            System.out.println(s2);
           
            //先使用iso8859-1编码
            String s3 = URLEncoder.encode(s2, "iso8859-1");
            //使用utf-8解码
            String s4 = URLDecoder.decode(s3, "utf-8");
            System.out.println(s4);

  • 相关阅读:
    设计模式之单例模式
    EditText的光标在4.0中的bug
    省赛热身赛之Median
    VB6获取本机所有IP地址公用函数
    省赛热身赛之Kagome Kagome
    OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较
    使用jQuery validate 验证注册表单
    Oracle 发布 GlassFish 路线图
    Oracle 发布 GlassFish 路线图
    Java 中的双重检查(DoubleCheck)
  • 原文地址:https://www.cnblogs.com/wang-meng/p/5402392.html
Copyright © 2011-2022 走看看