Java中HttpURLConnection getResponseCode返回null及空指针问题求助
问题描述
使用Java的HttpURLConnection发送带Basic Auth认证的GET请求获取JSON响应,相同请求结构在其他应用中正常运行,但本次请求出现与getResponseCode相关的NullPointerException,相关代码及报错堆栈如下:
核心代码
String accessToken = ""; String token = ""; // Create Basic Auth String auth = "riot"+":"+lockFilePass; byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8)); String authHeaderValue = "Basic "+new String(encodedAuth); String responseToSend = ""; try { String apiUrl = "https://127.0.0.1:"+port+"/entitlements/v1/token"; URL url = new URL(apiUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setDoOutput(true); // 可疑点 connection.setAllowUserInteraction(false); connection.setRequestProperty("Authorization", authHeaderValue); connection.setRequestProperty("User-Agent", "Mozilla/5.0"); System.out.println("yes1"); System.out.println(connection.getURL()); // Get the response code int responseCode = connection.getResponseCode(); String responseMessage = connection.getResponseMessage(); System.out.println("Response Message: "+responseMessage); accessToken = connection.getHeaderField("accessToken"); token = connection.getHeaderField("token"); System.out.println("ACCESS: "+accessToken); System.out.println("JUSTTOKEN: "+token); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); try { String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } System.out.println("Response: " + response.toString()); if (responseCode!=500) responseToSend = response.toString(); }catch (Exception e){ e.printStackTrace(); } reader.close(); connection.disconnect(); System.out.println("1: "+responseMessage+" 2: "+responseToSend); List<String> responseList = new ArrayList<>(); responseList.add(responseToSend); responseList.add(accessToken); responseList.add(token); return responseList; } catch (Exception e) { return null; }
报错堆栈
java.lang.NullPointerException at com.daffy.BotHandler.onMessageReceived(BotHandler.java:108) at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:446) at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96) at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:88) at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:70) at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:177) at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:138) at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:39) at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:1015) at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:901) at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:879) at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:1054) at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385) at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276) at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996) at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755) at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108) at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64) at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45)
可能的原因分析
1. GET请求错误启用输出流
代码中设置了connection.setDoOutput(true);,但GET请求不需要向服务器写入数据,该设置会强制HttpURLConnection将请求方法转为POST(即便代码显式设置为GET),导致请求结构与预期不符,服务器无法返回正常响应,进而引发后续获取响应码或响应头时出现异常。
解决方式:删除connection.setDoOutput(true);(默认值为false,无需手动设置)。
2. HTTPS自签名证书未被信任
请求目标是https://127.0.0.1,大概率使用自签名证书。当前JVM环境未配置信任该证书,导致连接建立失败,无法获取有效响应,后续操作触发空指针。
解决方式:将目标证书导入JVM信任库,或在代码中添加自定义证书信任逻辑(生产环境慎用后者)。
3. 基础变量未正确初始化
代码中lockFilePass和port变量的初始化逻辑未展示,若这两个变量为null,拼接出的apiUrl会是无效地址(如https://127.0.0.1:null/entitlements/v1/token),导致URL构造失败或连接无法建立,最终引发空指针。
解决方式:检查lockFilePass和port的赋值逻辑,确保apiUrl是合法的HTTPS地址。
4. 未设置超时导致连接无响应
代码未设置连接超时和读取超时,若服务器无响应或网络超时,HttpURLConnection无法及时获取响应,可能导致响应码或响应头为null,后续操作触发空指针。
解决方式:添加超时设置:
connection.setConnectTimeout(5000); // 5秒连接超时 connection.setReadTimeout(5000); // 5秒读取超时
5. 响应头字段缺失触发后续NPE
代码直接从响应头中获取accessToken和token,若服务器响应未包含这两个字段,这两个变量会为null。报错堆栈显示NPE发生在BotHandler.java:108,大概率是后续代码直接使用了这两个null值(如调用字符串方法)。
解决方式:使用前对accessToken和token判空,或赋予默认空字符串:
accessToken = connection.getHeaderField("accessToken") != null ? connection.getHeaderField("accessToken") : ""; token = connection.getHeaderField("token") != null ? connection.getHeaderField("token") : "";
6. 异常捕获逻辑吞掉关键错误
代码的catch块直接返回null,未打印或记录异常信息,导致连接过程中出现的错误(如IOException)被隐藏,无法定位真实问题。
解决方式:在catch块中添加异常打印逻辑:
catch (Exception e) { e.printStackTrace(); // 或写入日志 return null; }
内容的提问来源于stack exchange,提问作者Dafi

