当前位置:   article > 正文

springboot使用拦截器拦截接口的请求body, 修改body_handlerinterceptor拦截器修改并更新请求体

handlerinterceptor拦截器修改并更新请求体

新建拦截器: WebFilter

目的:拦截所有请求过滤器,并将请求类型是HttpServletRequest类型的请求替换为自定义{@link com.*.biz.service.common.interceptor.RequestWrapper

  1. import com.biz.service.common.interceptor.RequestWrapper;
  2. import org.springframework.core.annotation.Order;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. import javax.servlet.http.HttpServletRequest;
  10. import java.io.IOException;
  11. /**
  12. * @Description: 拦截所有请求过滤器,并将请求类型是HttpServletRequest类型的请求替换为自定义{@link com.biz.service.common.interceptor.RequestWrapper}
  13. */
  14. @Order(-1)
  15. @javax.servlet.annotation.WebFilter(filterName = "webFilter", urlPatterns = "/*")
  16. public class WebFilter implements Filter {
  17. @Override
  18. public void init(FilterConfig filterConfig) throws ServletException {
  19. }
  20. @Override
  21. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
  22. throws IOException, ServletException {
  23. ServletRequest request = null;
  24. if (servletRequest instanceof HttpServletRequest) {
  25. request = new RequestWrapper((HttpServletRequest) servletRequest);
  26. }
  27. if (request == null) {
  28. chain.doFilter(servletRequest, servletResponse);
  29. } else {
  30. chain.doFilter(request, servletResponse);
  31. }
  32. }
  33. @Override
  34. public void destroy() {
  35. }
  36. }
拦截器配置
  1. import com.biz.service.common.filter.WebFilter;
  2. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import java.util.Collections;
  6. @Configuration
  7. public class FilterConfig {
  8. @Bean
  9. FilterRegistrationBean<WebFilter> myFilterFilterRegistrationBean() {
  10. FilterRegistrationBean<WebFilter> bean = new FilterRegistrationBean<>();
  11. bean.setFilter(new WebFilter());
  12. bean.setOrder(-1);
  13. bean.setUrlPatterns(Collections.singletonList("/*"));
  14. return bean;
  15. }
  16. }
 

新建 RequestWrapper

目的: getInputStream获取流 然后在流中获取数据 但是这个方法只能获取一次;重写httpservletrequestwrapper把request保存下来.用过滤器把保存的request填进去 就可以多次读取了

  1. import javax.servlet.ReadListener;
  2. import javax.servlet.ServletInputStream;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletRequestWrapper;
  5. import java.io.BufferedReader;
  6. import java.io.ByteArrayInputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.InputStreamReader;
  10. /**
  11. * getInputStream获取流 然后在流中获取数据 但是这个方法只能获取一次
  12. * 重写httpservletrequestwrapper把request保存下来
  13. * 用过滤器把保存的request填进去 就可以多次读取了
  14. */
  15. public class RequestWrapper extends HttpServletRequestWrapper {
  16. private String body;
  17. public RequestWrapper(HttpServletRequest request) throws IOException {
  18. super(request);
  19. StringBuilder stringBuilder = new StringBuilder();
  20. BufferedReader bufferedReader = null;
  21. try {
  22. InputStream inputStream = request.getInputStream();
  23. if (inputStream != null) {
  24. bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
  25. char[] charBuffer = new char[128];
  26. int bytesRead = -1;
  27. while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
  28. stringBuilder.append(charBuffer, 0, bytesRead);
  29. }
  30. } else {
  31. stringBuilder.append("");
  32. }
  33. } catch (IOException ex) {
  34. throw ex;
  35. } finally {
  36. if (bufferedReader != null) {
  37. try {
  38. bufferedReader.close();
  39. } catch (IOException ex) {
  40. throw ex;
  41. }
  42. }
  43. }
  44. body = stringBuilder.toString();
  45. }
  46. @Override
  47. public ServletInputStream getInputStream() throws IOException {
  48. final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
  49. ServletInputStream servletInputStream = new ServletInputStream() {
  50. public boolean isFinished() {
  51. return false;
  52. }
  53. public boolean isReady() {
  54. return false;
  55. }
  56. public void setReadListener(ReadListener readListener) {
  57. }
  58. public int read() throws IOException {
  59. return byteArrayInputStream.read();
  60. }
  61. };
  62. return servletInputStream;
  63. }
  64. @Override
  65. public BufferedReader getReader() throws IOException {
  66. return new BufferedReader(new InputStreamReader(this.getInputStream()));
  67. }
  68. public String getBody() {
  69. return this.body;
  70. }
  71. // 赋值给body字段
  72. public void setBody(String body) {
  73. this.body = body;
  74. }
  75. }

