JavaWeb基础---response、request

目录

1. request

    1.1 request格式

    1.2 request的功能

   1.2.1 通过request获取请求协议中的内容

      (1) 获取请求行           

      (2) 获取请求头部   

             具体案例: 防盗链

            具体案例: 请求转发和请求包含

       (3)获取请求数据

2. response 

       2.1 rsponse 格式 

       2.2 response的功能(方法)

         2.2.1 方法

              (1)状态行

                    具体案例: 重定向

              (2) 响应头

                    具体案例:定时刷新 

              (3) 响应体(数据)

                    具体案例:上传图片到服务器

3. 补充:URL编码


 

在讲述request和response之前,得了解一下服务器是如何响应请求

             图片来源于csdn的Feathers  https://blog.csdn.net/xf616510229/article/details/53483472

可以看出,request是封装客户端发给服务端的请求数据的载体,response是封装服务端返回给客户端的数据的载体。

1. request

    1.1 request格式

        主要由4个部分组成:请求行、请求头部、空行、请求数据

        

     例子:   

GET http://api.share.baidu.com/v.gif?l=http%3A%2F%2Fblog.51cto.com%2F10981246%2F2062137 HTTP/1.1
Host: api.share.baidu.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://blog.51cto.com/10981246/2062137
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: BAIDUID=914AC858F2D0CFE9B72D6275F9216C93:FG=1; BIDUPSID=914AC858F2D0CFE9B72D6275F9216C93; PSTM=1543733306; BDUSS=FJOdmVDUlpZeWNRN0l-YzZZbkMwc1YtWnJTR1FxbURDRjVSMmFYWjhScXV1RkpjQVFBQUFBJCQAAAAAAAAAAAEAAABDOtLnc3ZsbGVuQmFpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK4rK1yuKytcZ; pgv_pvi=963150848; cflag=13%3A3; BDRCVFR[mkUqnUt8juD]=mk3SLVN4HKm; delPer=0; PSINO=1; H_PS_PSSID=1422_21121_28132_28266; pgv_si=s2632059904; ZD_ENTRY=google

   请求行: 第一行就是请求行GET代表请求的类型(下附有请求的类型大全),中间那一串url是要访问的网址,最后的HTTP/1.1 是协议版本。

   请求头:从第二行到Cookie那一行都是请求头。主要是存放一些字段,标明一些信息,常用的字段有:Accept :表示目的端能接受的数据类型;User-Agent:中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等;Host:目的端的主机号;Connection :处理完这次请求后是继续连接还是断开;Cookie:就是传个cookie过去;Referer:HTTP来源地址用来表示从哪儿链接到目前的网页,采用的格式是URL,作用是防盗链,下面会介绍其应用。更多字段可以查看简书的用户留七七的文章:https://www.jianshu.com/p/6e86903d74f7

  空行:请求头后必须有个空行

  请求数据:本例中没有请求数据。一般很少在get中附带请求数据。一般都是传个cookie

 

    1.2 request的功能

       ps:本文中所讲的方法都是HttpServletRequest或者ServletRquest中的方法

       1.2.1 通过request获取请求协议中的内容

      (1) 获取请求行           

                   String getMethod();     //获取请求类型,比如GET/HEAD

                   String getParameter(String name)    // 指定名称获取请求url(在post里就是表单里的参数)里面的参数

                   String getScheme();           //获取请求协议的类型 比如 http https ftp

                   String getProtocol();          //获取协议版本号  比如 http/1.1

 

     

                             本图片来自于传智播客的视频笔记

        ps: getQueryString()换成getParameter();

  

      (2) 获取请求头部   

               String getHeader(String name):获取指定名称的请求头;

               Enumeration getHeaderNames():获取所有请求头名称;

               int getIntHeader(String name):获取值为int类型的请求头

 

             具体案例: 防盗链

     把别人的链接放到自己的网站,还不注明,这就是盗链,防盗链很简单,利用请求行里的Referer字段,提取这个字段后做一些判断就好了。

            核心代码:     String referer = requeest.getHeader("Referer");

 

            具体案例: 请求转发和请求包含

    有时候我们会遇到一个servlet解决不了的请求,可以使用重定向(在下面的response会讲到),但是重定向对客户来说不完美,而且麻烦,在客户端上应该呈现的就是直接的结果。而请求转发和请求包含可以很好地解决这个问题,它能让一个请求调用多个servlet。

         

              格式: 

                请求转发 

                            RequestDispatcher rd = request.getRequestDispatcher("/BServlet");     //获取“调度器”,其中参数为BServlet绑定的URL,即BServlet的<url-pattern>值。

                             rd.forward(request, response) ;     //调用“调度器”的转发方法,该方法等同与告诉服务器,去调用BServlet的service()方法一样。

 

                 请求包含                 

                          RequestDispatcher rd = request.getRequestDispatcher("/BServlet");

                          rd.include(request, response);        //请求包含

 

         区别:请求转发留头不留体,而请求包含留头又留体。这里的头指得是响应头和响应体,响应头(类似请求头)里包含着那些指示字段,比如下面这种,响应体(类似于请求本文)就是返回的数据。这两个都是response里面的知识。

 

       (3)获取请求数据

            get方法没有获取请求数据的,只有getParameter()获取到url  ?后面的参数 
         

              

 

