使用Apache HttpClient与HttpURLConnection调用微博接口为何状态码不同?
为什么Apache HttpClient和HttpURLConnection调用微博OAuth2接口返回不同状态码?
我来帮你拆解这个问题的核心原因——你的HttpURLConnection代码里踩了一个容易忽略的坑,导致请求方法被偷偷篡改了。
先看两段代码的关键差异:
- 用Apache HttpClient时,你明确创建了
HttpGet对象,发送的是标准GET请求,所以接口返回200正常响应。 - 但你的HttpURLConnection代码里,设置了
conn2.setDoOutput(true),这才是触发405(方法不允许)错误的元凶!
具体差异解析
HttpURLConnection有个隐性规则:当你调用setDoOutput(true)时,它会默认把请求方法从GET改成POST。哪怕你手动设置了setRequestMethod("GET")也没用——因为GET请求设计上不需要请求体,而setDoOutput(true)意味着你要向服务器写入请求体内容,所以底层会强制切换成POST方法。
而微博的users/show.json接口只接受GET请求,当你的HttpURLConnection实际发送POST请求过去时,服务器自然返回405错误,告诉你“该请求方法不被允许”。
反观Apache HttpClient,它的API设计更直白:HttpGet就是严格的GET请求,不会因为你有没有准备输出流就偷偷改变请求方法,所以能正常拿到200响应。
修复你的HttpURLConnection代码
只需要去掉和输出流相关的代码即可,因为GET请求不需要向服务器写入数据:
String accessToken = "***"; String weiboUid = "***"; try { URL url = new URL("https://api.weibo.com/2/users/show.json?access_token=" + accessToken + "&uid=" + weiboUid); HttpURLConnection conn2 = (HttpURLConnection) url.openConnection(); conn2.setConnectTimeout(10000); conn2.setDoInput(true); // 移除setDoOutput(true)及后续的OutputStream操作 conn2.setRequestMethod("GET"); int responseCode = conn2.getResponseCode(); StringBuilder responseReq = new StringBuilder(); if (responseCode == HttpURLConnection.HTTP_OK) { String line; BufferedReader br = new BufferedReader(new InputStreamReader(conn2.getInputStream())); while ((line = br.readLine()) != null) { responseReq.append(line).append("\n"); } br.close(); } else { throw new Exception("data not exist!"); } String result = responseReq.toString().trim(); JsonParser parser = new JsonParser(); JsonObject jsonObject = parser.parse(result).getAsJsonObject(); String nickname = jsonObject.get("screen_name").getAsString(); System.out.println(nickname); } catch (Exception e) { e.printStackTrace(); } finally { if (conn2 != null) conn2.disconnect(); }
修改后,HttpURLConnection就会发送标准的GET请求,和HttpClient的行为保持一致,就能拿到200的正常响应了。
内容的提问来源于stack exchange,提问作者Star_Man
相关产品推荐
相关产品推荐

