Попытка сделать вызов PATCH для веб-службы приводит к ошибке, java.net.ProtocolException: Invalid HTTP method: PATCH
.
public class PatchTest {
public static void main(String[] args) throws Exception {
HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
httpUrlConnection.setRequestMethod("PATCH");
}
}
Я знаю, что это известная проблема с Httpurlconnection.setrequestmethod
, как обсуждалось в HttpURLConnection Неверный метод HTTP: PATCH . Сначала я попробовал обходной путь X-HTTP-Method-Override
, но служба все еще думает, что я выполняю вызов POST.
public class PatchTest {
public static void main(String[] args) throws Exception {
HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
httpUrlConnection.setRequestProperty("Content-Type", "application/json");
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setRequestProperty("X-HTTP-Method-Override", "PATCH");
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.getResponseCode();
InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getErrorStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.println(bufferedReader.readLine());
}
}
Ответ: {"code":"405","message":"Request method 'POST' not supported"}
Далее я попытался использовать метод отражения и это работало нормально, прежде чем пытаться отправить полезную нагрузку запроса.
public class PatchTest {
public static void main(String[] args) throws Exception {
allowMethods("PATCH");
HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
httpUrlConnection.setRequestProperty("Content-Type", "application/json");
httpUrlConnection.setDoOutput(true);
System.out.println("Response code: " + httpUrlConnection.getResponseCode());
InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getInputStream());
System.out.println(new BufferedReader(inputStreamReader).readLine());
}
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);
}
}
}
Response code: 200
{"somekey":"somevalue"}
Однако при попытке пользователя Writer
установить полезную нагрузку запроса я получаю ошибку 405.
public static void main(String[] args) throws Exception {
allowMethods("PATCH");
HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL("https://api.url.com").openConnection();
httpUrlConnection.setRequestProperty("Content-Type", "application/json");
httpUrlConnection.setDoOutput(true);
Writer writer = new BufferedWriter(new OutputStreamWriter(httpUrlConnection.getOutputStream()));
writer.write("{}");
writer.close();
InputStreamReader inputStreamReader = new InputStreamReader(httpUrlConnection.getInputStream());
System.out.println(new BufferedReader(inputStreamReader).readLine());
}
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 405 for URL: https://api.url.com
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at PatchTest.main(PatchTest.java:32)
Нужно ли внести некоторые изменения в allowMethods
, чтобы избежать ошибки 405, или я что-то упускаю?