使用Basic HttpURLConnection发起POST请求返回401错误但Postman正常如何解决
核心错误原因
- Content-Type配置不匹配:你当前设置的是
multipart/form-data(该格式用于携带文件等多部件内容),但实际提交的是&拼接的表单键值对,对应正确的Content-Type应为application/x-www-form-urlencoded,服务端因格式错误无法正确解析请求体中的凭证参数。 - BASIC认证格式错误:注释中的BASIC认证拼接逻辑不符合规范,标准BASIC Auth要求编码内容为
用户名:密码的格式,而非_username=xxx&_password=xxx的参数串。 - 重复传参冲突:同时在请求头、请求体中都添加了凭证参数,部分服务端校验逻辑会因参数冲突直接拒绝认证。
- HttpsURLConnection默认会自动处理301/302跳转,跳转时不会携带Authorization头,如果你请求的接口存在跳转,也会出现Postman正常但代码失败的情况(Postman默认跳转时会保留认证头)。
修复后的代码示例
obj = new URL(urlRequest); conn = (HttpsURLConnection) obj.openConnection(); conn.setRequestMethod("POST"); // 关闭自动跳转,避免跳转丢失认证头,如果确认接口无跳转可以去掉这行 conn.setInstanceFollowRedirects(false); conn.setRequestProperty("User-Agent", "PostmanRuntime/7.28.3"); conn.setRequestProperty("Accept", "*/*"); conn.setRequestProperty("Connection", "keep-alive"); // 修正Content-Type为表单提交格式 conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); // 如果你用BASIC认证,用这段,不要同时传请求体参数 String username = "xxxxxxxxxx"; String password = "yyyyyyyyyy"; String userCredentials = username + ":" + password; String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes())); conn.setRequestProperty("Authorization", basicAuth); conn.setDoOutput(true); // 如果你用请求体传参,就注释上面的BASIC认证代码,打开下面的参数提交逻辑 /* String urlParameters = "_username=" + URLEncoder.encode(username, "UTF-8") + "&_password=" + URLEncoder.encode(password, "UTF-8"); try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) { wr.writeBytes(urlParameters); wr.flush(); } */ int errCode = conn.getResponseCode(); BufferedReader inSt = new BufferedReader(new InputStreamReader( errCode >= 400 ? conn.getErrorStream() : conn.getInputStream(), "UTF-8")); StringBuilder response = new StringBuilder();
注:优先确认接口的认证规则,是走BASIC Auth头,还是走请求体传参,二选一即可,不要同时传两种凭证。
内容的提问来源于stack exchange,提问作者vbNewbie
相关产品推荐
相关产品推荐

