HttpURLConnection 无效的 HTTP 方法:PATCH

新手上路,请多包涵

当我尝试将非标准 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)

使用像 Jersey 这样的更高级别的 API 会产生相同的错误。是否有发出 PATCH HTTP 请求的解决方法?

原文由 kavai77 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2k
2 个回答

是的,有解决方法。利用

X-HTTP-方法覆盖

.此标头可用于 POST 请求以“伪造”其他 HTTP 方法。只需将 X-HTTP-Method-Override 标头的值设置为您要实际执行的 HTTP 方法。所以使用下面的代码。

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

原文由 sagar 发布,翻译遵循 CC BY-SA 3.0 许可协议

有很多好的答案,所以这是我的(不适用于 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 静态字段。

原文由 okutane 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题