You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android调用Positionstack API返回HTTP 400语法错误求助

解决Positionstack API在Android模拟器中返回400 Bad Request的问题

你的代码存在多个明确问题,直接导致了400错误及JSON语法错误提示,以下是问题分析和修复方案:

问题根源

  1. 语法不完整:代码中con.set语句未写完,属于无效语法,会导致请求构造逻辑异常。
  2. 请求头与请求体不匹配:你设置了Content-Type: application/json,但注释的参数传递代码是用form格式键值对(access_key=xxx),服务器尝试按JSON解析时自然会报语法错误。
  3. 缺少必填参数:注释掉了参数写入代码,未向API传递access_key和query这两个核心参数,服务器无法处理空请求。
  4. 请求方法选择不当:Positionstack的逆地理编码API默认支持GET请求,用GET传递参数更简洁,也不容易出错。

修复方案

方案1:使用GET请求(推荐)

GET请求直接将参数拼接在URL后,无需处理请求体,代码更简洁可靠:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class NetTest {
    public static String sendRequest(String baseUrl, String coordinate, String accessKey){
        HttpURLConnection con = null;
        BufferedReader buffer = null;
        StringBuffer resultBuffer = null;
        InputStream is;

        try{
            // 对坐标参数进行URL编码,避免特殊字符问题
            String encodedCoordinate = URLEncoder.encode(coordinate, StandardCharsets.UTF_8.name());
            // 拼接完整请求URL
            String fullUrl = String.format("%s?access_key=%s&query=%s", baseUrl, accessKey, encodedCoordinate);
            URL url = new URL(fullUrl);
            
            con = (HttpURLConnection) url.openConnection();
            con.setConnectTimeout(5000);
            con.setReadTimeout(5000);
            con.setRequestMethod("GET");

            // 接收响应
            int responseCode = con.getResponseCode();
            System.out.println(responseCode);
            is = responseCode == 200 ? con.getInputStream() : con.getErrorStream();
            
            resultBuffer = new StringBuffer();
            String line;
            buffer = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8.name()));
            while ((line = buffer.readLine()) != null){
                resultBuffer.append(line);
            }
            return resultBuffer.toString();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源,避免内存泄漏
            if (buffer != null) {
                try {
                    buffer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (con != null) {
                con.disconnect();
            }
        }
        return "";
    }

    public static void main(String[] args) {
        String coordinate = "-33.7,127";
        String url = "http://api.positionstack.com/v1/reverse";
        String accessKey = "你的实际access_key"; // 替换为你的API密钥
        System.out.println(sendRequest(url, coordinate, accessKey));
    }
}

方案2:修复POST请求(若坚持使用)

如果一定要用POST,需保证请求头与请求体格式一致,以下是两种可行方式:

方式A:Form格式POST请求

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;

public class NetTest {
    public static String sendRequest(String urlParam, String coordinate, String accessKey){
        HttpURLConnection con = null;
        BufferedReader buffer = null;
        StringBuffer resultBuffer = null;
        InputStream is;

        try{
            URL url = new URL(urlParam);
            con = (HttpURLConnection) url.openConnection();
            con.setConnectTimeout(5000);
            con.setReadTimeout(5000);
            con.setRequestMethod("POST");
            // 设置正确的Form格式请求头
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            con.setDoOutput(true);
            
            // 构造Form参数
            String postData = String.format("access_key=%s&query=%s", accessKey, coordinate);
            byte[] postDataBytes = postData.getBytes(StandardCharsets.UTF_8);
            
            // 写入请求体
            try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
                wr.write(postDataBytes);
                wr.flush();
            }

            // 接收响应
            int responseCode = con.getResponseCode();
            System.out.println(responseCode);
            is = responseCode == 200 ? con.getInputStream() : con.getErrorStream();
            
            resultBuffer = new StringBuffer();
            String line;
            buffer = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8.name()));
            while ((line = buffer.readLine()) != null){
                resultBuffer.append(line);
            }
            return resultBuffer.toString();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (buffer != null) {
                try {
                    buffer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (con != null) {
                con.disconnect();
            }
        }
        return "";
    }

    public static void main(String[] args) {
        String coordinate = "-33.7,127";
        String url = "http://api.positionstack.com/v1/reverse";
        String accessKey = "你的实际access_key"; // 替换为你的API密钥
        System.out.println(sendRequest(url, coordinate, accessKey));
    }
}

方式B:JSON格式POST请求

若要使用JSON格式,需构造合法的JSON请求体:

// 仅替换请求头和请求体部分代码
con.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
con.setDoOutput(true);

// 构造合法的JSON字符串
String jsonBody = String.format("{\"access_key\":\"%s\",\"query\":\"%s\"}", accessKey, coordinate);
byte[] jsonBytes = jsonBody.getBytes(StandardCharsets.UTF_8);

try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
    wr.write(jsonBytes);
    wr.flush();
}

额外注意事项

在Android中,网络请求不能在主线程执行,需要用Coroutine、AsyncTask或第三方网络库(如OkHttp)处理异步请求,否则会抛出NetworkOnMainThreadException。

内容的提问来源于stack exchange,提问作者user130355

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 02:15:33