如何在Ktor自定义插件中修改请求参数?
修改Ktor请求查询参数的实现方案
Ktor中ApplicationRequest及其查询参数对象都是不可变的,没有直接的append/remove方法,必须通过构建新请求对象的方式修改参数,以下是两种可行实现方式:
方式一:在自定义路由作用域插件中修改
利用createRouteScopedPlugin的拦截能力,在请求处理前替换请求对象:
class UniqueUserPluginConfiguration val UniqueUserPlugin = createRouteScopedPlugin(name = "UniqueUserPlugin", createConfiguration = ::UniqueUserPluginConfiguration) { intercept(ApplicationCallPipeline.Call) { // 获取原始查询参数 val originalQuery = call.request.queryParameters // 转换为可变Map进行修改:添加/移除参数 val mutableQuery = originalQuery.toMutableMap().apply { // 添加参数(覆盖原有同名参数) put("param", "123") // 移除指定参数 remove("unwantedParam") // 如果需要添加多值参数,用List赋值 // put("multiParam", listOf("val1", "val2")) } // 构建新的不可变查询参数 val newQueryParams = QueryParameters.build { mutableQuery.forEach { (key, values) -> values.forEach { append(key, it) } } } // 创建新请求并替换原有请求 call.request = call.request.copy(queryParameters = newQueryParams) } }
方式二:使用全局拦截器修改
如果不需要路由级别的作用域限制,直接通过全局拦截器实现:
fun Application.configureRequestParamsInterceptor() { intercept(ApplicationCallPipeline.Call) { val originalQuery = call.request.queryParameters val mutableQuery = originalQuery.toMutableMap().apply { put("param", "123") remove("oldParam") } val newQueryParams = QueryParameters.build { mutableQuery.forEach { (k, vs) -> vs.forEach { append(k, it) } } } call.request = call.request.copy(queryParameters = newQueryParams) } }
注意事项
- 拦截阶段选择:
ApplicationCallPipeline.Call阶段能确保后续路由逻辑拿到修改后的参数,是合适的修改时机。 - 多值参数处理:如果需要保留或添加同一key的多个值,操作可变Map时要处理
List<String>类型的值,构建新参数时用appendAll批量添加更高效。
内容的提问来源于stack exchange,提问作者Martin Lopez
相关产品推荐
相关产品推荐

