首页 > 编程语言 >Java替换RequstBody和RequestParam参数的属性

Java替换RequstBody和RequestParam参数的属性

时间:2024-09-01 08:52:41浏览次数:10  
标签:return RequstBody RequestParam springframework Java org import public String

Java替换RequstBody和RequestParam参数的属性

本文主要讲解在Java环境中如何替换RequestBody和RequestParam参数中的属性
背景
近期由于接手的老项目中存在所有接口中新增一个加密串来给接口做一个加密效果(项目历史原因,不方便上Jwt授权这套),所以就研究了一下Http请求链路,发现可以通过 javax.servlet.Filter去实现

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

package com.simplemessage.cloudpayservice.infrastructure.config.http;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**

  • @CreateAt: 2023/10/24 12:13

  • @ModifyAt: 2023/10/24 12:13

  • @Version 1.0
    */
    public class MyRequestWrapper extends HttpServletRequestWrapper {

    private Map params = new HashMap<>();
    public MyRequestWrapper(HttpServletRequest request, Map newParams) {
    super(request);
    if(request.getParameterMap() != null){
    this.params.putAll(request.getParameterMap());
    }
    if(newParams != null){
    this.params.putAll(newParams);
    }
    }

    /**

    • 获取参数
    • @return
      */
      @Override
      public Map getParameterMap() {
      return params;
      }

    @Override
    public Enumeration getParameterNames() {
    Vector l = new Vector(params.keySet());
    return l.elements();
    }

    @Override
    public String[] getParameterValues(String name) {
    Object v = params.get(name);
    if (v == null) {
    return null;
    } else if (v instanceof String[]) {
    return (String[]) v;
    } else if (v instanceof String) {
    return new String[]{(String) v};
    } else {
    return new String[]{v.toString()};
    }
    }

    /**

    • 根据参数的key获取参数
    • @param name
    • @return
      */
      @Override
      public String getParameter(String name) {
      Object v = params.get(name);
      if (v == null) {
      return null;
      } else if (v instanceof String[]) {
      String[] strArr = (String[]) v;
      if (strArr.length > 0) {
      return strArr[0];
      } else {
      return null;
      }
      } else if (v instanceof String) {
      return (String) v;
      } else {
      return v.toString();
      }
      }
      }
      package com.simplemessage.cloudpayservice.infrastructure.config.http;

import com.fasterxml.jackson.core.io.JsonEOFException;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.RequestFacade;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.FilterConfig;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**

  • @CreateAt: 2023/10/24 12:16
  • @ModifyAt: 2023/10/24 12:16
  • @Version 1.0
    */
    @Slf4j

@WebFilter(filterName = "replaceGetRequestFilter", urlPatterns = {"/*"})
public class ReplaceGetRequestFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    long start = System.currentTimeMillis();
    //获取HttpServletRequest对象
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    //判断当前是否为Get请求
    if ("GET".equalsIgnoreCase(httpServletRequest.getMethod())) {
    	// 获取参数信息
        String param= request.getParameter("param");
        //判断参数是否为空,为空则放行
        if (StringUtils.isEmpty(param)) {
            chain.doFilter(request, response);
            return;
        } else {
            Map<String, String[]> newParameterMap = new HashMap<>();
            // 替换参数(自定义规则)
            String newParama="test";
            newParameterMap.put("param", new String[]{newParama});
            // 实现参数替换
            MyRequestWrapper myRequestWrapper = new MyRequestWrapper(httpServletRequest, newParameterMap);
            chain.doFilter(myRequestWrapper, response);
        }

    } else {
        try {
            chain.doFilter(request, response);
        } catch (HttpMessageNotReadableException httpMessageNotReadableException) {
            log.error(((RequestFacade) request).getRequestURI() + ", " + httpMessageNotReadableException.getMessage());
        } catch (JsonEOFException jsonEOFException) {
            log.error(((RequestFacade) request).getRequestURI() + ", " + jsonEOFException.getMessage());
        }
    }
    long end = System.currentTimeMillis();
    log.info("{} 接口耗时:{} ms", httpServletRequest.getRequestURI(), (end - start));
}

