Springboot修改post請(qǐng)求接口入?yún)⒒蛑匦沦x值方式
前言
很久之前寫過一篇就是自動(dòng)填充接口參數(shù)的,利用的 HandlerMethodArgumentResolver 自定義注解
Springboot Controller接口默認(rèn)自動(dòng)填充 業(yè)務(wù)實(shí)體參數(shù)值
現(xiàn)在這一篇也差不多,達(dá)到的目的就是重新去給post請(qǐng)求的參數(shù)賦值、修改啥的。
不多說,開始。
首先知道一點(diǎn),post請(qǐng)求的參數(shù),一旦取出來就沒了,因?yàn)槭橇鲾?shù)據(jù)。
所以老樣子,我們寫多一個(gè)HttpServletRequestWrapper :
BodyReaderHttpServletRequestWrapper
import org.apache.commons.lang3.StringUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
/**
* @Author : JCccc
* @CreateTime : 2020/3/27
* @Description :
**/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
/**
* 所有參數(shù)的集合
*/
private Map<String, String[]> parameterMap;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
body = readBytes(reader);
parameterMap = request.getParameterMap();
}
@Override
public BufferedReader getReader() throws IOException {
ServletInputStream inputStream = getInputStream();
if (null == inputStream) {
return null;
}
return new BufferedReader(new InputStreamReader(inputStream));
}
@Override
public Enumeration<String> getParameterNames() {
Vector<String> vector = new Vector<>(parameterMap.keySet());
return vector.elements();
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (body == null) {
return null;
}
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
/**
* 通過BufferedReader和字符編碼集轉(zhuǎn)換成byte數(shù)組
*
* @param br
* @return
* @throws IOException
*/
private byte[] readBytes(BufferedReader br) throws IOException {
String str;
StringBuilder retStr = new StringBuilder();
while ((str = br.readLine()) != null) {
retStr.append(str);
}
if (StringUtils.isNotBlank(retStr.toString())) {
return retStr.toString().getBytes(StandardCharsets.UTF_8);
}
return null;
}
}然后是我們這一期的核心,
DefaultDataFillHandlerMethodArgumentResolver
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.speediance.admin.auth.ShiroUtils;
import com.speediance.admin.dto.req.UserDefaultDataFill;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.Date;
import java.util.Objects;
@Component
public class DefaultDataFillHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(UserDefaultDataFill.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest( HttpServletRequest.class );
BodyReaderHttpServletRequestWrapper myRequestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
// 從Request的包裝類中讀取數(shù)據(jù)
BufferedReader reader = myRequestWrapper.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
JSONObject jsonObject = JSON.parseObject(sb.toString());
Object bean = BeanUtils.instantiateClass(parameter.getParameterType());
BeanWrapper beanWrapper = new BeanWrapperImpl(bean);
//重新賦值
for (String key : jsonObject.keySet()) {
beanWrapper.setPropertyValue(key,jsonObject.get(key));
}
Long userId = //比如從數(shù)據(jù)庫(kù)查出來 或者從token解析出來;
//舉例子給如入?yún)⒆詣?dòng)填充 更新操作人
beanWrapper.setPropertyValue("updateUserId", userId);
return bean;
}
}然后就是重寫一個(gè)自定義注解 ,相當(dāng)于需要填充數(shù)據(jù)或者進(jìn)入到參數(shù)修改,我們采用它標(biāo)注:
UserDefaultDataFill
import java.lang.annotation.*;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserDefaultDataFill {
}然后就OK了,看看怎么用:
比如說一個(gè)更新接口,我們想默認(rèn)填充上入?yún)⒗锩娴?修改用戶ID (簡(jiǎn)單舉例,其余業(yè)務(wù)要修改值,賦值自己套用就可以)


然后可以看到我們的參數(shù)解析器里面的代碼 (其實(shí)就是復(fù)制流拿出參數(shù),修改完變成當(dāng)前接口的bean):

OK,就到這。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot POST請(qǐng)求接收多個(gè)參數(shù)值為null問題
- SpringBoot中Get請(qǐng)求和POST請(qǐng)求接收參數(shù)示例詳解
- 使用Springboot封裝好的發(fā)送post請(qǐng)求的工具類
- SpringBoot中如何處理不同的類型的POST請(qǐng)求
- SpringBoot使用@RestController處理GET和POST請(qǐng)求的代碼詳解
- vue2前端使用axios發(fā)起post請(qǐng)求后端(springboot)接收不到值解決辦法
- Springboot發(fā)送post請(qǐng)求的幾種方式總結(jié)
相關(guān)文章
Mybatis如何實(shí)現(xiàn)@Select等注解動(dòng)態(tài)組合SQL語(yǔ)句
這篇文章主要介紹了Mybatis如何實(shí)現(xiàn)@Select等注解動(dòng)態(tài)組合SQL語(yǔ)句,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
SpringCloud整合Netty集群實(shí)現(xiàn)WebSocket的示例代碼
文章主要介紹了SpringCloud整合Netty集群實(shí)現(xiàn)WebSocket的相關(guān)內(nèi)容,包括服務(wù)注冊(cè)和發(fā)現(xiàn)中心的配置,如使用Nacos、CommandLineRunner啟動(dòng)Netty服務(wù)等,還介紹了通過Redis實(shí)現(xiàn)消息發(fā)布訂閱的機(jī)制,需要的朋友可以參考下2024-11-11
SpringBoot+VUE實(shí)現(xiàn)數(shù)據(jù)表格的實(shí)戰(zhàn)
本文將使用VUE+SpringBoot+MybatisPlus,以前后端分離的形式來實(shí)現(xiàn)數(shù)據(jù)表格在前端的渲染,具有一定的參考價(jià)值,感興趣的可以了解一下2021-08-08
Java數(shù)據(jù)存儲(chǔ)的“雙子星”對(duì)決(Map和Set的區(qū)別)
文章主要介紹了Java中Map和Set兩種數(shù)據(jù)結(jié)構(gòu)的定義、實(shí)現(xiàn)、方法及應(yīng)用場(chǎng)景,Map用于存儲(chǔ)鍵值對(duì),鍵唯一,值可重復(fù);Set用于存儲(chǔ)唯一元素,無序,兩者都提供了豐富的操作方法,如添加、刪除、查找等,感興趣的朋友一起看看吧2025-02-02
Java中xxl-job實(shí)現(xiàn)分片廣播任務(wù)的示例
本文主要介紹了Java中xxl-job實(shí)現(xiàn)分片廣播任務(wù)的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03

