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

Java替换RequestBody和RequestParam参数的属性

时间:2023-10-24 17:03:20浏览次数:35  
标签:Java String RequestParam java return RequestBody org import public

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.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
@Component
@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", 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() {
    }
}

替换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<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    /**
     * 在Http消息转换器执转换,之前执行
     * inputMessage 客户端请求的信息
     * parameter 参数信息
     * targetType 参数类型
     * converterType Http消息转换器类类型
     *
     * @return 返回 一个自定义的HttpInputMessage
     */
    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> 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<? extends HttpMessageConverter<?>> converterType) {
        return body;
    }

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


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

标签:Java,String,RequestParam,java,return,RequestBody,org,import,public
From: https://www.cnblogs.com/ancold/p/17785227.html

相关文章

  • 关于Windows打印机驱动相关问题-如何利用Java(或其他)调用打印机驱动程序完成原始文件翻
    前面这些都是问题描述,问题在偏下面场景:用户电脑上安装了PCL驱动,可通过驱动完成打印。需求:现在需要提供一种脱离PC端完成文件上传并打印的功能。让用户使用手机或pc未安装驱动时都能打印文件。目前思路:首先上传文件这一步没有任何问题,开发了相应的H5界面,通过浏览器进行原始文件......
  • 如何用Java找出两个List中的重复元素,读这一篇就够了
     在Java编程中,我们经常需要找出两个列表(List)中的重复元素。在本文中,我们将探讨三种方法来实现这一目标。 方法一:使用HashSetJava中的HashSet是一个不允许有重复元素的集合。我们可以利用这个特性,通过合并两个List并计算差集,来找出重复的元素。以下是一个通过使用HashSet数......
  • [VM] The JavaScript Virtual Machine
    TableofContentIntroudctiontoVMsCPU-UnderstandingthePysicalMachineVMs-Arrays,Objects,functions,prototypechainsDepotExplorer:collectingdatafromtheVMDeopt:CallingCoventions&InliningMegamohpism&InlineCache:Objectpro......
  • Java ConcurrentModificationException异常原因和解决方法
    JavaConcurrentModificationException异常原因和解决方法JavaConcurrentModificationException异常原因和解决方法在前面一篇文章中提到,对Vector、ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常。下面我们就来讨论以......
  • java动态创建es 及mapping
    publicCreateIndexResponsecreateIndexWithMapping(Stringindex,Map<String,String>mapping){CreateIndexResponseresponse=null;try{CreateIndexRequestrequest=newCreateIndexRequest(index);request.settings(Settings.b......
  • Java中的NumberFormatException异常常见原因是什么?
    Java中的NumberFormatException异常常见原因是什么?Java中的NumberFormatException是一种常见的异常,它通常在字符串转换成数值类型时发生。本文将探讨NumberFormatException异常的原因及解决方法。引起NumberFormatException异常的原因:字符串转换成数值类型时格式错误。例如,对于......
  • Linux配置java和maven环境变量
    修改/etc/profile文件,新增如下代码exportJAVA_HOME=/usr/local/btjdk/jdk8exportCLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarexportPATH=$PATH:$JAVA_HOME/binexportM2_HOME=/usr/local/maven/apache-maven-3.9.4exportPATH=$PATH:$M2_HOME/bin刷新/etc/prof......
  • JavaScript在发送AJAX请求时,URL的域名地址是使用绝对地址还是相对地址?
    在使用JavaScript发送AJAX请求时,URL的域名地址通常是使用相对地址。相对地址指的是相对于当前页面的URL来确定请求的目标地址。当请求发送到服务器时,浏览器会自动将相对地址转换为完整的绝对URL。这样做的好处是能够更灵活地处理不同环境下的URL路径,同时减少了在JavaScript代码中......
  • Java List 排序的2种方法
    1. 利用Collections类的java.util.Collections.sort(java.util.List,java.util.Comparator)方法,自定义比较器对象对指定对象进行排序对学生对象按照其分数(降序)进行排序,当分数相同时按学号(从小到大)排序,代码如下:Student类classStudent{ privateintid; privateStringname......
  • Java HashMap类
    HashMap是我们使用非常多的Collection,它是基于哈希表的Map接口的实现,以key-value的形式存在。HashMap实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该......