Android Samples内置HTTP服务器接收浏览器POST数据实现咨询
Android原生简易HTTP服务器处理POST请求完整实现
我刚好之前也折腾过这个Android原生HTTP服务器的POST处理,给你一套完整的实现方案,亲测能用~
首先得明确核心问题:你之前用处理GET的方式接POST肯定会出问题——GET的参数是拼在URL里的,而POST的请求数据是放在**请求体(Request Body)**中的,得从输入流里读取,这是两者最关键的区别。下面直接上代码:
1. 核心服务器实现类
import android.os.AsyncTask; import android.util.Log; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; public class NativeHttpServer { private static final String TAG = "NativeHttpServer"; private HttpServer server; // 启动服务器,指定监听端口 public void startServer(int port) { try { server = HttpServer.create(new InetSocketAddress(port), 0); // 注册POST请求的处理路径,比如 "/submit" server.createContext("/submit", new PostRequestHandler()); // 加个GET测试路径,用来验证服务器是否正常运行 server.createContext("/test", new GetRequestHandler()); server.setExecutor(null); // 使用默认线程池处理请求 server.start(); Log.d(TAG, "服务器启动成功,监听端口:" + port); } catch (IOException e) { Log.e(TAG, "服务器启动失败:" + e.getMessage()); e.printStackTrace(); } } // 停止服务器 public void stopServer() { if (server != null) { server.stop(0); Log.d(TAG, "服务器已停止"); } } // POST请求处理器核心逻辑 private static class PostRequestHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { // 先判断请求方法是不是POST,不是直接返回405 if (!"POST".equalsIgnoreCase(exchange.getRequestMethod())) { sendResponse(exchange, 405, "Method Not Allowed"); return; } // 读取POST请求体的内容 StringBuilder requestBody = new StringBuilder(); BufferedReader reader = new BufferedReader( new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8)); String line; while ((line = reader.readLine()) != null) { requestBody.append(line); } reader.close(); Log.d(TAG, "收到POST数据:" + requestBody.toString()); // 这里可以加你的业务逻辑,比如解析表单、JSON数据 String responseContent = "已成功接收POST数据:" + requestBody.toString(); // 返回响应给浏览器 sendResponse(exchange, 200, responseContent); } } // GET请求处理器(可选,用来测试服务器状态) private static class GetRequestHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { if (!"GET".equalsIgnoreCase(exchange.getRequestMethod())) { sendResponse(exchange, 405, "Method Not Allowed"); return; } String responseContent = "服务器运行正常!可以尝试发送POST请求到 /submit"; sendResponse(exchange, 200, responseContent); } } // 封装响应发送的通用方法 private static void sendResponse(HttpExchange exchange, int statusCode, String response) throws IOException { // 解决跨域问题(如果浏览器和设备不在同一域的话) exchange.getResponseHeaders().set("Access-Control-Allow-Origin", "*"); exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=utf-8"); exchange.sendResponseHeaders(statusCode, response.getBytes(StandardCharsets.UTF_8).length); OutputStream os = exchange.getResponseBody(); os.write(response.getBytes(StandardCharsets.UTF_8)); os.close(); } }
2. 在Activity中启动服务器
2.1 先配置权限(AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2.2 Activity中调用代码
public class MainActivity extends AppCompatActivity { private NativeHttpServer httpServer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化并启动服务器,用8080端口为例 httpServer = new NativeHttpServer(); // 必须在后台线程启动,Android主线程不能做IO/网络操作 new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... voids) { httpServer.startServer(8080); return null; } }.execute(); } @Override protected void onDestroy() { super.onDestroy(); // 页面销毁时停止服务器 if (httpServer != null) { httpServer.stopServer(); } } }
3. 浏览器测试用HTML页面
把下面代码保存成HTML文件,打开后把url替换成你的Android设备局域网IP(比如http://192.168.1.100:8080/submit),就能测试POST请求了:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>测试Android POST服务器</title> </head> <body> <h3>发送POST数据</h3> <input type="text" id="inputData" placeholder="输入要发送的内容"> <button onclick="sendPost()">发送</button> <div id="responseResult"></div> <script> function sendPost() { const data = document.getElementById('inputData').value; const url = 'http://你的Android设备IP:8080/submit'; // 替换成实际IP fetch(url, { method: 'POST', headers: { 'Content-Type': 'text/plain; charset=utf-8', }, body: data, }) .then(response => response.text()) .then(result => { document.getElementById('responseResult').textContent = '服务器响应:' + result; }) .catch(error => { console.error('请求错误:', error); document.getElementById('responseResult').textContent = '请求失败:' + error.message; }); } </script> </body> </html>
关键注意点
- 请求方法校验:一定要先判断请求方法是不是POST,避免用GET的逻辑处理POST请求
- 请求体读取:必须从
exchange.getRequestBody()获取输入流,不能像GET那样去读URL的Query参数 - 线程安全:服务器启动必须放在后台线程,Android主线程禁止IO操作
- 跨域问题:如果浏览器和设备不在同一局域网,记得在响应头里加
Access-Control-Allow-Origin: *,不然浏览器会拦截请求
之前的连接错误大概率是因为你用处理GET的方式去读取POST数据,导致请求没被正确处理,服务器返回错误状态码,所以浏览器报连接异常。按上面的代码实现应该就能解决问题了~
内容的提问来源于stack exchange,提问作者Maroono DeShvali
相关产品推荐
相关产品推荐