创建过滤器,获取请求的body,处理后,set回请求中;

  1. import cn.hutool.core.util.StrUtil;
  2. import com.biz.api.common.annotations.I18nTimeHandle;
  3. import com.biz.service.utils.DateZoneUtil;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.web.method.HandlerMethod;
  6. import org.springframework.web.servlet.HandlerInterceptor;
  7. import org.springframework.web.servlet.ModelAndView;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import java.util.List;
  11. @Slf4j
  12. public class DateHandlerInterceptor implements HandlerInterceptor {
  13. //在请求处理之前进行调用(Controller方法调用之前)
  14. @Override
  15. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  16. HandlerMethod handlerMethod = (HandlerMethod) handler;
  17. I18nTimeHandle annotation = handlerMethod.getMethod().getAnnotation(I18nTimeHandle.class);
  18. if (annotation == null) {
  19. return true;
  20. }
  21. /**
  22. * getInputStream获取流 然后在流中获取数据 但是这个方法只能获取一次,重写HttpServletRequestWrapper把request保存下来
  23. * 用过滤器把保存的request填进去 就可以多次读取了
  24. */
  25. //如果方法上存在 I18nTimeHandle 注解,则进行时间时区处理
  26. if (request instanceof RequestWrapper) {
  27. RequestWrapper requestWrapper = (RequestWrapper) request;
  28. String body = requestWrapper.getBody();
  29. log.info("处理前的请求体:{}", body);
  30. //获取请求json中时间字符串
  31. List<String> jsonStrDateStr = DateZoneUtil.getJsonStrDateStr(body);
  32. for (String originDate : jsonStrDateStr) {
  33. //将前端传入的时间 转换成 东八区的时间
  34. String targetDate = DateZoneUtil.converDateGMT(originDate, "+8", "+6");
  35. body = StrUtil.replace(body, originDate, targetDate);
  36. }
  37. log.info("处理后的请求体:{}", body);
  38. //将处理后的body放回
  39. requestWrapper.setBody(body);
  40. }
  41. return true;
  42. }
  43. //请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
  44. @Override
  45. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  46. }
  47. //在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
  48. @Override
  49. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  50. }
  51. }

过滤器配置

  1. import com.biz.service.common.interceptor.DateHandlerInterceptor;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  4. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  5. @Configuration
  6. public class WebAppConfig implements WebMvcConfigurer {
  7. @Override
  8. public void addInterceptors(InterceptorRegistry registry) {
  9. // 可添加多个,这里选择拦截所有请求地址,进入后判断是否有加注解即可
  10. registry.addInterceptor(new DateHandlerInterceptor()).addPathPatterns("/**");
  11. }
  12. }