@Override
public void destroy() {
}

}

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**

  • 注入bean
  • @CreateAt: 2023/10/30 9:57
  • @ModifyAt: 2023/10/30 9:57
  • @Version 1.0
    */

@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new ReplaceGetRequestFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}

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

package com.simplemessage.cloudpayservice.infrastructure.config.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.List;

/**

  • @version 1.0

  • @createAt: 2023/10/24 12:23:23

  • @modifyAt: 2023/10/24 12:23:23
    */
    @RestControllerAdvice
    @Slf4j
    public class DecryptRequestBodyHandler implements RequestBodyAdvice {

    /**

    • 该方法用于判断当前请求,是否要执行beforeBodyRead方法
    • methodParameter方法的参数对象
    • type方法的参数类型
    • aClass 将会使用到的Http消息转换器类类型
    • 注意:此判断方法,会在beforeBodyRead 和 afterBodyRead方法前都触发一次。
    • @return 返回true则会执行beforeBodyRead
      */

    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class> aClass) {
    return true;
    }
    //代码效果参考:http://www.intpipe.com/sitemap/post.xml
    /**

    • 在Http消息转换器执转换,之前执行

    • inputMessage 客户端请求的信息

    • parameter 参数信息

    • targetType 参数类型

    • converterType Http消息转换器类类型

    • @return 返回 一个自定义的HttpInputMessage
      */
      @Override
      public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) throws IOException {
      // 如果body是空内容直接返回原来的请求
      if (inputMessage.getBody().available() <= 0) {
      return inputMessage;
      }
      // 请求中的header信息
      HttpHeaders headers = inputMessage.getHeaders();

      // 将输入流读出来,注意 body 里面的流只能读一次
      ByteArrayOutputStream requestBodyDataByte = new ByteArrayOutputStream();
      try {
      //复制流信息
      IOUtils.copy(inputMessage.getBody(), requestBodyDataByte);
      } catch (Exception e) {
      log.error("参数流拷贝失败: ", e.toString());
      return inputMessage;
      }
      ByteArrayOutputStream requestBodyDataByteNew = null;
      try {
      JSONObject body = JSON.parseObject(requestBodyDataByte.toByteArray(), JSONObject.class);
      if (ObjectUtils.isEmpty(body)) {
      return inputMessage;
      }
      //自定义规则信息
      if (body.containsKey("param")) {
      String custId = body.getString("param");
      String newParam="";
      body.put("custId", newParam);
      requestBodyDataByteNew = new ByteArrayOutputStream();
      //拷贝流信息
      IOUtils.copy(new ByteArrayInputStream(body.toJSONString().getBytes()), requestBodyDataByteNew);
      }
      } catch (Throwable e) {
      log.error("流转换异常 ", e.toString());
      }
      // 如果上述发生异常,仍然使用原来的请求内容
      requestBodyDataByte = requestBodyDataByteNew != null ? requestBodyDataByteNew : requestBodyDataByte;
      InputStream rawInputStream = new ByteArrayInputStream(requestBodyDataByte.toByteArray());
      inputMessage.getHeaders().set(HttpHeaders.CONTENT_LENGTH, String.valueOf(rawInputStream.available()));
      return new HttpInputMessage() {
      @Override
      public HttpHeaders getHeaders() {
      return inputMessage.getHeaders();
      }

       @Override
       public InputStream getBody() throws IOException {
           return rawInputStream;
       }
      

      };
      }

    /**

    • 在Http消息转换器执转换,之后执行
    • body 转换后的对象
    • inputMessage 客户端的请求数据
    • parameter handler方法的参数类型
    • targetType handler方法的参数类型
    • converterType 使用的Http消息转换器类类型
    • @return 返回一个新的对象
      */
      @Override
      public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) {
      return body;
      }

    /**

    • 参数与afterBodyRead相同,不过这个方法body为空的情况
      */
      @Override
      public Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) {
      return body;
      }
      }

