Springboot修改post請(qǐng)求接口入?yún)⒒蛑匦沦x值方式
前言
很久之前寫過(guò)一篇就是自動(dòng)填充接口參數(shù)的,利用的 HandlerMethodArgumentResolver 自定義注解
Springboot Controller接口默認(rèn)自動(dòng)填充 業(yè)務(wù)實(shí)體參數(shù)值
現(xiàn)在這一篇也差不多,達(dá)到的目的就是重新去給post請(qǐng)求的參數(shù)賦值、修改啥的。
不多說(shuō),開(kāi)始。
首先知道一點(diǎn),post請(qǐng)求的參數(shù),一旦取出來(lái)就沒(méi)了,因?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();
}
};
}
/**
* 通過(guò)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ù)查出來(lái) 或者從token解析出來(lái);
//舉例子給如入?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了,看看怎么用:
比如說(shuō)一個(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問(wèn)題
- 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)文章
解決Request.getParameter獲取不到特殊字符bug問(wèn)題
這篇文章主要介紹了解決Request.getParameter獲取不到特殊字符bug問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
JavaFx 中創(chuàng)建計(jì)時(shí)器的步驟詳解
本文介紹了如何在JavaFx中創(chuàng)建計(jì)時(shí)器,通過(guò)創(chuàng)建計(jì)時(shí)器界面、編寫計(jì)時(shí)器邏輯以及關(guān)聯(lián)計(jì)時(shí)器按鈕,我們可以快速實(shí)現(xiàn)一個(gè)靈活可靠的計(jì)時(shí)器組件,本文能夠幫助讀者在 JavaFx 中成功實(shí)現(xiàn)自己的計(jì)時(shí)器功能,感興趣的朋友一起看看吧2023-11-11
Spring Data JPA實(shí)現(xiàn)動(dòng)態(tài)條件與范圍查詢實(shí)例代碼
本篇文章主要介紹了Spring Data JPA實(shí)現(xiàn)動(dòng)態(tài)條件與范圍查詢實(shí)例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-06-06
Java使用責(zé)任鏈模式處理學(xué)生請(qǐng)假問(wèn)題詳解
這篇文章主要介紹了Java使用責(zé)任鏈模式處理學(xué)生請(qǐng)假問(wèn)題,結(jié)合實(shí)例形式詳細(xì)分析了責(zé)任鏈模式的概念、原理及Java使用責(zé)任鏈模式處理學(xué)生請(qǐng)假問(wèn)題的相關(guān)步驟、操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-04-04
MybatisPlus批量保存原理及失效原因排查全過(guò)程
這篇文章主要介紹了MybatisPlus批量保存原理及失效原因排查全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
maven項(xiàng)目連接MySQL方式(使用原生的jdbc)
文章介紹了如何在項(xiàng)目中添加依賴、組織目錄結(jié)構(gòu)、配置數(shù)據(jù)庫(kù)連接屬性以及編寫工具類,并分享了個(gè)人經(jīng)驗(yàn),鼓勵(lì)讀者參考和支持腳本之家2026-03-03
Java時(shí)區(qū)轉(zhuǎn)換實(shí)例代碼解析
這篇文章主要介紹了Java時(shí)區(qū)轉(zhuǎn)換實(shí)例代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03

