You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8调用PATCH请求报Invalid HTTP method错误,求解决方案

问题描述

尝试在Java 1.8.0_171环境下,向ClientApp的REST API发送PATCH请求时,触发java.net.ProtocolException: Invalid HTTP method: PATCH错误。曾尝试使用X-HTTP-Method-Override请求头但未成功,且受组织限制无法升级Java版本。

代码示例

package com.in.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class ConnectToCorbion {
    
    public static void main(String[] args) throws IOException {
        
         String PATCH_PARAMS = "[ { \"op\": \"replace\", \"path\": \"/optionalFields1/text1\", \"value\": \"SR234568\", \"from\" : \"string\" }]";
        String my_url = "https://uat.clientapp.com/api/ChangeActivities";
        byte[] patchData       = PATCH_PARAMS.getBytes( StandardCharsets.UTF_8 );
        URL obj = null;
        
            System.out.println("BEFORE");
            obj = new URL(my_url);
            System.out.println("AFTER");
    
        
        String username = "username";
        String password = "password";

        HttpURLConnection patchConnection = null;
    
            System.out.println("BEFORE openConnection");
            try {
                patchConnection = (HttpURLConnection) obj.openConnection();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("AFTER openConnection");
            patchConnection.setRequestMethod("PATCH");
        //patchConnection.setRequestProperty("X-HTTP-Method-Override", "PATCH");
        
        patchConnection.setRequestProperty("Accept", "application/json");
        patchConnection.setRequestProperty("Content-Type", "application/json-patch+json");
        patchConnection.setRequestProperty("messageType", "application/json-patch+json");

        // Basic Auth for Java 8+
        patchConnection.setRequestProperty("Authorization",
            "Basic " + Base64.getEncoder().encodeToString(
              (username + ":" + password).getBytes()
            )
        );

        patchConnection.setDoOutput(true);
        OutputStream os = null;
        
            System.out.println("BEFORE getOutputStream");
            os = patchConnection.getOutputStream();
            System.out.println("AFTER getOutputStream");
        
            os.write(PATCH_PARAMS.getBytes());
            os.flush();
            os.close();
        
        int responseCode = patchConnection.getResponseCode();
        System.out.println("Response Code :  " + responseCode);

        if (responseCode == HttpURLConnection.HTTP_CREATED) { //success
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    patchConnection.getInputStream()));
            
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            System.out.println(response.toString());
        } else {
            System.out.println("PATCH NOT WORKING");
        }
        
    }

}

错误日志

BEFORE
AFTER
BEFORE openConnection
AFTER openConnection
Exception in thread "main" java.net.ProtocolException: Invalid HTTP method: PATCH
    at java.net.HttpURLConnection.setRequestMethod(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.setRequestMethod(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestMethod(Unknown Source)
    at com.in.Test.ConnectToCorbion.main(ConnectToCorbion.java:44)

解决方案

问题根源

Java 8的HttpURLConnection默认仅支持GET、POST、HEAD、OPTIONS、PUT、DELETE这些HTTP方法,直接调用setRequestMethod("PATCH")会触发方法校验失败,抛出ProtocolException。

方案1:反射绕过方法限制

通过反射修改HttpURLConnection内部的method字段,绕过内置的方法校验逻辑,适用于Java 8u171版本:

// 替换原代码中的patchConnection.setRequestMethod("PATCH");
try {
    java.lang.reflect.Field methodField = HttpURLConnection.class.getDeclaredField("method");
    methodField.setAccessible(true);
    methodField.set(patchConnection, "PATCH");
} catch (NoSuchFieldException | IllegalAccessException e) {
    e.printStackTrace();
}

注意:该方法依赖JDK内部实现,若后续小版本更新修改了字段名或访问权限可能失效,但对于当前指定版本稳定可用。

方案2:正确使用X-HTTP-Method-Override请求头

若目标API服务器支持X-HTTP-Method-Override机制,需发送POST请求并添加该头来模拟PATCH请求,同时保持请求体和Content-Type不变:

// 替换原setRequestMethod("PATCH"),改用POST
patchConnection.setRequestMethod("POST");
// 添加方法覆盖头
patchConnection.setRequestProperty("X-HTTP-Method-Override", "PATCH");

注意:必须确认目标服务器已配置支持该请求头,否则无法触发PATCH逻辑。

方案3:使用兼容Java 8的第三方HTTP客户端库

若允许引入第三方依赖,推荐使用Apache HttpClient 4.x或OkHttp 3.x,它们原生支持PATCH方法且完全兼容Java 8:

Apache HttpClient示例

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

// 初始化客户端
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPatch patch = new HttpPatch(my_url);

// 设置请求头
patch.setHeader("Accept", "application/json");
patch.setHeader("Content-Type", "application/json-patch+json");
String auth = Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
patch.setHeader("Authorization", "Basic " + auth);

// 设置请求体
StringEntity entity = new StringEntity(PATCH_PARAMS, StandardCharsets.UTF_8);
patch.setEntity(entity);

// 执行请求并处理响应
CloseableHttpResponse response = client.execute(patch);
int responseCode = response.getStatusLine().getStatusCode();
// 此处添加响应解析逻辑
client.close();
response.close();

OkHttp示例

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

// 初始化客户端
OkHttpClient client = new OkHttpClient();

// 构建请求体和请求
RequestBody body = RequestBody.create(PATCH_PARAMS, MediaType.parse("application/json-patch+json"));
String auth = Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
Request request = new Request.Builder()
        .url(my_url)
        .patch(body)
        .addHeader("Accept", "application/json")
        .addHeader("Authorization", "Basic " + auth)
        .build();

// 执行请求并处理响应
Response response = client.newCall(request).execute();
int responseCode = response.code();
// 此处添加响应解析逻辑
response.close();

内容的提问来源于stack exchange,提问作者Justin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 23:24:54