android 网络访问拦截器使用后的bug处理

客户端调用header鉴权

说明:登录成功以后,会把JSESSIONID保存到AppDataStore中,然后我们在去访问接口的时候,自动的由拦截器去帮我们增加header。

一般代码如下:

复制代码
override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        if (request.url.toString().indexOf("login") != -1) return chain.proceed(request)

        var jsessionId = cachedJSessionId
        if (jsessionId == null) {
            synchronized(updateLock) {
                jsessionId = cachedJSessionId
                if (jsessionId == null) {
                    updateJSessionId()
                    return chain.proceed(request)
                }
            }
        }

        val cookieHeader = request.header("Cookie").orEmpty()
        val newCookie = if (cookieHeader.isEmpty()) {
            "JSESSIONID=$jsessionId"
        } else {
            "$cookieHeader; JSESSIONID=$jsessionId"
        }

        val newRequest = request.newBuilder()
            .header("Cookie", newCookie)
            .build()

        return chain.proceed(newRequest)
    }

错误出现并查找原因

开始一切都是好好的,但是最近访问10次,只有2次是正常的,数据加载成功,其它的8次基本上是报405错误。

然后我们来看看具体的405的说明:

Android 访问接口报 405 是一个很常见的客户端错误,它的核心原因非常明确:客户端发送的 HTTP 请求方法(Method),服务器不允许或不支持。

核心原因:方法不匹配

HTTP 1.1 规范定义了多种请求方法,最常用的有:

  • GET: 从服务器获取资源。
  • POST: 向服务器提交数据,创建新资源。
  • PUT: 向服务器提交数据,更新已存在的资源。
  • DELETE: 请求服务器删除指定资源。
  • PATCH: 对资源进行部分更新。
  • HEAD: 只请求资源的头部信息,不返回具体内容。

当你在 Android 端使用了一个服务器接口不支持的方法时,服务器就会返回 405 Method Not Allowed 错误。

举个例子:

  • 服务器上的某个接口 /api/login 只接受 POST 请求(因为需要提交用户名和密码)。
  • 你的 Android 代码中却错误地使用了 GET 方法去访问它。
  • 服务器收到 GET /api/login 请求后,发现这个接口不支持 GET,于是就返回 405 错误。

解决方案步骤(由易到难)

遇到 405 错误,最直接的排查方向就是确认请求方法是否正确。

1. 核对接口文档,确认正确的请求方法

这是最重要的一步。你必须与后端开发人员或接口文档确认,你要访问的这个接口究竟应该使用哪种 HTTP 方法。

2. 检查你的 Android 代码,确保方法正确

根据你使用的网络库,检查代码中的请求方法设置。

示例 1:使用 Retrofit (最常用)

Retrofit 通过注解来指定请求方法。

java

运行

复制代码
// 假设接口文档规定 /api/data 应该使用 POST 方法
public interface ApiService {
    // 正确的写法
    @POST("/api/data")
    Call<MyResponse> fetchData(@Body MyRequest request);

    // 错误的写法 (如果服务器不支持 GET,就会报 405)
    @GET("/api/data") 
    Call<MyResponse> fetchDataError(@Query("param") String param);
}

排查点: 仔细检查你的 ApiService 接口中对应方法的注解是 @GET、@POST 还是其他,并与文档保持一致。

这里面最主要是405是header中的JSESSIONID不对,是旧的,还是上次登录的时候返回的,并且我们在新的登录成功以后,又将旧的JSESSIONID传入到了服务器去请求API导致。

问题处理

在拦截器中定义清空的方法,每次登录成功以后,去执行一次,保存我们的拦截器去读最新的。

复制代码
// 在 AuthInterceptor 类中添加此方法
    fun clearCachedJSessionId() {
        synchronized(updateLock) {
            cachedJSessionId = null
        }
        updateJSessionId() // 立即重新加载
    }

在登录成功以后,我们去调用一下:

说明:先将要用到authInterceptor的地方进行注入,然后我们再去调用即可。

这次每次成功的获取了新的JSESSIONID,都去处理一下,保证最新的header传入就可以。

总结

与服务器(shiro)、(spring security)交互的时候,我们都需要保存一些标识信息(auth),然后用这个auth信息(JSEESIONID)去与服务器进行交互,这样可以保证接口调用的正确性,也可以保存唯一性。android中我们使用拦截器的方式就可以达到自动处理请求header。

拦截器的几种方式:

https://blog.csdn.net/jwbabc/article/details/149103966?spm=1011.2415.3001.5331

有兴趣的小伙伴可以自己试一下。

相关推荐
猫咪很可爱17 小时前
MySQL 5.7 备份恢复后函数与存储过程丢失:原因分析与正确备份姿势
数据库·mysql·bug·shell
李永奉1 天前
杰理可视化SDK开发-【BUG】AC7006F8芯片开启一拖二和双麦DNS通话算法后,大概率通话时蓝牙自动断连,RAM空间爆了问题处理
单片机·嵌入式硬件·mcu·物联网·电脑·bug
8年车载测试4 天前
车载测试中如何通过 Jira 平台提交 Bug:操作步骤与关键要点
bug·jira·uds诊断·hil测试·uds自动化测试·ecu刷写测试·canoe工具
硅基手札4 天前
SPI技术系列 13 · SPI 调试与排查
linux·运维·stm32·单片机·嵌入式硬件·bug
李永奉4 天前
杰理可视化SDK开发-【BUG】AC7006F8芯片开启一拖二和双麦通话语音算法后,设置触摸音在唤醒语音助手和通话时触摸音没作用问题
单片机·嵌入式硬件·mcu·物联网·电脑·bug
kyle~6 天前
机器人通信 --- FANUC TCP 并发请求-响应错位 Bug 复盘
tcp/ip·机器人·bug
鬼手点金8 天前
Harness 工程:模型之外的竞争力
服务器·人工智能·深度学习·机器学习·bug
巴巴媛6669 天前
【Debug1】程序死机,while(1)循环,怎么办?
c语言·笔记·stm32·嵌入式硬件·bug
JosieBook11 天前
【多线程】两台机器同时抢一个字典:一次并发 Bug 的排查
java·网络·bug
鬼手点金11 天前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw