zoukankan      html  css  js  c++  java
  • Servlet的API(二)

      web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。request和response对象既然代表请求和响应,那我们获取客户机提交过来的数据,只需要找request对象即可,要向客户机输出数据,只需要找response对象即可。这一节我们来看看Servlet的这两个对象:HttpServletResponse对象和HttpServletRequest对象。

    1. HttpServletRequest对象

            HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象中的方法,可以获得客户的这些信息。

            1)获取客户机环境信息常用的方法如下:(具体见Demo1)

    getRequestURL();   //返回客户端发出请求时的完整URL  
    getRequestURI();   //返回请求行中的资源名部分  
    getQueryString();  //返回请求行中的参数部分  
    getRemoteAddr();   //返回发出请求的客户机的IP地址  
    getRemoteHost();   //返回发出请求的客户机完整主机名  
    getRemotePort();   //返回客户机所使用的网络端口号  
    getLocalAddr();    //返回WEB服务器的IP地址  
    getLocalName();    //返回WEB服务器的主机名  
    getMethod();       //得到客户机请求方式  

      相应的示例代码Demo1如下:

    //获取客户机环境信息常见的方法  
    public class RequestDemo1 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            //uri标识一个资源,url标识互联网上的一个资源,所以url是uri的子集  
            System.out.println(request.getRequestURL());//会打印出http://localhost:8080/test/servlet/RequestDemo1  
            System.out.println(request.getRequestURI());//会打印出/test/servlet/RequestDemo1  
              
            //请求http://localhost:8080/test/servlet/RequestDemo1?name=eson_15  
            System.out.println(request.getQueryString());//打印出name=eson_15  
              
            System.out.println(request.getRemoteAddr());//打印出来访地址:127.0.0.1       
            System.out.println(request.getRemoteHost());//打印来访主机:127.0.0.1        
            System.out.println(request.getRemotePort());//打印来访端口号:3969  
            System.out.println(request.getLocalAddr());//打印出服务器地址:127.0.0.1   
              
            System.out.println(request.getMethod());//打印访问方式:GET/POST  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            doGet(request, response);  
        }  
    }  

       2)获取请求信息常用的方法--Map如下:(Demo2)

    //获得客户机请求头  
    getHeader(String name);  
    getHeaders(String name);  //获取指定名称的头的所有值  
    getHeaderNames(); //获取所有头的名称  
      
    //获得客户机请求参数(客户端提交的数据)  
    getParameter(name);  
    getParameterValues(String name);  //获取指定参数名的所有值  
    getParameterNames();  //获取所有参数名  
    getParameterMap();  //获取封装数据的map集合,在框架中使用频繁  

    相应的示例代码Demo2如下:

    public class RequestDemo2 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            <pre name="code" class="java">                //获取压缩方式 gzip,deflate.实际中在输出数据之前可以用该方法先判断浏览器是否支持gzip方式  
            System.out.println(request.getHeader("Accept-Encoding"));  
              
            //获取指定名称的头的所有值  
            Enumeration e = request.getHeaders("Accept-Encoding");  
            while(e.hasMoreElements()) {  
                String value = (String) e.nextElement();  
                System.out.println(value);  
            }         
            System.out.println("----------------------------");       
            //获取所有的头和值  
            e = request.getHeaderNames();  
            while(e.hasMoreElements()) {  
                String name = (String) e.nextElement();  
                String value = request.getHeader(name);  
                System.out.println(name + "=" + value);  
            }         
            System.out.println("----------------------------");       
            //http://localhost:8080/day06/servlet/RequestDemo2?name=eson_15  
            System.out.println(request.getParameter("name"));//eson_15  
              
            //http://localhost:8080/day06/servlet/RequestDemo2?like=sing&like=dance  
            String likes[] = request.getParameterValues("like");//获取指定参数名的所有值  
            //重要!获取数组数据的方式(可避免空指针异常)  
            for(int i = 0; likes != null && i < likes.length; i++) {  
                System.out.println(likes[i]);//sing dance  
            }         
            System.out.println("----------------------------");       
            //http://localhost:8080/day06/servlet/RequestDemo2?name=eson_15&like=swim&love=you  
            e = request.getParameterNames();//获取所有参数名  
            while(e.hasMoreElements()) {  
                String name = (String) e.nextElement();  
                String value = request.getParameter(name);  
                System.out.println(name + "=" + value);  
            }         
            System.out.println("----------------------------");       
            ////http://localhost:8080/day06/servlet/RequestDemo2?name=eson_15&like=swim&love=you  
            Map<String, String[]> map = request.getParameterMap();  
            for(Map.Entry<String, String[]> me : map.entrySet()) {  
                String name = me.getKey();  
                String value[] = me.getValue();  
                System.out.println(name + "=" + value[0]);  
            }  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
            doGet(request, response);  
        }  
    }  

        3)实现请求转发:(Demo3/test.jsp/Demo4)

            request对象实现请求转发:请求转发指一个web资源受到客户端请求后,通知服务器去调用另一个web资源进行处理。请求转发应用场景:MVC设计模式        request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forwoard方法可以实现请求转发。        request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其他web资源处理。相关方法如下:

    setAttribute();    //设置属性  
    getAttribute();    //获得属性值  
    removeAttribute(); //删除某个属性  
    getAttributeNames(); //获得所有属性名  
    //以上所有方法中的参数我都省略了,括号里为空并不代表没有参数!!   

        相应的示例代码如下:

    //Demo3:请求转发:MVC 重点  
    public class RequestDemo3 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
              
            String data = "abcd";  
              
            //开发中不能用ServletContext做容器,因为用户公用一个ServletContext,一个用户设置了数据后,另一个用户如果也设置了,将会覆盖第一个用户的值       
    //      this.getServletContext().setAttribute("data", data);  
              
            //request本身就是一个容器,我们可以用request来传递数据,不同的用户有不同的request,相互之间不会产生影响  
            request.setAttribute("data", data);  
                          
            //转发方法1,框架习惯用这种  
          //    RequestDispatcher  rd = this.getServletContext().getRequestDispatcher("/test.jsp");  
          //    rd.forward(request, response);  
              
            //转发方法2, 开发习惯用这种。这两种方法没有区别  
            RequestDispatcher rd = request.getRequestDispatcher("/test.jsp");  
            rd.forward(request, response);  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            doGet(request, response);  
        }  
    }  

     相应的test.jsp页面如下:

    <html>  
      <head>     
      </head>  
      <body>  
        <%  
            //String data = (String) this.getServletContext().getAttribute("data");  
            String data = (String) request.getAttribute("data");  
            out.write(data);  
         %>  
      </body>  
    </html>  

       4)获取用户提交数据(Demo4/form.html)
            首先看一下前台页面form.html,主要是获得几个参数:

    <!DOCTYPE html>  
    <html>  
      <head>  
        <title>form.html</title>  
          
        <meta name="keywords" content="keyword1,keyword2,keyword3">  
        <meta name="description" content="this is my page">  
        <meta name="content-type" content="text/html; charset=UTF-8">  
        <meta http-equiv="content-type" content="text/html;charset=UTF-8">  
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->  
      
      </head>  
        
      <body>  
        <form action="/test/servlet/RequestDemo4" method="get">  
            用户名:<input type="text" name="username"/><br/>  
            密码:<input type="password" name="password"/><br/>  
            性别:  
                <input type="radio" name="gender" value="male"/><input type="radio" name="gender" value="female"/><br/>  
                  
            城市:  
                <select name="city">  
                    <option value="beijing">北京</option>  
                    <option value="shanghai">上海</option>  
                    <option value="guangzhou">广州</option>  
                </select><br/>  
                  
            爱好:  
                <input type="checkbox" name="like" value="sing">唱歌  
                <input type="checkbox" name="like" value="dance">跳舞  
                <input type="checkbox" name="like" value="basketball">篮球  
                <input type="checkbox" name="like" value="football">足球  
                <br/>  
                  
            简历:  
                <textarea rows="5" cols="60" name="resume">请输入简历</textarea>  
                <br/>  
                  
            相片:  
                <input type="file" name="file"/><br/>  
                  
                <input type="hidden" name="name" value="xxx"><br/>  
                  
            <input type="submit" value="提交"/>  
              
        </form>  
      </body>  
    </html>  

     当用户提交后,自动跳转到RequestDemo4这个Servlet来处理:

    public class RequestDemo4 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {        
              
            request.setCharacterEncoding("UTF-8");//通过UTF-8获得浏览器中的数据 (post方式有效)  
            //关于GET方式,请见下面这个帖子,写的很详细,请认真阅读一下  
            //http://blog.csdn.net/xh16319/article/details/8456547  
      
            System.out.println(request.getParameter("username"));  
            System.out.println(request.getParameter("gender"));  
            System.out.println(request.getParameter("city"));  
              
            String likes[] = request.getParameterValues("like");  
            for(int i = 0; likes != null && i < likes.length; i++){  
                System.out.println(likes[i]);  
            }  
              
            System.out.println(request.getParameter("resume"));  
            System.out.println(request.getParameter("name"));  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            doGet(request, response);  
        }  
      
    }  

          request比较简单,在开发中主要是用来获取前台带来的数据,以及实现跳转等等。下面看看response对象。

    2. HttpServletResponse对象

            这个对象是指服务器的响应,这个对象中封装了想客户端发送数据,发送响应头,发送响应状态码的方法。如:

    PrintWriter getWriter();  /得到字符流  
    ServletOutputStream getOutputStream(); //得到字节流  
    void setStatus(int sc);  //设置要发送的状态码  
    void setHead(String name, String value);   //响应头 等等  

      response常见应用有如下几个:

            1)向客户端输出中文数据:分别以OutputStream和PrintWriter输出(Demo1)

    public class ResponseDemo1 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
              
    //      outputChineseByByte(response);  
            outputChineseByChar(response);  
        }  
      
        private void outputChineseByChar(HttpServletResponse response)  
                throws IOException {  
            String data = "中国";   
              
            response.setHeader("content-type", "text/html;charset=UTF-8");//通知浏览器以UTF-8打开,注意里面是分号不是逗号  
            response.setCharacterEncoding("UTF-8");//通过response以UTF-8输出  
            /* 
             * 上面两个步骤可以用一个方法来等价 
             * response.setContentType("text/html;charset=UTF-8"); 
             * 在这个方法里相当于做了以上两件事,开发中用该方法比较方便,但是不方便理解,视个人习惯而定 
            */  
            PrintWriter out = response.getWriter();//一定要先将上面设置好才能输出  
            out.write(data);  
        }  
      
        //以字节流方式输出  
        private void outputChineseByByte(HttpServletResponse response)  
                throws IOException, UnsupportedEncodingException {  
            //在服务器端,数据是以哪个码表输出的,那么就要控制浏览器用哪个码表打开  
            String data = "中国";       
            OutputStream out = response.getOutputStream();  
              
            response.setHeader("content-type", "text/html;charset=UTF-8");//告诉浏览器用utf-8编码打开  
    //      这种用html来模拟http响应头的方式也可以,即告诉浏览器以UTF-8的方式打开  
    //      out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes());  
              
            out.write(data.getBytes("UTF-8"));//将“中国”这个字符通过字节输出,一定会查码表,浏览器在打开的时候若查的不是这个码表,则就会出错  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            doGet(request, response);  
        }  
      
    }  

     2)文件下载和中文文件下载(Demo2)

    public class ResponseDemo2 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
    //      downloadFile(response);  
              
            downloadErrorDemo(response);  
        }  
      
        //中文文件的下载,中文文件名要经过URL编码  
        private void downloadFile(HttpServletResponse response) throws FileNotFoundException, IOException {  
            String realPath = this.getServletContext().getRealPath("/狗狗.jpg"); //狗狗.jpg存放在WebRoot下  
            String fileName = realPath.substring(realPath.lastIndexOf("\") + 1);  
              
            //URLEncoding  
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName));  
              
            FileInputStream in = new FileInputStream(realPath);  
            int len = 0;  
            byte buffer[] = new byte[1024];  
            OutputStream out = response.getOutputStream();  
            while((len = in.read(buffer)) > 0) {  
                out.write(buffer, 0, len);  
            }  
              
            in.close();  
        }  
          
        //文件下载注意事项:字节流可以处理任意类型的数据,字符流只能处理字符数据,如果用字符流处理字节数据会导致数据丢失  
        private void downloadErrorDemo(HttpServletResponse response) throws FileNotFoundException, IOException {  
            String realPath = this.getServletContext().getRealPath("/狗狗.jpg");  
            String fileName = realPath.substring(realPath.lastIndexOf("\") + 1);  
              
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName));  
              
            FileReader in = new FileReader(realPath);  
            int len = 0;  
            char buffer[] = new char[1024];  
            PrintWriter out = response.getWriter();  
            while((len = in.read(buffer)) > 0){  
                out.write(buffer, 0, len);  
            }  
            /* 
             * 该程序下载下来的文件无法打开的原因: 
             * 因为任意文件都是通过二进制保存的,那么字符流在读取图片文件时,每次读取一个字符大小的二进制数,该二进制数在gb2312中可能并没有相对应的码,结果就用?代替。 
             * 然后写到浏览器的时候,浏览器拿到?并不能正确解析出原始的二进制数,就用0代替,这样就造成了数据的丢失。 
             * 所以字符流不能去读取字节数据,会导致数据的丢失 
             *  
            */  
            in.close();  
        }  
      
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            doGet(request, response);  
        }  
      
    }  

       3)输出随机图片(Demo3)

    public class ResponseDemo3 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
      
            //6. 设置头,控制浏览器不要缓存图片数据  
            response.setHeader("cache-control", "no-cache");  
              
            //5. 通知浏览器以图片方式打开  
            response.setHeader("content-type","image/jpeg");  
              
            //1. 在内存中创建一幅图片  
            BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);  
              
            //2. 得到图片  
            Graphics2D g = (Graphics2D)image.getGraphics();  
            g.setColor(Color.WHITE);  
            g.fillRect(0, 0, 80, 20);//用白色填充整个矩形背景  
              
            //3. 向图片上写数据  
            g.setColor(Color.RED);//设置图片背景  
            g.setFont(new Font(null,Font.BOLD,20));//设置文字  
            g.drawString(makeNum(), 0, 20);//写上随机数  
              
            //4. 将图片写给浏览器  
            ImageIO.write(image, "jpg", response.getOutputStream());  
        }  
      
         private String makeNum() {   
            Random r = new Random();  
            String num = r.nextInt(9999999) + "";//0-9999999  
            StringBuffer sb = new StringBuffer();  
            for(int i = 0; i < 7-num.length(); i++){  
                sb.append("0");  
            }         
            return sb.toString() + num;  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            doGet(request, response);  
        }  
      
    }  

          4)发送http头以及请求重定向(这一块放在下一篇博客里解说)

    3. web工程中url地址的写法

            在程序中有写:

    //web工程中url地址的写法  
    public class ResponseDemo4 extends HttpServlet {  
      
        public void doGet(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
              
            /*只要是写地址,请统统以"/"开始,若"/"是给服务器用的则代表web工程,若"/"是给浏览器用的则代表webapps**/  
              
            //servletContext  
            this.getServletContext().getRealPath("/dog.jpg");//给服务器用的  
              
            //forward  
            this.getServletContext().getRequestDispatcher("/servlet/ResponseDemo3");//给服务器用的  
              
            //sendRedirect        
            response.sendRedirect("/test/servlet/ResponseDemo3");//给浏览器用的  
              
            //html  <a href="/test/servlet/ResponseDemo3"></a> //给浏览器用的  
        }  
      
        public void doPost(HttpServletRequest request, HttpServletResponse response)  
                throws ServletException, IOException {  
      
            doGet(request, response);  
        }  
      
    }  

      HttpServletRequest和HttpServletResponse就介绍这么多,如有错误之处,欢迎留言指正~

  • 相关阅读:
    linux TCP数据包重传过程----小结
    linux TCP头部的构造的简单分析
    CentOS 7镜像下载
    JAVAEE——BOS物流项目03:学习计划、messager、menubutton、登陆拦截器、信息校验和取派员添加功能
    JAVAEE——BOS物流项目02:学习计划、动态添加选项卡、ztree、项目底层代码构建
    JAVAEE——BOS物流项目01:学习计划、搭建环境、主页设计(jQuery EasyUI)
    Maven02——回顾、整合ssh框架、分模块开发、私服
    巧妙取法——最小公倍数
    深度优先搜索——地宫取宝
    Maven01——简介、安装配置、入门程序、项目构建和依赖管理
  • 原文地址:https://www.cnblogs.com/shanheyongmu/p/5919761.html
Copyright © 2011-2022 走看看