diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java
index ad62d54b4..2ed5e237e 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java
@@ -32,6 +32,7 @@ import org.dromara.hutool.http.client.cookie.GlobalCookieManager;
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
import org.dromara.hutool.http.meta.HeaderName;
import org.dromara.hutool.http.meta.HttpStatus;
+import org.dromara.hutool.http.meta.Method;
import java.io.IOException;
import java.net.HttpURLConnection;
@@ -135,13 +136,13 @@ public class JdkClientEngine extends AbstractClientEngine {
// 覆盖默认Header
.header(message.headers(), true);
- if(!message.method().isIgnoreBody()){
+ if (!message.method().isIgnoreBody()) {
// 在允许发送body的情况下,如果用户自定义了Content-Length,则使用用户定义的值
final long contentLength = message.contentLength();
- if(contentLength > 0){
+ if (contentLength > 0) {
// 固定请求长度
conn.setFixedLengthStreamingMode(contentLength);
- } else if(message.isChunked()){
+ } else if (message.isChunked()) {
conn.setChunkedStreamingMode(4096);
}
}
@@ -176,6 +177,15 @@ public class JdkClientEngine extends AbstractClientEngine {
if (code != HttpURLConnection.HTTP_OK) {
if (HttpStatus.isRedirected(code)) {
message.url(getLocationUrl(message.handledUrl(), conn.header(HeaderName.LOCATION)));
+
+ // https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7
+ // https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections
+ // 307方法和消息主体都不发生变化。
+ if (HttpStatus.HTTP_TEMP_REDIRECT != code) {
+ // 重定向默认使用GET
+ message.method(Method.GET);
+ }
+
if (conn.redirectCount < message.maxRedirects()) {
conn.redirectCount++;
return send(message, isAsync);
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/meta/HttpStatus.java b/hutool-http/src/main/java/org/dromara/hutool/http/meta/HttpStatus.java
index 62b3e12f0..9171b5398 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/meta/HttpStatus.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/meta/HttpStatus.java
@@ -21,7 +21,6 @@ package org.dromara.hutool.http.meta;
*
* @author Looly, Ningqingsheng
* @see java.net.HttpURLConnection
- *
*/
public interface HttpStatus {
@@ -112,12 +111,16 @@ public interface HttpStatus {
int HTTP_MOVED_PERM = 301;
/**
- * HTTP Status-Code 302: Temporary Redirect.
+ * HTTP Status-Code 302: Temporary Redirect.
+ * 由于不可预见的原因该页面暂不可用。
+ * GET 方法不会发生变更。其他方法有可能会变更为 GET 方法。
*/
int HTTP_MOVED_TEMP = 302;
/**
- * HTTP Status-Code 303: See Other.
+ * HTTP Status-Code 303: See Other.
+ * 用于 PUT 或 POST 请求完成之后重定向,来防止由于页面刷新导致的操作的重复触发。
+ * GET 方法不会发生变更,其他方法会变更为 GET 方法(消息主体丢失)。
*/
int HTTP_SEE_OTHER = 303;
@@ -133,7 +136,9 @@ public interface HttpStatus {
/**
* HTTP 1.1 Status-Code 307: Temporary Redirect.
- * 见:RFC-7231
+ * 由于不可预见的原因该页面暂不可用。当站点支持非 GET 方法的链接或操作的时候,该状态码优于 302 状态码。
+ * 方法和消息主体都不发生变化。
+ * 见:https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7
*/
int HTTP_TEMP_REDIRECT = 307;
@@ -349,17 +354,18 @@ public interface HttpStatus {
/**
* 是否为重定向状态码
+ *
* @param responseCode 被检查的状态码
* @return 是否为重定向状态码
* @since 5.6.3
*/
- static boolean isRedirected(final int responseCode){
+ static boolean isRedirected(final int responseCode) {
return responseCode == HTTP_MOVED_PERM
- || responseCode == HTTP_MOVED_TEMP
- || responseCode == HTTP_SEE_OTHER
- // issue#1504@Github,307和308是RFC 7538中http 1.1定义的规范
- || responseCode == HTTP_TEMP_REDIRECT
- || responseCode == HTTP_PERMANENT_REDIRECT;
+ || responseCode == HTTP_MOVED_TEMP
+ || responseCode == HTTP_SEE_OTHER
+ // issue#1504@Github,307和308是RFC 7538中http 1.1定义的规范
+ || responseCode == HTTP_TEMP_REDIRECT
+ || responseCode == HTTP_PERMANENT_REDIRECT;
}
}