2. response 

       2.1 rsponse 格式 

            主要由四个部分组成:状态行,消息报头,空行和响应正文

        

        例子:

POST http://get.sogou.com/q HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: get.sogou.com
Content-Length: 591
Pragma: no-cache
Cookie: YYID=04ADC58062834FD9AECFFC824C8AB3B2; QQ_Sogou_Openid=A24C952FFCE6FEB736204D4E6E150CB2,1547716436; IMESKIN=1:; IMEVER=9.2.0.2770; SUV=00D4504E3DB7CF9D5C0379C0D330B543; IMESKINID=2:; IPLOC=CN4201

k=EScvOFxK08VDA4Pd0rwI4UtXB1bcDYJKaHFBS3FQs7ZKcPgX4ri6QKb3ImAkjNhHFLcZNrrmHPWV9Sd1DxNYzpeLrnrS1qUwzYzbsJFDg4f2BKrKxx64YR3BwI+mCwjg1EyvJswnU/YgjZZsnmPJu0gJYY1ebUgPNgZXe8KGJxQ=&v=QJThaB/YVj7+0NHP3FYTMiOAo166zruSkYKv0H5+JgVn0xZxhV9Pv4Ec7NZJgWP0UUrmeBukf8IKy05U5OPoe2bFUUST8REWzR9BLZi4IRkLaZjQ+TUzaBAv3GuP4VOqHYmuDty0CkVruRm+uBxBh0aWVYaKJytzd0gJ4EVCX9E=&u=wh0DTIE3w+9fbAxvO6WMjgpHTU0Tlyyc5Ce5lS+ch/3MX9awRPSx8Jyn4xhhEstu&g=qbkOUBQHmByQMu9VOUF0/1WhEr+h379/7Xc6zTBd5vxWjxUgjOVCNJQmKAzYu54PUhhbJrRMWc4lVRfGyouTPZ0MODTxrkfrAl/U6fMkxa5V4vrr72ATYximhJ2ftiub0RlF5yWqvAjbLLvYRCDdrJ3A+pQQ86gdLehqQuGjeGI=

 

        状态行:由协议版本号、状态码、状态消息组成。状态码是一个重点,我们经常会通过状态码来判断这次请求的结果,

