news 2026/4/23 12:58:09

SpEL表达式动态修改参数和请求体

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpEL表达式动态修改参数和请求体

在现代Web应用开发中,我们经常需要在请求到达最终处理器之前对请求数据进行动态修改。本文将介绍如何使用Spring的SpEL(Spring Expression Language)表达式来动态修改HTTP请求的参数和请求体,并通过一个完整的示例展示实现过程。

整体架构概述

整个解决方案的核心流程包括:

1. HandlerInterceptor拦截请求

使用Spring的HandlerInterceptor接口来拦截请求,在请求被实际处理前进行预处理:

publicclassSmartRouterInterceptorimplementsHandlerInterceptor{privatefinalSmartRouterManagersmartRouterManager;publicSmartRouterInterceptor(SmartRouterManagersmartRouterManager){this.smartRouterManager=smartRouterManager;}@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{returnsmartRouterManager.rule(request,response);}}

SmartRouterInterceptor作为拦截器,将请求交给SmartRouterManager进行规则处理,这是整个流程的入口点。

2. 重新封装HttpServletRequestWrapper以支持请求体反复读取

由于HTTP请求体只能被读取一次,我们需要创建一个可变的请求包装器来支持多次读取和修改:

publicclassMutableHttpServletRequestWrapperextendsHttpServletRequestWrapper{privateMap<String,String[]>modifiedParams=newHashMap<>();privatebyte[]modifiedBody;privateBufferedReaderbodyReader;publicMutableHttpServletRequestWrapper(HttpServletRequestrequest)throwsIOException{super(request);// 复制原始参数modifiedParams.putAll(request.getParameterMap());// 读取并缓存原始请求体if(isRequestBodySupported(request)){InputStreaminputStream=request.getInputStream();modifiedBody=StreamUtils.copyToByteArray(inputStream);bodyReader=newBufferedReader(newInputStreamReader(newByteArrayInputStream(modifiedBody),StandardCharsets.UTF_8));}}@OverridepublicServletInputStreamgetInputStream()throwsIOException{if(modifiedBody==null){returnsuper.getInputStream();}finalByteArrayInputStreambyteArrayInputStream=newByteArrayInputStream(modifiedBody);returnnewServletInputStream(){@OverridepublicbooleanisFinished(){returnbyteArrayInputStream.available()==0;}@OverridepublicbooleanisReady(){returntrue;}@OverridepublicvoidsetReadListener(ReadListenerreadListener){}@Overridepublicintread()throwsIOException{returnbyteArrayInputStream.read();}};}// 其他重写方法...}

这个包装器类解决了原生HttpServletRequest只能读取一次请求体的问题,通过缓存机制实现了请求体的重复读取。

3. 使用SpEL表达式修改参数和请求体

核心功能是使用SpEL表达式来动态修改请求数据:

@UtilityClasspublicclassSpelParamModifier{privatestaticfinalExpressionParserPARSER=newSpelExpressionParser();publicvoidmodifyParam(Map<String,String[]>params,StringspelExpression){StandardEvaluationContextcontext=newStandardEvaluationContext();context.setVariable("params",params);PARSER.parseExpression(spelExpression).getValue(context);}publicvoidmodifyJsonBody(Map<String,Object>params,StringspelExpression){StandardEvaluationContextcontext=newStandardEvaluationContext();context.setVariable("params",params);PARSER.parseExpression(spelExpression).getValue(context);}}

SmartRouterManager中集成这些组件:

if(StringUtils.hasText(mapRule)||StringUtils.hasText(bodyRule)){MutableHttpServletRequestWrappermutableRequest=newMutableHttpServletRequestWrapper(request);if(StringUtils.hasText(mapRule)){Map<String,String[]>modifiedMap=newHashMap<>(mutableRequest.getParameterMap());SpelParamModifier.modifyParam(modifiedMap,mapRule);modifiedMap.forEach(mutableRequest::setParameter);}if(StringUtils.hasText(bodyRule)){StringoriginalBody=StreamUtils.copyToString(mutableRequest.getInputStream(),StandardCharsets.UTF_8);Map<String,Object>bodyMap=OBJECT_MAPPER.readValue(originalBody,Map.class);SpelParamModifier.modifyJsonBody(bodyMap,bodyRule);StringmodifiedBody=OBJECT_MAPPER.writeValueAsString(bodyMap);mutableRequest.setJsonBody(modifiedBody);}request=mutableRequest;}

实际应用场景

这种设计模式特别适用于以下场景:

  • API网关:在请求转发前修改请求参数或请求体
  • 路由规则:根据不同条件动态修改请求内容
  • 参数验证和清理:在业务逻辑处理前统一修改请求数据
  • A/B测试:根据规则动态修改请求参数进行实验

总结

通过结合使用HandlerInterceptorHttpServletRequestWrapper和SpEL表达式,我们可以创建一个灵活的请求处理系统,能够在运行时动态修改HTTP请求的参数和请求体。这种方案提供了高度的灵活性和可扩展性,使得我们能够根据业务需求编写复杂的请求修改规则。


示例代码地址:

Gitee

Github

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 13:00:57

TCP/IP(IP、TCP、UDP、ICMP)与 HTTP/HTTPS

互联网看似复杂&#xff0c;实则由一套精密的“数字交通规则”支撑——TCP/IP 协议族。它如同城市的道路系统&#xff08;IP 负责定位&#xff0c;TCP/UDP 负责运输&#xff09;&#xff0c;而 HTTP/HTTPS 则是跑在道路上的“快递服务”。本文用一张图核心逻辑&#xff0c;带你…

作者头像 李华
网站建设 2026/4/8 18:50:00

2026年1月主流GEO优化服务商全面测评:技术路径与服务品质全解析

进入2026年&#xff0c;GEO服务商之间的竞争已从功能堆砌迈向战略纵深与商业实效的比拼。本测评报告聚焦于市场领先的五家服务商——智推时代、质安华GNA、小叮文化、易百讯与大树科技&#xff0c;通过解构其技术路径的独特性、服务模式的成熟度以及案例的商业落地效果&#xf…

作者头像 李华
网站建设 2026/4/18 5:20:35

十年nova再进化:持续受热捧的背后,藏着对“色彩”的执着

当手机成为我们最亲密的记录工具&#xff0c;色彩的真实与灵动&#xff0c;早已超越像素参数&#xff0c;成为衡量影像实力的核心标尺。华为nova 15 Ultra带着对色彩的极致追求而来&#xff0c;从一眼心动的外观到颠覆行业的前后双红枫影像&#xff0c;再到让创意落地的AI修图黑…

作者头像 李华
网站建设 2026/4/20 18:36:47

告别繁琐管道:LightOnOCR-2-1B 如何以 1B 参数实现极致 OCR 性能

LightOnOCR-2-1B&#xff1a;10 亿参数的轻量级 OCR 革命&#xff0c;速度与精度双杀 OCR 进入“端到端 轻量化”新纪元 在文档处理领域&#xff0c;传统 OCR&#xff08;光学字符识别&#xff09;系统长期依赖复杂的多阶段流水线&#xff1a;图像预处理 → 文本检测 → 文字…

作者头像 李华
网站建设 2026/4/20 0:33:45

收藏!30+程序员破局35岁危机:从Java后端到大厂大模型岗的实战指南

各位30的程序员同行&#xff0c;你是否也曾在深夜对着电脑屏幕陷入沉思&#xff1a;手头的CRUD工作日渐机械&#xff0c;职业晋升通道一眼就能望到尽头&#xff0c;看着身边20多岁的同事轻松驾驭新框架&#xff0c;还能毫无压力地通宵加班——这一刻&#xff0c;你是不是也在怀…

作者头像 李华