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

Android 6(Marshmallow)中Volley仅返回ServerError Code:400问题排查

解决Android 6上Volley GET请求报400错误的问题

我之前也碰到过几乎一模一样的场景!Android 6(Marshmallow)上某个Volley GET请求总是触发onErrorResponse,错误码400但没具体消息,其他请求正常,浏览器也能访问,加了请求头也没用对吧?结合我的踩坑经验,给你几个排查方向:

1. 优先检查URL编码问题

Android 6的Volley对URL中特殊字符的编码处理和高版本Android有差异,比如URL里的中文、空格、或者&/=这类符号的特殊组合,高版本可能自动帮你编码了,但Android 6的Volley没处理到位,导致服务端解析失败返回400。

解决办法是手动编码URL的查询参数:

// 比如你的参数是name和value,分别编码后再拼接
String paramName = URLEncoder.encode("参数名", "UTF-8");
String paramValue = URLEncoder.encode("参数值(可能含特殊字符)", "UTF-8");
String url = "https://你的域名/api?" + paramName + "=" + paramValue;

2. 匹配浏览器的User-Agent请求头

有些服务端会校验请求的User-Agent,Android 6的Volley默认的User-Agent和浏览器差异很大,可能被服务端拦截返回400。你可以手动设置和浏览器一致的User-Agent:

StringRequest request = new StringRequest(Request.Method.GET, url,
        response -> { /* 成功回调 */ },
        error -> { /* 错误回调 */ }) {
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<>();
        // 这里用Chrome的User-Agent示例,你可以复制自己浏览器的
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
        return headers;
    }
};

3. 强制Volley使用TLS 1.2

Android 6默认只支持到TLS 1.1,如果你的服务端已经禁用了旧版TLS协议,会导致SSL握手失败,有些服务端会把这种错误映射成400返回。这时候需要让Volley强制使用TLS 1.2:

首先自定义一个TLSSocketFactory:

public class TLSSocketFactory extends SSLSocketFactory {
    private SSLSocketFactory internalSSLSocketFactory;

    public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext context = SSLContext.getInstance("TLSv1.2");
        context.init(null, null, null);
        internalSSLSocketFactory = context.getSocketFactory();
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return internalSSLSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return internalSSLSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket() throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
    }

    private Socket enableTLSOnSocket(Socket socket) {
        if(socket instanceof SSLSocket) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
        }
        return socket;
    }
}

然后创建RequestQueue时使用这个自定义栈:

try {
    TLSSocketFactory tlsSocketFactory = new TLSSocketFactory();
    HttpStack stack = new HurlStack(null, tlsSocketFactory);
    RequestQueue queue = Volley.newRequestQueue(context, stack);
    queue.add(request);
} catch (KeyManagementException | NoSuchAlgorithmException e) {
    e.printStackTrace();
}

4. 补充缺失的请求头

Android 6的Volley可能默认缺少一些浏览器常见的请求头,比如Accept、Accept-Encoding等,尝试手动添加这些头:

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = new HashMap<>();
    headers.put("Accept", "*/*");
    headers.put("Accept-Encoding", "gzip, deflate");
    headers.put("Connection", "keep-alive");
    return headers;
}

建议你按照从易到难的顺序排查:先检查URL编码,再试修改User-Agent,最后考虑TLS的问题,大概率能解决!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:52:39