经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
Java替换RequestBody和RequestParam参数的属性
来源:cnblogs  作者:初夏的阳光丶  时间:2023/10/25 10:13:03  对本文有异议

Java替换RequstBody和RequestParam参数的属性

本文主要讲解在Java环境中如何替换RequestBody和RequestParam参数中的属性

背景

近期由于接手的老项目中存在所有接口中新增一个加密串来给接口做一个加密效果(项目历史原因,不方便上Jwt授权这套),所以就研究了一下Http请求链路,发现可以通过 javax.servlet.Filter去实现

替换RequestParam参数

首先通过继续HttpServletRequestWrapper来达到获取和替换RequestParam中的参数信息,接下来我们通过javax.servlet.Filter去获取ServletRequest中参数的信息,并且定义对应规则,来实现替换参数
代码示例:

  1. package com.simplemessage.cloudpayservice.infrastructure.config.http;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletRequestWrapper;
  4. import java.util.Enumeration;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import java.util.Vector;
  8. /**
  9. * @CreateAt: 2023/10/24 12:13
  10. * @ModifyAt: 2023/10/24 12:13
  11. * @Version 1.0
  12. */
  13. public class MyRequestWrapper extends HttpServletRequestWrapper {
  14. private Map params = new HashMap<>();
  15. public MyRequestWrapper(HttpServletRequest request, Map newParams) {
  16. super(request);
  17. if(request.getParameterMap() != null){
  18. this.params.putAll(request.getParameterMap());
  19. }
  20. if(newParams != null){
  21. this.params.putAll(newParams);
  22. }
  23. }
  24. /**
  25. * 获取参数
  26. * @return
  27. */
  28. @Override
  29. public Map getParameterMap() {
  30. return params;
  31. }
  32. @Override
  33. public Enumeration getParameterNames() {
  34. Vector l = new Vector(params.keySet());
  35. return l.elements();
  36. }
  37. @Override
  38. public String[] getParameterValues(String name) {
  39. Object v = params.get(name);
  40. if (v == null) {
  41. return null;
  42. } else if (v instanceof String[]) {
  43. return (String[]) v;
  44. } else if (v instanceof String) {
  45. return new String[]{(String) v};
  46. } else {
  47. return new String[]{v.toString()};
  48. }
  49. }
  50. /**
  51. * 根据参数的key获取参数
  52. * @param name
  53. * @return
  54. */
  55. @Override
  56. public String getParameter(String name) {
  57. Object v = params.get(name);
  58. if (v == null) {
  59. return null;
  60. } else if (v instanceof String[]) {
  61. String[] strArr = (String[]) v;
  62. if (strArr.length > 0) {
  63. return strArr[0];
  64. } else {
  65. return null;
  66. }
  67. } else if (v instanceof String) {
  68. return (String) v;
  69. } else {
  70. return v.toString();
  71. }
  72. }
  73. }
  1. package com.simplemessage.cloudpayservice.infrastructure.config.http;
  2. import com.fasterxml.jackson.core.io.JsonEOFException;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.apache.catalina.connector.RequestFacade;
  5. import org.springframework.http.converter.HttpMessageNotReadableException;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.util.StringUtils;
  8. import javax.servlet.*;
  9. import javax.servlet.annotation.WebFilter;
  10. import javax.servlet.http.HttpServletRequest;
  11. import java.io.IOException;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. /**
  15. * @CreateAt: 2023/10/24 12:16
  16. * @ModifyAt: 2023/10/24 12:16
  17. * @Version 1.0
  18. */
  19. @Slf4j
  20. @Component
  21. @WebFilter(filterName = "replaceGetRequestFilter", urlPatterns = {"/*"})
  22. public class ReplaceGetRequestFilter implements Filter {
  23. @Override
  24. public void init(FilterConfig filterConfig) {
  25. }
  26. @Override
  27. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  28. long start = System.currentTimeMillis();
  29. //获取HttpServletRequest对象
  30. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  31. //判断当前是否为Get请求
  32. if ("GET".equalsIgnoreCase(httpServletRequest.getMethod())) {
  33. // 获取参数信息
  34. String param= request.getParameter("param");
  35. //判断参数是否为空,为空则放行
  36. if (StringUtils.isEmpty(param)) {
  37. chain.doFilter(request, response);
  38. return;
  39. } else {
  40. Map<String, String[]> newParameterMap = new HashMap<>();
  41. // 替换参数(自定义规则)
  42. String newParama="test";
  43. newParameterMap.put("param", newParama);
  44. // 实现参数替换
  45. MyRequestWrapper myRequestWrapper = new MyRequestWrapper(httpServletRequest, newParameterMap);
  46. chain.doFilter(myRequestWrapper, response);
  47. }
  48. } else {
  49. try {
  50. chain.doFilter(request, response);
  51. } catch (HttpMessageNotReadableException httpMessageNotReadableException) {
  52. log.error(((RequestFacade) request).getRequestURI() + ", " + httpMessageNotReadableException.getMessage());
  53. } catch (JsonEOFException jsonEOFException) {
  54. log.error(((RequestFacade) request).getRequestURI() + ", " + jsonEOFException.getMessage());
  55. }
  56. }
  57. long end = System.currentTimeMillis();
  58. log.info("{} 接口耗时:{} ms", httpServletRequest.getRequestURI(), (end - start));
  59. }
  60. @Override
  61. public void destroy() {
  62. }
  63. }