标签:return,RequstBody,RequestParam,springframework,Java,org,import,public,String
From: https://www.cnblogs.com/longshao2024/p/18391010

相关文章

  • Java 中的自增++和自减--运算符【小白必看】
    Java中的自增和自减运算符在学习Java编程语言时,自增(++)和自减(--)运算符是两个常见且基础的操作符。它们主要用于对变量进行简单的加减操作。以下我们将详细讲解这两个运算符的用法,并通过代码示例来帮助理解。1.自增运算符(++)自增运算符(++)用于将变量的值增加1。在Jav......
  • JavaScript中数组;JavaScript中对象及方法;笔记分享;知识回顾
    一,JS中数组数组创建4种语法:<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title></title><script>/*第一种......
  • JavaScript中DOW和BOW;笔记分享;知识回顾
    一,BOW1什么是BOWBOM是BrowserObjectModel的简写,即浏览器对象模型。BOM有一系列对象组成,是访问、控制、修改浏览器的属性的方法BOM没有统一的标准(每种客户端都可以自定标准)。BOM的顶层是window对象2,window对象及常用方法(1),什么是window对象Window对象描述:    ......
  • 【Java】Record的使用 (简洁教程)
    Java系列文章目录补充内容Windows通过SSH连接Linux第一章Linux基本命令的学习与Linux历史文章目录Java系列文章目录一、前言二、学习内容:三、问题描述四、解决方案:4.1为什么引入Record4.2Record与Class区别4.3使用场景五、总结:5.1场景使用5.2字段的定义......
  • 第四章 Java核心类库 第三节 集合框架
    1.集合框架概述与结构首先,我们来简单了解一下Java集合框架的概述和结构。集合框架的定义:Java集合框架是一组用来存储和操作数据集合的接口和类。它提供了一种统一的标准方法来操作不同的数据集合,极大简化了编程任务。集合框架的结构:集合框架包括三大主要接口:List接口:用......
  • Java基础(接口)
    目录为什么要有接口接口的定义接口的特点接口用interface定义定义接口类继承接口接口当中只能使用抽象方法接口类不能创建对象,只能用多态一个类可以继承多个接口实现接口中的方法接口和接口之间可以互相继承其他特点抽象类与接口的区别接口实例实例1Servlet......
  • java异常
    1.异常概念在程序中也是一样,程序猿是一帮办事严谨、追求完美的高科技人才。在日常开发中,绞尽脑汁将代码写的尽善尽美,在程序运行过程中,难免会出现一些奇奇怪怪的问题。有时通过代码很难去控制,比如:数据格式不对、网络不通畅、内存报警等。一位好的程序猿也要学习如何处理异常,完善......
  • 梁山县技工学校继续教育刷课脚本-JavaScript编写
    脚本学习网站:lsx.qzjystudy.com脚本地址:梁山县技工学校继续教育-刷课脚本教程1.插件安装(以MicrosoftEdge浏览器为例)打开最中间那个蓝色绿色的浏览器,谷歌之类的浏览器也可以点击屏幕右上角三个点,图示位置,然后点击扩展点击获取扩展搜索Tampermonkey,并点击获取那个绿......
  • Java毕设项目II基于Java的工厂车间管理系统设计与实现
    目录一、前言二、技术介绍三、系统实现四、论文参考五、核心代码六、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言随着工业4.0时代的到来,车间管理的智能化......
  • JAVAEE初阶第二节——多线程基础(上)
    系列文章目录JAVAEE初阶第二节——多线程基础(上)计算机的工作原理认识线程(Thread)Thread类及常见方法线程的状态文章目录系列文章目录JAVAEE初阶第二节——多线程基础(上)计算机的工作原理一.认识线程(Thread)1.概念1.1为啥要有线程1.2线程1.2.1线程如何解决......