HttpURLConnection 无效的 HTTP 方法:PATCH

2022-08-31 10:22:17

当我尝试使用非标准的HTTP方法,如PATCH与URLConnection:

    HttpURLConnection conn = (HttpURLConnection) new URL("http://example.com").openConnection();
    conn.setRequestMethod("PATCH");

我得到一个例外:

java.net.ProtocolException: Invalid HTTP method: PATCH
at java.net.HttpURLConnection.setRequestMethod(HttpURLConnection.java:440)

使用更高级别的 API(如 Jersey)会生成相同的错误。是否有发出 PATCH HTTP 请求的解决方法?


答案 1

有很多好的答案,所以这是我的(不是在jdk12中工作):

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;

public class SupportPatch {
    public static void main(String... args) throws IOException {
        allowMethods("PATCH");

        HttpURLConnection conn = (HttpURLConnection) new URL("http://example.com").openConnection();
        conn.setRequestMethod("PATCH");
    }

    private static void allowMethods(String... methods) {
        try {
            Field methodsField = HttpURLConnection.class.getDeclaredField("methods");

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);

            methodsField.setAccessible(true);

            String[] oldMethods = (String[]) methodsField.get(null);
            Set<String> methodsSet = new LinkedHashSet<>(Arrays.asList(oldMethods));
            methodsSet.addAll(Arrays.asList(methods));
            String[] newMethods = methodsSet.toArray(new String[0]);

            methodsField.set(null/*static field*/, newMethods);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new IllegalStateException(e);
        }
    }
}

它还使用反射,但不是入侵每个连接对象,而是破解内部检查中使用的HttpURLConnection#methods静态字段。


答案 2

是的,有解决此问题的方法。用

X-HTTP-方法-覆盖

.此标头可以在 POST 请求中用于“伪造”其他 HTTP 方法。只需将 X-HTTP-方法-覆盖标头的值设置为要实际执行的 HTTP 方法即可。因此,请使用以下代码。

conn.setRequestProperty("X-HTTP-Method-Override", "PATCH");
conn.setRequestMethod("POST");

推荐