工具类代码

  1. import cn.hutool.core.util.StrUtil;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.google.common.collect.Lists;
  5. import com.biz.service.common.exception.BizException;
  6. import java.text.ParseException;
  7. import java.text.SimpleDateFormat;
  8. import java.util.Date;
  9. import java.util.List;
  10. import java.util.TimeZone;
  11. public class DateZoneUtil {
  12. private static String GMT_8 = "GMT+8";
  13. /**
  14. * 转换时间时区
  15. *
  16. * @param dateStr 需要转的时间字符串
  17. * @param sourceTimeZone 源时间时区 +8
  18. * @param targetTimeZone 目标时间时区 +6
  19. * @return
  20. * @throws ParseException
  21. */
  22. public static String converDateGMT(String dateStr, String sourceTimeZone, String targetTimeZone) {
  23. sourceTimeZone = StrUtil.isEmpty(sourceTimeZone) ? GMT_8 : converTimeZone(sourceTimeZone);
  24. targetTimeZone = StrUtil.isEmpty(targetTimeZone) ? GMT_8 : converTimeZone(targetTimeZone);
  25. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  26. //获取传入的时间值
  27. Long time = 0L;
  28. try {
  29. time = new Date(sdf.parse(dateStr).getTime()).getTime();
  30. } catch (ParseException pe) {
  31. throw new BizException("时间格式化异常");
  32. }
  33. //获取源时区时间相对的GMT时间
  34. Long sourceRelativelyGMT = time - TimeZone.getTimeZone(sourceTimeZone).getRawOffset();
  35. //GMT时间+目标时间时区的偏移量获取目标时间
  36. Long targetTime = sourceRelativelyGMT + TimeZone.getTimeZone(targetTimeZone).getRawOffset();
  37. Date date = new Date(targetTime);
  38. return cn.hutool.core.date.DateUtil.formatDateTime(date);
  39. }
  40. /**
  41. * timeZone转换 +8->GMT+8
  42. *
  43. * @param timeZone
  44. * @return
  45. */
  46. private static String converTimeZone(String timeZone) {
  47. if (StrUtil.isEmpty(timeZone)) {
  48. return GMT_8;
  49. }
  50. return "GMT" + timeZone;
  51. }
  52. /**
  53. * 从jsonStr中获取时间字符串(只有符合格式的才会被截取 yyyy-MM-dd HH:mm:ss )
  54. *
  55. * @param jsonStr
  56. * @return
  57. */
  58. public static List<String> getJsonStrDateStr(String jsonStr) {
  59. //递归获取jsonObject中的时间字符串
  60. return getJsonObjectDateStr(JSONObject.parseObject(jsonStr));
  61. }
  62. /**
  63. * 递归获取jsonObject中的时间字符串
  64. *
  65. * @param jsonObject
  66. * @return
  67. */
  68. private static List<String> getJsonObjectDateStr(JSONObject jsonObject) {
  69. List<String> resultList = Lists.newArrayList();
  70. jsonObject.entrySet().forEach(v -> {
  71. if (v.getValue() != null && v.getValue().getClass().equals(String.class) && isValidDate(String.valueOf(v.getValue()))) {
  72. resultList.add(/*v.getKey() + "---" +*/ String.valueOf(v.getValue()));
  73. } else if (v.getValue() != null && v.getValue().getClass().equals(JSONObject.class)) {
  74. JSONObject jsonObject1 = (JSONObject) v.getValue();
  75. resultList.addAll(getJsonObjectDateStr(jsonObject1));
  76. } else if (v.getValue() != null && v.getValue().getClass().equals(JSONArray.class)) {
  77. JSONArray jsonArray = (JSONArray) v.getValue();
  78. for (Object o : jsonArray) {
  79. JSONObject jsonObject2 = (JSONObject) o;
  80. resultList.addAll(getJsonObjectDateStr(jsonObject2));
  81. }
  82. }
  83. });
  84. return resultList;
  85. }
  86. public static Boolean isValidDate(String s) {
  87. if (s.length() != 19) {
  88. return Boolean.FALSE;
  89. }
  90. SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  91. try {
  92. dateFormat.parse(s);
  93. return Boolean.TRUE;
  94. } catch (Exception e) {
  95. return Boolean.FALSE;
  96. }
  97. }
  98. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/460440
推荐阅读
相关标签
  

闽ICP备14008679号