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 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 HttpMessageConve服务器托管网rter>> 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() > converterType) {
return body;
}
/**
* 参数与afterBodyRead相同,不过这个方法body为空的情况
*/
@Override
public Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) {
return body;
}
}
如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net