Android Studio向Spring Boot服务器发送POST请求失败,求解决方案
Hey there! I see you're having trouble getting that raw HttpsURLConnection code to send a POST request from Android (API 29) to your Spring Boot server. Let's break down what might be going wrong and fix this step by step.
First, the main issues with your original code:
- You're calling an undefined
getQuerymethod (it's needed to convert parameters into URL-encoded form data) - Android API 29+ blocks cleartext HTTP by default (unless explicitly allowed)
- Network requests can't run on the main thread (you'll hit a
NetworkOnMainThreadException) - Your Spring Boot server might not be set up to receive the parameter format you're sending
Option 1: Fix the Raw HttpsURLConnection Code
Step 1: Implement the Missing getQuery Method
Add this helper method to convert your NameValuePair list into a URL-encoded string:
private String getQuery(List<NameValuePair> params) throws UnsupportedEncodingException { StringBuilder result = new StringBuilder(); boolean first = true; for (NameValuePair pair : params) { if (first) first = false; else result.append("&"); result.append(URLEncoder.encode(pair.getName(), "UTF-8")); result.append("="); result.append(URLEncoder.encode(pair.getValue(), "UTF-8")); } return result.toString(); }
Step 2: Allow Cleartext HTTP (Testing Only)
If your Spring Boot server uses HTTP (not HTTPS), add this to your AndroidManifest.xml inside the <application> tag (never use this in production):
android:usesCleartextTraffic="true"
Step 3: Run the Request on a Background Thread
Network calls can't run on the main thread. Use an AsyncTask (or Kotlin Coroutines if you're using Kotlin) to handle this:
private class PostRequestTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { try { URL url = new URL("http://your-spring-boot-server-url/api/your-endpoint"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); // Configure connection settings conn.setReadTimeout(10000); conn.setConnectTimeout(15000); conn.setRequestMethod("POST"); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // Add your parameters List<NameValuePair> params = new ArrayList<>(); params.add(new BasicNameValuePair("firstParam", "your-value-1")); params.add(new BasicNameValuePair("secondParam", "your-value-2")); // Write parameters to the output stream OutputStream os = conn.getOutputStream(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); writer.write(getQuery(params)); writer.flush(); writer.close(); os.close(); // Get and process the response int responseCode = conn.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = br.readLine()) != null) { response.append(line); } br.close(); return response.toString(); } else { return "Request failed with code: " + responseCode; } } catch (Exception e) { e.printStackTrace(); return "Error: " + e.getMessage(); } } @Override protected void onPostExecute(String result) { // Handle the response here (e.g., update UI, log results) Log.d("POST_RESPONSE", result); } }
Call the task like this:
new PostRequestTask().execute();
Option 2: Use OkHttp (Simpler & More Reliable)
Raw HttpsURLConnection is verbose and error-prone. OkHttp is a popular library that simplifies network calls significantly.
Step 1: Add OkHttp Dependency
Add this to your app-level build.gradle (module-level) dependencies:
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
Step 2: Send Form Data to Spring Boot
OkHttpClient client = new OkHttpClient(); // Build form data RequestBody formBody = new FormBody.Builder() .add("firstParam", "your-value-1") .add("secondParam", "your-value-2") .build(); // Create POST request Request request = new Request.Builder() .url("http://your-spring-boot-server-url/api/your-endpoint") .post(formBody) .build(); // Execute request asynchronously client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String responseBody = response.body().string(); Log.d("OKHTTP_RESPONSE", responseBody); // If you need to update UI, switch back to main thread runOnUiThread(() -> { // Update UI elements here }); } else { Log.e("OKHTTP_ERROR", "Request failed: " + response.code()); } } });
Spring Boot Server Setup
Make sure your Spring Boot controller is set up to receive the parameters correctly:
For Form Data
@RestController @RequestMapping("/api") public class MyController { @PostMapping("/your-endpoint") public ResponseEntity<String> handlePostRequest( @RequestParam String firstParam, @RequestParam String secondParam) { // Process the parameters as needed return ResponseEntity.ok("Received: " + firstParam + ", " + secondParam); } }
For JSON Data (More Common for REST APIs)
If you prefer sending JSON instead of form data, adjust your Android code to send a JSON body:
String jsonBody = "{\"firstParam\":\"your-value-1\",\"secondParam\":\"your-value-2\"}"; RequestBody requestBody = RequestBody.create( jsonBody, MediaType.parse("application/json; charset=utf-8") ); Request request = new Request.Builder() .url("http://your-spring-boot-server-url/api/json-endpoint") .post(requestBody) .build(); // Execute request with OkHttp as before
Then update your Spring Boot controller to accept JSON:
// Create a DTO class to map the JSON public class RequestPayload { private String firstParam; private String secondParam; // Getters and Setters public String getFirstParam() { return firstParam; } public void setFirstParam(String firstParam) { this.firstParam = firstParam; } public String getSecondParam() { return secondParam; } public void setSecondParam(String secondParam) { this.secondParam = secondParam; } } @RestController @RequestMapping("/api") public class MyController { @PostMapping("/json-endpoint") public ResponseEntity<String> handleJsonRequest(@RequestBody RequestPayload payload) { return ResponseEntity.ok("Received JSON: " + payload.getFirstParam() + ", " + payload.getSecondParam()); } }
Critical Notes
- Add Internet Permission: Make sure you have this in your
AndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET" /> - Use HTTPS in Production: Avoid cleartext HTTP in production—set up HTTPS for your Spring Boot server.
- CORS Configuration: If your Android app runs on a different domain/port than your Spring Boot server, add CORS configuration to your Spring Boot app to allow cross-origin requests.
内容的提问来源于stack exchange,提问作者ozer