1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误

      记住一些常见的就好了,比如200(成功),302(重定向),400(请求的语法错误),404(未找到页面),500(服务器内部错误),其他的碰到的再查。

       响应头:从第二行到第五行都是响应头的部分,与request的请求头类似,也会包含了很多指示字段,比如Content-Type:返回的MIME类型与编码,告诉服务端它发送的数据属于什么文件类型;Host:目的端的主机号;Pragma:设置特殊实现字段,可能会对请求响应链有多种影响  ;Content-Encoding:设置数据的编码方式,推荐utf-8;Refresh:重定向或者新资源创建时使用,在页面的头部有个扩展可以实现相似的功能,并且大部分浏览器都支持。更多字段可以查看简书的用户留七七的文章:https://www.jianshu.com/p/6e86903d74f7

       空行:响应头和响应体之间必须有空行

       响应体:响应体就是数据,也就是上面例子中的第八行,k=ESc......

 

       2.2 response的功能(方法)

         2.2.1 方法

              (1)状态行

                         void setStatus(int src);      // 发送成功的状态码

                        void  setError(int src);         //发送错误的状态码

                         void setError(int src, String msg);  //发送错误的状态码,还可以附带一个信息

                       

                    具体案例: 重定向

        当你访问一个url网址时,它会给你自动转到另一个url网址,这就是重定向。重定向的作用很大,因为现在大多数用户使用的都是域名来访问网站,不会有人记住你的i地址,当你同一个域名有多个网站时,你就可以使用重定向让用户直接跳转到你的主网站,而且使用302还有可能会遇到网址劫持。对于什么是网络劫持跟301、302的区别可以参考ITOYO的用户wenrunchang123的文章:https://wenrunchang123.iteye.com/blog/1322411。下面是百度百科里面关于重定向的几个用途。

                 

  •                 写法: 一共有两步。第一步是设置响应码,第二步是设置location头,指定第二次请求的url。对于响应码,如果你是想要永久跳转,那就选择301,如果你只是暂时性的(24小时到48小时内),可以选择302、307,307是302的改良版,但是现在更多的还是使用302,至于为什么我就不列出来了,你可以参考博客园的用户烛秋的博客:http://www.cnblogs.com/cswuyg/p/3871976.html 。下面以302举例。

                       response.setStatus(302);

                       response.setHeader("Location","http://www.svllen.com");   

                      //便捷写法

                       response.setRedirect("http://www.svllen.com");

 

  •                   重定向和转发请求的区别:重定向是客户端行为,客户端需要经过两次请求,url是变化的,在客户端的地址栏中可以体现出来(但是不会在浏览器界面上显示说重定向了,给你转到某某网站之类)。转发是服务端行为,只需要一次请求,URL是不变的,在一次请求中使用多个servlet。更多详情可以参考简书的用户 含辞未吐若幽兰的文章:https://www.jianshu.com/p/cb1813792a91      

              (2) 响应头

                         void addHeader(String name, String value);   //往响应头里添加一个字段,如果有了就在现有value不变情况下追加这个value

                         void setHeader();     //往响应头里添加一个子段,如果有了就覆盖原来的value;

                    ps:还有setIntHeader(string name,int value),setDateHeader(String name,long date),addDateHeader(String name,long date)。都是一样的作用,只不过是添加的值得类型不一样而已,有int,String ,date类型。

                    具体案例:定时刷新 

                               平时上网应该会遇到这种情况,注册或者支付成功会显示 ***成功,5秒后自动跳转到***页面。定时刷新起的  就是这个作用。

             

                                                                    图片来源于黑马视频

          /day10_1/EServlet,day_10_1是你的项目名,EServlet是你请求的servlet的url路径,即<url-pattern>里面的值。

         ps:上面的代码输出会乱码,解决方法直接加一句:resp.setContentType("text/html;charset=utf-8");  

 

              (3) 响应体(数据)

                        可以发送的数据有两种,一种是字节流,一种是字符流,同一个请求这两种流只能用一种。

                             字节流: ServletOutputStream out = response.getOutputStream();

                                      一般用于音视频,图片的等类型的数据。

                              字符流: PrintWriter out = response.getWriter();

                                       一般用于字符串,json类型。          

                    具体案例:上传图片到服务器

                           详情请参考csdn的周文凯:https://blog.csdn.net/xuehuayous/article/details/51453077#commentBox  (我不会告诉你我是因为懒才直接贴别人的博客的.......),具体的服务端代码我也上传到csdn了:https://download.csdn.net/download/vibugs/10912808

 

3. 补充

     3.1URL编码

         在日常的工作中,你会经常遇到URL里面带中文字符或者是一些特殊的字符的情况,有些浏览器会给你转码转换好,但是有些并不会转成合适的,如果恰巧遇到不合适的那你服务器接收到的请求很有可能就失败了。面对这些混乱的编码方式,就需要我们自己手动进行URL编码。不同语言的写法不一样,我这里介绍java、js的URL编码方式。

  String name = "张三";

//java的URL编码方式

String str = URLEncoder.encode(name,"utf-8");

//JS的URL编码方式

 var str = encodeURLComponent(name);     //js的第一种方式,默认UTF-8.对整个name进行编码

var str = encodeURL(name);           //     js的第二种编码方式,默认UTF-8,对个别需要编码的符号进行编码  

---------------------------------------------------------------------------------------------------------------------

至于解码,你把这些方法里面的encode都替换成decode就好了。

 

     3.2 路径

     

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值