一、 参数传递
由于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 板车普遍是在后座上装货物(装的货物量大)