使用SpringBoot使用過濾器去除@RequestBody參數兩端的空格
使用SpringBoot使用過濾器去除@RequestBody參數兩端的空格;一般我們去普通的請求我們都會對請求參數進行驗證。Java也提供了@notNull和@notBlank這種驗證方式,但是對@RequestBody 這種只能驗證是不是非空,對數據兩端的空格未進行處理,同時大家也不想遍歷一遍參數然后再處理再封裝到對象中,正好項目中有這個需要,所以就參考別的做了Post請求中針對application/json格式的有@RequestBody注解的參數進行了去空格處理
協議:CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0/
版權聲明:本文為原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
第一步:編寫一個配置信息
ParamsFilterConfig.java
package com.codepeople.framework.config;
import javax.servlet.DispatcherType;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.framework.filter.ParamsFilter;
/**
* @ClassName: ParamsFilterConfig
* @Description: SpringBoot中去除@RequestBody中前后端空格
* @Author 劉 仁
* @DateTime 2020-7-23 10:07:02
*/
@Configuration
public class ParamsFilterConfig {
@Bean
public FilterRegistrationBean paramsFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new ParamsFilter());
registration.addUrlPatterns("/*");
registration.setName("paramsFilter");
registration.setOrder(Integer.MAX_VALUE-1);
return registration;
}
}
第二步:編寫ParamsFilter過濾器
ParamsFilter.java
package com.codepeople.framework.filter;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
@Component
@WebFilter(urlPatterns = "/**", filterName = "ParamsFilter", dispatcherTypes = DispatcherType.REQUEST)
public class ParamsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ParameterRequestWrapper parmsRequest = new ParameterRequestWrapper((HttpServletRequest) request);
chain.doFilter(parmsRequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
第三步:實現ParameterRequestWrapper
ParameterRequestWrapper.java
package com.codepeople.framework.filter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import com.alibaba.fastjson.JSON;
import com.codepeople.framework.util.StringJsonUtils;
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map<String , String[]> params = new HashMap<>();
public ParameterRequestWrapper(HttpServletRequest request) {
// 將request交給父類,以便於調用對應方法的時候,將其輸出,其實父親類的實現方式和第一種new的方式類似
super(request);
//將參數表,賦予給當前的Map以便於持有request中的參數
Map<String, String[]> requestMap=request.getParameterMap();
this.params.putAll(requestMap);
this.modifyParameterValues();
}
/**
* 重寫getInputStream方法 post類型的請求參數必須通過流才能獲取到值
*/
@Override
public ServletInputStream getInputStream() throws IOException {
/** 非json類型,直接返回 */
if(!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)){
return super.getInputStream();
}
//為空,直接返回
String json = IOUtils.toString(super.getInputStream(), "utf-8");
if (StringUtils.isEmpty(json)) {
return super.getInputStream();
}
System.out.println("去除POST請求數據兩端的空格前參數:"+json);
Map<String,Object> map= StringJsonUtils.jsonStringToMap(json);
System.out.println("去除POST請求數據兩端的空格后參數:"+JSON.toJSONString(map));
ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8"));
return new MyServletInputStream(bis);
}
/**
* @Title: modifyParameterValues
* @Description: 將parameter的值去除空格后重寫回去
* @DateTime 2020-7-23 10:31:12
*/
public void modifyParameterValues(){
Set<String> set = params.keySet();
Iterator<String> it = set.iterator();
while(it.hasNext()){
String key= it.next();
String[] values = params.get(key);
values[0] = values[0].trim();
params.put(key, values);
}
}
@Override
public String getParameter(String name) {
String[]values = params.get(name);
if(values == null || values.length == 0) {
return null;
}
return values[0];
}
/**
* @Title: getParameterValues
* @Description: 重寫getParameterValues
* @DateTime 2020-7-23 10:31:12
*/
@Override
public String[] getParameterValues(String name) {//同上
return params.get(name);
}
class MyServletInputStream extends ServletInputStream{
private ByteArrayInputStream bis;
public MyServletInputStream(ByteArrayInputStream bis){
this.bis=bis;
}
@Override
public boolean isFinished() {
return true;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read(){
return bis.read();
}
}
}
第四步:利用fastjson實現json字符串轉map功能
package com.codepeople.framework.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* @ClassName: StringJsonUtils
* @Description:
* @Author 劉 仁
* @DateTime 2020-7-23 10:26:28
*/
public class StringJsonUtils {
/**
* @Title: jsonStringToMap
* @Description: 把jsonString轉為Map
* @Author 劉 仁
* @DateTime 2020-7-23 10:27:11
* @param jsonString
* @return
*/
public static Map<String, Object> jsonStringToMap(String jsonString) {
Map<String, Object> map = new HashMap<>();
JSONObject jsonObject = JSONObject.parseObject(jsonString);
for (Object k : jsonObject.keySet()) {
Object o = jsonObject.get(k);
if (o instanceof JSONArray) {
List<Map<String, Object>> list = new ArrayList<>();
Iterator<Object> it = ((JSONArray) o).iterator();
while (it.hasNext()) {
Object obj = it.next();
list.add(jsonStringToMap(obj.toString()));
}
map.put(k.toString(), list);
} else if (o instanceof JSONObject) {
// 如果內層是json對象的話,繼續解析
map.put(k.toString(), jsonStringToMap(o.toString()));
} else {
// 如果內層是普通對象的話,直接放入map中
// map.put(k.toString(), o.toString().trim());
if (o instanceof String) {
map.put(k.toString(), o.toString().trim());
} else {
map.put(k.toString(), o);
}
}
}
return map;
}
}
主要引入的包
<!--常用工具類 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- io常用工具類 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
測試日志
11:28:07.995 [http-nio-80-exec-17] INFO c.r.f.f.ParameterRequestWrapper - [getInputStream,54] - 去除POST請求數據兩端的空格前參數:{
"idNumber": "110101201003073036",
"password": " 123456 "
}
11:28:07.997 [http-nio-80-exec-17] INFO c.r.f.f.ParameterRequestWrapper - [getInputStream,56] - 去除POST請求數據兩端的空格后參數:{"password":"123456","idNumber":"110101201003073036"}
博客地址:https://www.codepeople.cn
=====================================================================
微信公眾號: