Android与Spring Boot WebSocket通信:如何接收Android端发送的数据?
解决Spring Boot获取Android端WebSocket发送数值的问题
你的核心问题是Android用的是原生WebSocket协议,但Spring Boot配置的是STOMP协议的WebSocket,两者协议不兼容,导致后端收不到前端发送的消息。下面给两种可行的解决思路:
方案一:Android端改用STOMP客户端适配Spring Boot配置
Spring Boot当前配置的是STOMP协议的WebSocket,所以Android端需要用STOMP客户端来连接并发送消息,才能和后端兼容。
1. Android端修改
首先在Android项目的build.gradle中添加STOMP依赖:
dependencies { implementation 'com.github.NaikSoftware:StompProtocolAndroid:1.6.0' }
然后修改RestModule和GpsActivity的代码,改用STOMP连接:
// RestModule.kt object RestModule { fun getStompClient(): StompClient { val stompClient = StompClient(OkHttpClient()) // 连接地址对应Spring Boot的STOMP端点 stompClient.connect("ws://my-ip:30000/ws") return stompClient } } // GpsActivity.kt class GpsActivity: ComponentActivity() { private lateinit var stompClient: StompClient private val service = RestModule override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { stompClient = service.getStompClient() } } private fun createLocation() { val locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { for (location in locationResult.locations){ location?.let { val json = "{\"latitude\": ${location.latitude}, \"longitude\": ${location.longitude}}" // 发送到Spring Boot配置的/app/greetings目的地 stompClient.send("/app/greetings", json).subscribe() markerPosition.value=LatLng(location.latitude, location.longitude) } } } } } }
2. Spring Boot端优化接收(可选)
创建实体类自动解析JSON,不用手动处理字符串:
// Location.java public class Location { private double latitude; private double longitude; public Location() {} // 必须保留无参构造函数,供Jackson解析 // getter和setter public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; } }
修改控制器方法直接接收实体类:
@RestController @RequestMapping("/cart-purchase-command") public class CartPurchaseCommand { private static final Logger logger = LoggerFactory.getLogger(CartPurchaseCommand.class); @MessageMapping("/greetings") @SendTo("/topic/greetings") public String broadcastNews(@Payload Location location) { logger.info(">> 纬度: {}, 经度: {}", location.getLatitude(), location.getLongitude()); return "收到位置:纬度" + location.getLatitude() + ",经度" + location.getLongitude(); } }
方案二:Spring Boot添加普通WebSocket处理器兼容Android原生WebSocket
如果不想修改Android端代码,可以在Spring Boot中添加原生WebSocket支持,和现有STOMP配置共存。
1. 创建WebSocket处理器
// LocationWebSocketHandler.java @Component public class LocationWebSocketHandler extends TextWebSocketHandler { private static final Logger logger = LoggerFactory.getLogger(LocationWebSocketHandler.class); @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 获取Android发送的JSON字符串 String payload = message.getPayload(); logger.info(">> 收到原生WebSocket消息: {}", payload); // 用Jackson解析成实体类 ObjectMapper mapper = new ObjectMapper(); Location location = mapper.readValue(payload, Location.class); logger.info(">> 解析后的位置:纬度{},经度{}", location.getLatitude(), location.getLongitude()); // 可选:给Android回复消息 session.sendMessage(new TextMessage("已收到位置:" + payload)); } }
2. 注册原生WebSocket端点
修改WebSocketConfig,添加原生WebSocket的注册逻辑:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer, WebSocketConfigurer { @Autowired private LocationWebSocketHandler locationWebSocketHandler; // 原有的STOMP配置 @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS(); } // 新增原生WebSocket配置 @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // 注册对应Android连接路径的端点 registry.addHandler(locationWebSocketHandler, "/cart-purchase-command/app/greetings") .setAllowedOrigins("*"); } }
这样Android端无需改动,Spring Boot就能正常接收消息。
内容的提问来源于stack exchange,提问作者Rafael Souza
相关产品推荐
相关产品推荐

