如何在Flutter真机中调用本地Spring Boot API?连接失败排查
问题:Flutter真机无法连接本地Spring Boot API(连接拒绝)
我开发了Spring Boot Web应用,提供给Flutter移动端调用的API,Spring Boot运行在本地,示例地址为http://127.0.0.1:8086/assessmentportal/authenticate/verifyemail/reset-password-otp。尝试在Flutter真机上调用API时失败,已确保手机和电脑处于同一网络(笔记本以太网+热点Wi-Fi),但问题未解决。
Flutter端API调用代码
class API { final sendEmailOTPUrl = "http://127.0.0.1:8086/assessmentportal/authenticate/verifyemail/sendotp"; final verifyEmailOTPUrl = "http://127.0.0.1:8086/assessmentportal/authenticate/verifyemail/verify-otp"; final Dio _dio = Dio(); Future<Map<String, String>> sendEmailVerificationOTP( {required String? email}) async { Map<String, String> data = {"email": "$email"}; Response response = await _dio.post(sendEmailOTPUrl, data: data); log("Response obtained: $response"); Map<String, String> result = jsonDecode(response.data); return result; } Future<Map<String, String>> verifyEmailVerificationOTP( {required String? email, required String? otp}) async { Map<String, dynamic> data = {"email": email, "otp": int.parse(otp!)}; Response response = await _dio.post(verifyEmailOTPUrl, data: data); Map<String, String> result = jsonDecode(response.data); return result; } }
运行错误日志
E/flutter ( 3127): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioError [DioErrorType.other]: SocketException: Connection refused (OS Error: Connection refused, errno = 111), address = 127.0.0.1, port = 34222 E/flutter ( 3127): Source stack: E/flutter ( 3127): #0 DioMixin.fetch (package:dio/src/dio_mixin.dart:488:35) E/flutter ( 3127): #1 DioMixin.request (package:dio/src/dio_mixin.dart:483:12) E/flutter ( 3127): #2 DioMixin.post (package:dio/src/dio_mixin.dart:97:12) E/flutter ( 3127): #3 API.sendEmailVerificationOTP (package:assessmentportal/NewtworkUtil/API.dart:16:36) E/flutter ( 3127): #4 _RegisterScreenState.build.<anonymous closure>.<anonymous closure> (package:assessmentportal/Register%20and%20Login/RegisterScren.dart:80:45) E/flutter ( 3127): #5 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21) E/flutter ( 3127): #6 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24) E/flutter ( 3127): #7 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11) E/flutter ( 3127): #8 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5) E/flutter ( 3127): #9 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7) E/flutter ( 3127): #10 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:615:9) E/flutter ( 3127): #11 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12) E/flutter ( 3127): #12 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9) E/flutter ( 3127): #13 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13) E/flutter ( 3127): #14 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18) E/flutter ( 3127): #15 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7) E/flutter ( 3127): #16 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:460:19) E/flutter ( 3127): #17 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22) E/flutter ( 3127): #18 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11) E/flutter ( 3127): #19 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7) E/flutter ( 3127): #20 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5) E/flutter ( 3127): #21 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7) E/flutter ( 3127): #22 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7) E/flutter ( 3127): #23 _invoke1 (dart:ui/hooks.dart:167:13) E/flutter ( 3127): #24 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7) E/flutter ( 3127): #25 _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31) E/flutter ( 3127): E/flutter ( 3127): #0 DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:643:7) E/flutter ( 3127): #1 _RootZone.runBinary (dart:async/zone.dart:1658:54) E/flutter ( 3127): #2 _FutureListener.handleError (dart:async/future_impl.dart:162:22) E/flutter ( 3127): #3 Future._propagateToListeners.handleError (dart:async/future_impl.dart:778:47) E/flutter ( 3127): #4 Future._propagateToListeners (dart:async/future_impl.dart:799:13) E/flutter ( 3127): #5 Future._completeError (dart:async/future_impl.dart:574:5) E/flutter ( 3127): #6 _SyncCompleter._completeError (dart:async/future_impl.dart:51:12) E/flutter ( 3127): #7 _Completer.completeError (dart:async/future_impl.dart:23:5) E/flutter ( 3127): #8 Future.any.onError (dart:async/future.dart:617:45) E/flutter ( 3127): #9 _RootZone.runBinary (dart:async/zone.dart:1658:54) E/flutter ( 3127): #10 _FutureListener.handleError (dart:async/future_impl.dart:162:22) E/flutter ( 3127): #11 Future._propagateToListeners.handleError (dart:async/future_impl.dart:778:47) E/flutter ( 3127): #12 Future._propagateToListeners (dart:async/future_impl.dart:799:13) E/flutter ( 3127): #13 Future._completeError (dart:async/future_impl.dart:574:5) E/flutter ( 3127): #14 Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:665:7) E/flutter ( 3127): #15 _microtaskLoop (dart:async/schedule_microtask.dart:40:21) E/flutter ( 3127): #16 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5) E/flutter ( 3127): I/ViewRootImpl@aa5f3e2[MainActivity]( 3127): MSG_WINDOW_FOCUS_CHANGED 0 1
错误原因分析
- 代码中使用
127.0.0.1作为API地址,在真机上这个地址指向手机自身,而非运行Spring Boot的电脑,导致连接拒绝。 - 错误日志中的端口34222是手机发起请求的本地端口,不是Spring Boot的8086端口,属于正常现象,核心问题还是地址指向错误。
解决方法
1. 获取电脑局域网IP地址
- Windows:打开命令提示符,输入
ipconfig,找到当前热点Wi-Fi对应的适配器的IPv4地址(格式如192.168.x.x)。 - macOS/Linux:打开终端,输入
ifconfig或ip addr,找到对应网络接口的IP地址。
2. 修改Flutter中的API地址
将代码中的127.0.0.1替换为电脑的局域网IP:
class API { // 替换为你的电脑局域网IP final String baseUrl = "http://192.168.1.100:8086/assessmentportal/authenticate/verifyemail"; final sendEmailOTPUrl = "$baseUrl/sendotp"; final verifyEmailOTPUrl = "$baseUrl/verify-otp"; // 其余代码保持不变 }
3. 配置Spring Boot允许外部访问
在application.properties或application.yml中,确保应用绑定到所有IP:
server.address=0.0.0.0 server.port=8086
4. 开放电脑防火墙8086端口
- Windows:进入防火墙设置,添加入站规则,允许8086端口的TCP连接。
- macOS/Linux:使用
ufw allow 8086/tcp命令开放端口。
5. 验证网络连通性
在手机浏览器中访问http://[电脑IP]:8086/assessmentportal/authenticate/verifyemail/reset-password-otp,如果能正常响应,再重新运行Flutter应用测试API调用。
内容的提问来源于stack exchange,提问作者ayush
相关产品推荐
相关产品推荐