替换RequestBody参数

主要思路就是通过获取Post中请求的输入流信息,解析输入流信息,按照对应的规则进行替换参数信息,最后将对应的流信息包装进行返回
代码示例:

  1. package com.simplemessage.cloudpayservice.infrastructure.config.http;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.apache.commons.lang.StringUtils;
  6. import org.apache.tomcat.util.http.fileupload.IOUtils;
  7. import org.springframework.core.MethodParameter;
  8. import org.springframework.http.HttpHeaders;
  9. import org.springframework.http.HttpInputMessage;
  10. import org.springframework.http.converter.HttpMessageConverter;
  11. import org.springframework.lang.Nullable;
  12. import org.springframework.util.CollectionUtils;
  13. import org.springframework.util.ObjectUtils;
  14. import org.springframework.web.bind.annotation.RestControllerAdvice;
  15. import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
  16. import java.io.ByteArrayInputStream;
  17. import java.io.ByteArrayOutputStream;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.lang.reflect.Type;
  21. import java.util.List;
  22. /**
  23. * @version 1.0
  24. * @createAt: 2023/10/24 12:23:23
  25. * @modifyAt: 2023/10/24 12:23:23
  26. */
  27. @RestControllerAdvice
  28. @Slf4j
  29. public class DecryptRequestBodyHandler implements RequestBodyAdvice {
  30. /**
  31. * 该方法用于判断当前请求,是否要执行beforeBodyRead方法
  32. * methodParameter方法的参数对象
  33. * type方法的参数类型
  34. * aClass 将会使用到的Http消息转换器类类型
  35. * 注意:此判断方法,会在beforeBodyRead 和 afterBodyRead方法前都触发一次。
  36. * @return 返回true则会执行beforeBodyRead
  37. */
  38. @Override
  39. public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
  40. return true;
  41. }
  42. /**
  43. * 在Http消息转换器执转换,之前执行
  44. * inputMessage 客户端请求的信息
  45. * parameter 参数信息
  46. * targetType 参数类型
  47. * converterType Http消息转换器类类型
  48. *
  49. * @return 返回 一个自定义的HttpInputMessage
  50. */
  51. @Override
  52. public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
  53. // 如果body是空内容直接返回原来的请求
  54. if (inputMessage.getBody().available() <= 0) {
  55. return inputMessage;
  56. }
  57. // 请求中的header信息
  58. HttpHeaders headers = inputMessage.getHeaders();
  59. // 将输入流读出来,注意 body 里面的流只能读一次
  60. ByteArrayOutputStream requestBodyDataByte = new ByteArrayOutputStream();
  61. try {
  62. //复制流信息
  63. IOUtils.copy(inputMessage.getBody(), requestBodyDataByte);
  64. } catch (Exception e) {
  65. log.error("参数流拷贝失败: ", e.toString());
  66. return inputMessage;
  67. }
  68. ByteArrayOutputStream requestBodyDataByteNew = null;
  69. try {
  70. JSONObject body = JSON.parseObject(requestBodyDataByte.toByteArray(), JSONObject.class);
  71. if (ObjectUtils.isEmpty(body)) {
  72. return inputMessage;
  73. }
  74. //自定义规则西悉尼
  75. if (body.containsKey("param")) {
  76. String custId = body.getString("param");
  77. String newParam="";
  78. body.put("custId", newParam);
  79. requestBodyDataByteNew = new ByteArrayOutputStream();
  80. //拷贝流信息
  81. IOUtils.copy(new ByteArrayInputStream(body.toJSONString().getBytes()), requestBodyDataByteNew);
  82. }
  83. } catch (Throwable e) {
  84. log.error("流转换异常 ", e.toString());
  85. }
  86. // 如果上述发生异常,仍然使用原来的请求内容
  87. requestBodyDataByte = requestBodyDataByteNew != null ? requestBodyDataByteNew : requestBodyDataByte;
  88. InputStream rawInputStream = new ByteArrayInputStream(requestBodyDataByte.toByteArray());
  89. inputMessage.getHeaders().set(HttpHeaders.CONTENT_LENGTH, String.valueOf(rawInputStream.available()));
  90. return new HttpInputMessage() {
  91. @Override
  92. public HttpHeaders getHeaders() {
  93. return inputMessage.getHeaders();
  94. }
  95. @Override
  96. public InputStream getBody() throws IOException {
  97. return rawInputStream;
  98. }
  99. };
  100. }
  101. /**
  102. * 在Http消息转换器执转换,之后执行
  103. * body 转换后的对象
  104. * inputMessage 客户端的请求数据
  105. * parameter handler方法的参数类型
  106. * targetType handler方法的参数类型
  107. * converterType 使用的Http消息转换器类类型
  108. *
  109. * @return 返回一个新的对象
  110. */
  111. @Override
  112. public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
  113. return body;
  114. }
  115. /**
  116. * 参数与afterBodyRead相同,不过这个方法body为空的情况
  117. */
  118. @Override
  119. public Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
  120. return body;
  121. }
  122. }

如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧??

原文链接:https://www.cnblogs.com/ancold/p/17785227.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号