HttpURLConnection Invalid HTTP method: PATCH
Yes there is workaround for this. Use
X-HTTP-Method-Override
. This header can be used in a POST request to “fake” other HTTP methods. Simply set the value of the X-HTTP-Method-Override header to the HTTP method you would like to actually perform.So use following code.
conn.setRequestProperty("X-HTTP-Method-Override", "PATCH");conn.setRequestMethod("POST");
There are a lot of good answers, so here is mine (not work in 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); } }}
It also uses reflection, but instead of hacking into every connection object we're hacking HttpURLConnection#methods static field which is used in the checks internally.
There is a Won't Fix bug in OpenJDK for this: https://bugs.openjdk.java.net/browse/JDK-7016595
However, with Apache Http-Components Client 4.2+ this is possible. It has a custom networking implementation, thus using all standard HTTP methods like PATCH is possible. It even has a HttpPatch class supporting the patch method.
CloseableHttpClient httpClient = HttpClients.createDefault();HttpPatch httpPatch = new HttpPatch(new URI("http://example.com"));CloseableHttpResponse response = httpClient.execute(httpPatch);
Maven Coordinates:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.2+</version></dependency>