zoukankan      html  css  js  c++  java
  • 16、请求和响应

     
     

    一、HttpServletResponse(服务器-->客户端)

    响应行、响应头、响应体
    里面有很多常量代表状态吗404等

    1、响应行  

    HTTP/1.1   200   OK
    setStatus(int sc);   //设置响应状态码(200)
     

    2、响应头

    1 sendRedirect(String location)  // 请求重定向 (常用)
    2 setHeader(String name, String value)   // 设置响应头信息
    response.setHeader("content-type", "text/html;charset=UTF-8");  //告知浏览器使用什么码表
    1 //告知客户端不缓存
    2  response.setHeader("pragma", "no-cache");
    3  response.setHeader("cache-control", "no-cache");
    4  response.setDateHeader("expires", 0);
    response.setIntHeader("refresh", 1);   //  刷新
    response.setHeader("content-disposition", "attatchment;filename="+filename)  // 告诉浏览器下载文件
    filename = URLEncoder.encode(filename, "UTF-8");  // 解决乱码,设置文件名的编码,将不安全的文件名改为UTF-8
    1 // 虽然这两行代码在之前,但是只是告诉浏览器要重定向,再由浏览器重定向
    2 response.setStatus(302);  // 告诉客户端重新定向新的资源
    3 // 告诉浏览器要去访问那个URL
    4 response.setHeader("location", "/httpServletResponce/demo8");  // 客户端执行,/如果是服务器直接解析就是代表当前应用;要是客户端解析是服务器的根目录就是8080下的/
    1 // 重定向,告诉浏览器重定向和重定向到哪个URL
    2 response.sendRedirect("/httpServletResponce/demo8");

    3、响应正文(主体)

    1 getWrite();   // 字符输出流
    2 getOutputStream();   // 字节输出流
    3 setCharacterEncoding(String charset);   // resuest.setCharacterEncoding,告知服务器要使用什么编码,浏览器使用的什么编码传过来的就是什么编码  客户端-->服务器
    4 setContentType(String type);  // response.setContentType, 封装了setCharacterEncoding、setHeader,告知服务器使用了什么编码,客户端要使用什么编码,服务器传过来的是什么编码就是什么编码 (常用服务器-->客户端
     1 public void doGet(HttpServletRequest request, HttpServletResponse response)
     2         throws ServletException, IOException {
     3     // 服务器中默认编码为IOS8859-1,不支持中文,tomcat规定
     4     response.setCharacterEncoding("UTF-8");  // 告诉服务器用UTF-8解码
     5     response.setHeader("Content-type", "text/html;charset=UTF-8");  // 告诉客户端用什么编码
     6     // 告诉服务器使用的是UTF-8解析文本,告诉客户端使用什么编码
     7     response.setContentType("text/html;charset=UTF-8");
     8     
     9     PrintWriter writer = response.getWriter(); // 得到字符输出流
    10     writer.write("你好");  // 向客户端响应文本内容,出现?
    11 }
    1 public void doGet(HttpServletRequest request, HttpServletResponse response)
    2         throws ServletException, IOException {
    3     
    4     ServletOutputStream out = response.getOutputStream();
    5     out.write("你好".getBytes());  // String的getBytes使用平台的字符集
    6 }

    4、常见应用:

    (1)文件下载

    (2)验证码

    输出随机图片(CAPTCHA图像):Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的测试)
    刷新网页不变是缓存的原因
    (3)刷新和跳转页面
     
    1 //告知各种客户端不缓存
    2  response.setHeader("pragma", "no-cache");
    3  response.setHeader("cache-control", "no-cache");
    4  response.setDateHeader("expires", 0);  // 系统时间和设置时间差就是缓存时间
     1 // 文件下载
     2 public void doGet(HttpServletRequest request, HttpServletResponse response)
     3         throws ServletException, IOException {
     4     // 通过路径得到一个输入流
     5     String path = this.getServletContext().getRealPath("/WEB-INF/classes/美女.jpg");
     6     FileInputStream file = new FileInputStream(new File(path));
     7     // 创建字节输出流
     8     ServletOutputStream sos = response.getOutputStream();
     9     
    10     // 得到要下载的文件名
    11     String filename = path.substring(path.lastIndexOf("\")+1);
    12     // 设置文件名的编码,将不安全的文件名改为UTF-8
    13     filename = URLEncoder.encode(filename, "UTF-8");
    14     // 告知客户端要下载文件
    15     response.setHeader("content-disposition", "attatchment;filename="+filename);
    16     response.setHeader("content-type", "image/jpeg");  // jpeg简称jpg
    17     // 执行输出操作
    18     int length = 0;
    19     byte[] buf = new byte[1024];
    20     while((length=file.read(buf))!=-1) {
    21         sos.write(buf, 0, length);
    22     }
    23     // 关闭资源
    24     sos.close();
    25     file.close();
    26 }
     1 // 自定义验证码
     2 private void test1(HttpServletResponse response) throws IOException {
     3     int width = 110;
     4     int height = 25;
     5     // 在内存中创建图片对象
     6     BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
     7     
     8     // 创建一个画笔
     9     Graphics g = image.getGraphics();
    10     
    11     // 给图片添加背景色
    12     g.setColor(Color.PINK);
    13     g.fillRect(1, 1, width-2, height-2);  // 填充
    14     
    15     // 给边框一个颜色
    16     g.setColor(Color.RED);
    17     g.drawRect(0, 0, width-1, height-1);
    18     
    19     // 设置文本样式
    20     g.setColor(Color.BLUE);
    21     g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 15));
    22     
    23     // 给图片添加文本
    24     Random r = new Random();
    25     int position = 20;
    26     for(int i=0; i < 4; i++) {
    27         g.drawString(r.nextInt(10)+"", position, 20);
    28         position+=20;
    29     }
    30     
    31     // 添加干扰线,确定左右两个点
    32     for(int i=0; i<9; i++) {
    33         g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
    34     }
    35     
    36     // 将图片对象以流的形式输出到客户端
    37     ImageIO.write(image, "jpg", response.getOutputStream());
    38 }
    // 利用ValidateCode封装好的验证码类实现验证码。网上有很多
    private void test2(HttpServletResponse response) throws IOException {
        
        ValidateCode vc = new ValidateCode();
        vc.write(response.getOutputStream());
    }
     1 <head>
     2 <script type="text/javascript">
     3     function changeCode(){
     4         // 得到图片元素
     5         var img = document.getElementsByTagName("img")[0];
     6         // img.setAttribute("src","/httpServletResponce/demo4");  // XML Dom语法
     7         img.src="/httpServletResponce/demo4?time="+new Date().getTime();  // 浏览器缓存会造成不会改变,两次时间改一下
     8     }
     9 </script>
    10 </head>
    11 <body>
    12     <form action="#" method="post">
    13         用户名:<input type="text" name="userName"/><br>
    14         密码:<input type="password" name="pwd"/><br>
    15         用户名:<input type="text" name="code"/>
    16         <img src="/httpServletResponce/demo4" onclick="changeCode()"/><a href="javascript:changeCode()">看不清换一张</a><br>  <!-- src也会发送请求 -->
    17         <input type="submit" value="提交"/><br>
    18     </form>
    19 
    20 </body>

     

    1 // 刷新
    2 private void test3(HttpServletResponse response) throws IOException {
    3     response.setIntHeader("refresh", 1);  // 1s钟刷新一次
    4     
    5     Random random = new Random();
    6     response.getWriter().write(random.nextInt(100)+"");
    7 }
    1 // 跳转到主页
    2 private void test4(HttpServletResponse response) throws IOException {
    3     // 设置字符集避免乱码
    4     response.setContentType("text/html;charset=UTF-8");
    5     response.getWriter().write("注册成功,3s之后跳转到主页");
    6     // 设置3s跳转到demo6
    7     response.setHeader("refresh", "3;url=/httpServletResponce/demo6");
    8 }

    response注意:

    (1)getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。
    (2) getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法,会抛异常。
    (3) Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
    (4) Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。

     二、HttpServletRequest(客户端-->服务器)

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

    域对象,维护了map,请求一次有效

    1、请求行

    1 Get http://localhost:8080/day09/servlet/req1 ?username=zs http/1.1
    2 getMethod();    //获得请求方式
    3 getRequestURL();  // 返回客户端发出请求时的完整URL。(常用
    4 getRequestURI();  // 返回请求行中的资源名部分。(常用
    5 getContextPath();  // 当前应用的虚拟目录 /day09_01_request (常用
    6 getQueryString() ;  // 返回请求行中的参数部分。

    2、请求消息头

    1  String getHeader(String name)    // 根据头名称得到头信息值
    2  Enumeration getHeaderNames()   // 得到所有头信息name
    3  Enumeration getHeaders(String name)   // 根据头名称得到相同名称头信息值
     1 // 判断使用的是哪个浏览器
     2 public void doGet(HttpServletRequest request, HttpServletResponse response)
     3         throws ServletException, IOException {
     4     String header = request.getHeader("User-Agent");
     5     if(header.toLowerCase().contains("msie")) {
     6         System.out.println("你使用的是IE浏览器");
     7     } else if(header.toLowerCase().contains("firefox")) {
     8         System.out.println("你使用的是火狐浏览器");
     9     } else if(header.toLowerCase().contains("chrome")) {
    10         System.out.println("你使用的是谷歌浏览器");
    11     } else {
    12         System.out.println("你使用的是其他浏览器");
    13     }
    14 }
     1 public void doGet(HttpServletRequest request, HttpServletResponse response)
     2         throws ServletException, IOException {
     3 /*  host:localhost:8080
     4     connection:keep-alive
     5     cache-control:max-age=0
     6     upgrade-insecure-requests:1
     7     user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36
     8     accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*;q=0.8
     9     accept-encoding:gzip, deflate, sdch, br
    10     accept-language:zh-CN,zh;q=0.8,en;q=0.6
    11 */
    12     // 获取所有消息头的name
    13     Enumeration names = request.getHeaderNames();
    14     while(names.hasMoreElements()) {
    15         String e = (String) names.nextElement();
    16         System.out.println(e+":"+request.getHeader(e));
    17     }
    18 }

    3、请求正文(重要

    (1)与获取表单数据相关的方法
    1 <input type="text" name="username" />
    2 getParameter(name)   //根据表单中name属性的名,获取value属性的值方法(常用)
    3 getParameterValues(String name)  // 专业为复选框取取提供的方法(常用
    4 getParameterNames()   // 得到表单提交的所有name的方法
    5 getParameterMap   // 到表单提交的所有值的方法 //做框架用,非常实用(常用
    6 getInputStream   // 以字节流的方式得到所有表单数据
     1 // 要提交的表单
     2 <body>
     3     <form action="/httpServletRequest/demo2" method="post">
     4         用户名:<input type="text" name="userName"/><br/>
     5         密码:<input type="password" name="pwd"/><br/>
     6         性别:<input type="radio" name="sex" value="男" checked="checked"/>
     7             <input type="radio" name="sex" value="女" /><br/>
     8         爱好:<input type="checkbox" name="hobby" value="篮球"/>篮球
     9             <input type="checkbox" name="hobby" value="羽毛球"/>羽毛球
    10             <input type="checkbox" name="hobby" value="乒乓球"/>乒乓球<br/>
    11         所在城市:
    12         <select name="city">
    13             <option>=====请选择======</option>
    14             <option value="bj">北京</option>
    15             <option value="sh">上海</option>
    16             <option value="gz">广州</option>
    17             <option value="sz">深圳</option>
    18         </select>
    19         <br/>
    20         
    21         <input type="submit" value="注册"/>
    22     </form>
    23 </body>
     1 // 以post方式提交表单
     2 public void doGet(HttpServletRequest request, HttpServletResponse response)
     3         throws ServletException, IOException {
     4     // 告诉服务器使用什么编码,浏览器使用的是什么编码传过来的就是什么编码
     5     request.setCharacterEncoding("UTF-8");  // 要是get方法会一直出现乱码,post则不会
     6     
     7     // 获取表单数据
     8     String userName = request.getParameter("userName");  // 根据表单中name属性的名,获取value属性的值方法
     9     String pwd = request.getParameter("pwd");
    10     String sex = request.getParameter("sex");    
    11     String[] hobbys = request.getParameterValues("hobby");
    12     String city = request.getParameter("city");
    13     
    14     System.out.println(userName);
    15     System.out.println(pwd);
    16     System.out.println(sex);
    17     
    18     for (int i = 0; hobbys!=null && i < hobbys.length; i++) {
    19         System.out.println(hobbys[i]+"	");
    20     }
    21     
    22     System.out.println(city);
    23 }
     1 public void doGet(HttpServletRequest request, HttpServletResponse response)
     2         throws ServletException, IOException {
     3     // 告诉服务器使用什么编码,浏览器使用的是什么编码传过来的就是什么编码
     4     request.setCharacterEncoding("UTF-8");  // 要是get方法会一直出现乱码,post则不会
     5     
     6     Enumeration names = request.getParameterNames();  // 获取所有表单name的名字
     7     while(names.hasMoreElements()) {
     8         String name = (String) names.nextElement();  // 表单数据全是String,得到每一个name名
     9         String[] values = request.getParameterValues(name);  // 根据name名得到value值
    10         for (int i = 0; i < values.length && values != null; i++) {
    11             System.out.println(name+"	"+values[i]);
    12         }
    13     }
    14 }
     1 // 获取表单数据
     2 private void test1(HttpServletRequest request) {
     3     
     4     String userName = request.getParameter("userName");  // 根据表单中name属性的名,获取value属性的值方法
     5     String pwd = request.getParameter("pwd");
     6     String sex = request.getParameter("sex");    
     7     String[] hobbys = request.getParameterValues("hobby");
     8     String city = request.getParameter("city");
     9     
    10     System.out.println(userName);
    11     System.out.println(pwd);
    12     System.out.println(sex);
    13     
    14     for (int i = 0; hobbys!=null && i < hobbys.length; i++) {
    15         System.out.println(hobbys[i]+"	");
    16     }
    17     
    18     System.out.println(city);
    19 }
     1 // 输出对应表单name对应的value
     2 private void test2(HttpServletRequest request) {
     3     Enumeration names = request.getParameterNames();  // 获取所有表单name的名字
     4     while(names.hasMoreElements()) {
     5         String name = (String) names.nextElement();  // 表单数据全是String,得到每一个name名
     6         String[] values = request.getParameterValues(name);  // 根据name名得到value值
     7         for (int i = 0; i < values.length && values != null; i++) {
     8             System.out.println(name+"	"+values[i]);
     9         }
    10     }
    11 }
     1 // 封装表单数据,方式一,底层
     2 private void test3(HttpServletRequest request) {
     3     try {
     4         User user = new User();
     5         
     6         Map<String, String[]> map = request.getParameterMap();  // 获取表单数据,键-值
     7         
     8         for (Map.Entry<String, String[]> m : map.entrySet()) {
     9             String name = m.getKey();  // key
    10             String[] value = m.getValue();
    11             
    12             // 创建一个属性描述器,反射内省
    13             PropertyDescriptor pd = new PropertyDescriptor(name, User.class);  // 在实体类中字段要与表单中的name一致,约定优于编码,方便反射
    14             // 得到setter属性,成员变量叫字段,setter等方法叫属性
    15             Method setter = pd.getWriteMethod();
    16             
    17             if(value.length==1) {  // 值只有一项
    18                 setter.invoke(user, value[0]);  // 给一个变量赋值
    19             } else {  // 多项
    20                 // jdk1.5之前value会被拆成多个对象,之后不会
    21                 setter.invoke(user, (Object)value);  // 给复选框赋值
    22             }
    23         }
    24         System.out.println(user);
    25     } catch (Exception e) {
    26         e.printStackTrace();
    27     }
    28 }
    1 // 封装表单数据,方式二,用框架BeanUtils (好用)
    2 private void test4(HttpServletRequest request) {
    3     try {
    4         User u = new User();
    5         BeanUtils.populate(u, request.getParameterMap());
    6     } catch (Exception e) {
    7         e.printStackTrace();
    8     }
    9 }

    entity 实体
    domain 域
    将表单数据封装成一个类传递给数据库插入
    在实体类中字段要与表单中的name名一直,约定优于编码。反射中有使用
    此后成员变量不叫属性,叫字段;getXxx方法才叫属性
    (2)与操作非表单数据相关的方法(request也是一个域对象)
    1 void setAttribute(String name, Object value); (常用2 Object getAttribute(String name); (常用3 Void removeAttribute(String name);
     
     
    (3)与请求转发相关的方法
    1 RequestDispatcher getRequestDispatcher(String path)  //得到请求转发或请求包含的协助对象
    2 forward(ServletRequest request, ServletResponse response) //转发的方法 (常用
    3 include(ServletRequest request, ServletResponse response) //请求包含

     转发(RequestDispatcher)和重定向(sendRedirect)

    (4)与请求编码相关的方法:
    1 //解决post方式编码
    2 request.setCharacterEncoding("UTF-8"); //告诉服务器客户端要使用什么编码,只能处理post请求方式(常用3 //解决get方式编码,少,每个又要写一次
    4 String name = new String(name.getBytes( “iso-8859-1 ” ),” UTF-8 ”);

     

    有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
  • 相关阅读:
    cf------(round)#1 C. Ancient Berland Circus(几何)
    cf------(round)#1 B. Spreadsheets(模拟)
    grep 精确匹配
    解决 service iptables save 报错 please try to use systemctl
    kubernetes 亲和性调度详解
    免费好用的SSH手机客户端
    axios和drf结合的增删改查
    CDH 部署 Hadoop:5.开始安装
    OpenNebula概述
    Python 3.x 引入了函数注释
  • 原文地址:https://www.cnblogs.com/1989guojie/p/6134742.html
Copyright © 2011-2022 走看看