retrofit2 GET请求能通过RequestBody进行参数传递吗

一、 参数传递

由于GET请求参数是通过url进行传递的,即参数通过在url后追加的方式进行传递。而实现HTTP协议的各种软件对GET参数长度的限制是不同的,就像有的浏览器要求GET 请求URL长度不能超过1024字符(这里的1024是随意假设的一个数字)。也就是说

1. 如果GET请求URL长度超过1024字符 (假如某浏览器限制的URL长度就是1024字符),那么在客户端浏览器这里就被截取了——即超过的参数就不能发送到服务端。

2. 如果浏览器对GET请求参数没有做限制,也没用做截取等操作,有多少数据就发送多少数据到服务端,那这个时候服务端会如何处理?服务端会辨别这是GET请求过来的,然后判断参数长度是否超过1024字符,超过的话就进行截取,或者直接报错吗?会有这种操作吗? —— 这个要看每个服务端的处理,不能一概而论,不同的服务端处理不一样

 

 

图片来源参考: https://www.cnblogs.com/tweet/p/7574662.html 

 

二、retrofix2  GET请求如果通过RequestBody进行参数传递,会怎么处理?

—— 直接报错 

目前我测试的结果是 这样的,也就是说这款 http client工具 对GET请求中RequestBody参数传递,会直接报错,不让你通过这种方式进行参数传递。如下:

跟踪下源码:

发现如下,在构建GET请求 method对象的时候,进行了校验

 public ServiceMethod build() {
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();
      if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError("'"
            + Utils.getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
      }
      responseConverter = createResponseConverter();

      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

      if (httpMethod == null) {
        throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      }

      if (!hasBody) {
        if (isMultipart) {
          throw methodError(
              "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
          throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
        }
      }

      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) {
        Type parameterType = parameterTypes[p];
        if (Utils.hasUnresolvableType(parameterType)) {
          throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
              parameterType);
        }

        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        if (parameterAnnotations == null) {
          throw parameterError(p, "No Retrofit annotation found.");
        }

        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }

      if (relativeUrl == null && !gotUrl) {
        throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
      }

        // 这里报错,GET 请求就会 异常出现在这里
      if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError("Non-body HTTP method cannot contain @Body.");
      }
      if (isFormEncoded && !gotField) {
        throw methodError("Form-encoded method must contain at least one @Field.");
      }
      if (isMultipart && !gotPart) {
        throw methodError("Multipart method must contain at least one @Part.");
      }

      return new ServiceMethod<>(this);
    }

 

三、GET请求 扩展

上面retrofit工具,GET请求是不支持通过RequestBody进行参数传递的,但是如果我自定义GET请求,通过socket进行服务端连接,发送数据,并通过RequestBody携带参数,进行传递:

1. 能发送到服务端吗 ?

2. 服务端能接收到该RequestBody中的参数吗?

 

答案是什么?

1.  GET  RequstBody参数能发送到服务端

HTTP协议并没有规定GET请求不能通过RequestBody 进行参数传递,协议层面是没有规定,也就是说实现上是可以这么做的,但是大家普遍都不会这么做,因为根据约定,如果要通过RequestBody进行参数传递,完全可以使用POST方法,否则定义POST方法有什么用呢,所以普遍上浏览器都不支持GET请求传递RequestBody参数

2. 服务端能接收到GET 请求中RequestBody参数,但是至于能不能帮你解析RequestBody参数(反序列化成对象),就看不同服务端的处理了,有的能,有的不能。

举个例子,农村,要去集市上卖东西,你可以用自行车装货物,也可以用板车装货物。

2.1 自行车装货物普遍是在车前的篮筐中装货物(装的货物量少),但是你也可以在自行车的后座上面装货物,但是不能保证到了集市上会卸货。

2.2 板车普遍是在后座上装货物(装的货物量大)

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值