springboot清除字符串前后空格與防xss攻擊方法
springboot清除字符串前后空格與防xss攻擊
一、查看WebMvcAutoConfiguration.class中的方法源碼
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
try {
//從容器中獲取
return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
} catch (NoSuchBeanDefinitionException ex) {
return super.getConfigurableWebBindingInitializer();
}
可以發(fā)現(xiàn)ConfigurableWebBindingInitializer是從容器(beanFactory)中獲取到的,所以我們可以配置一個(gè)
ConfigurableWebBindingInitializer來替換默認(rèn)的,只需要在容器中添加一個(gè)我們自定義的轉(zhuǎn)換器即可。
當(dāng)我們創(chuàng)建了自己的ConfigurableWebBindingInitializer這個(gè)Bean,Spring boot就會(huì)自動(dòng)使用它來配置Spring MVC實(shí)現(xiàn)參數(shù)的類型轉(zhuǎn)換。
二、自定義屬性編輯器
/**
*
* @description 與spring mvc的@InitBinder結(jié)合 用于防止XSS攻擊
*/
class StringEscapeEditor extends PropertyEditorSupport {
/** 轉(zhuǎn)義HTML */
private boolean escapeHTML;
/** 轉(zhuǎn)義javascript */
private boolean escapeJavaScript;
/** 是否將空字符串轉(zhuǎn)換為null */
private final boolean emptyAsNull;
/** 是否去掉前后空格 */
private final boolean trimmed;
public StringEscapeEditor() {
this(true,true,false,true);
}
public StringEscapeEditor(boolean escapeHTML, boolean escapeJavaScript) {
this(true,true,escapeHTML,escapeJavaScript);
}
public StringEscapeEditor(boolean emptyAsNull,boolean trimmed, boolean escapeHTML, boolean escapeJavaScript) {
super();
this.emptyAsNull = emptyAsNull;
this.trimmed = trimmed;
this.escapeHTML = escapeHTML;
this.escapeJavaScript = escapeJavaScript;
}
@Override
public String getAsText() {
Object value = getValue();
if(Objects.nonNull(value))
{
return value.toString();
}
return value != null ? value.toString() : null;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
String value = text;
if (value == null || emptyAsNull && text.isEmpty()) {
//do nothing
} else if (trimmed) {
//去字符傳參數(shù)前后空格
value = value.trim();
}
if (escapeHTML) {
//HTML轉(zhuǎn)義(防止XSS攻擊)
//HtmlUtils.htmlEscape 默認(rèn)的是ISO-8859-1編碼格式,會(huì)將中文的某些符號(hào)進(jìn)行轉(zhuǎn)義。
//如果不想讓中文符號(hào)進(jìn)行轉(zhuǎn)義請(qǐng)使用UTF-8的編碼格式。例如:HtmlUtils.htmlEscape(text, "UTF-8")
value = HtmlUtils.htmlEscape(value, "UTF-8");
}
if (escapeJavaScript) {
//javascript轉(zhuǎn)義(防止XSS攻擊)
value = JavaScriptUtils.javaScriptEscape(value);
}
setValue(value);
}
}
三、創(chuàng)建WebBindingInitializerConfiguration類
加上@Bean注解,交給spring容器管理。
@Configuration
public class WebBindingInitializerConfiguration {
@Bean
public ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
FormattingConversionService conversionService = new DefaultFormattingConversionService();
//we can add our custom converters and formatters
//conversionService.addConverter(...);
//conversionService.addFormatter(...);
initializer.setConversionService(conversionService);
//we can set our custom validator
//initializer.setValidator(....);
//here we are setting a custom PropertyEditor
initializer.setPropertyEditorRegistrar(propertyEditorRegistry -> {
propertyEditorRegistry.registerCustomEditor(String.class,
new StringEscapeEditor());
});
return initializer;
}
}
springboot去除參數(shù)中前后空格說明
一、 需求
使用SpringBoot使用過濾器去除@RequestBody參數(shù)兩端的空格;一般我們?nèi)テ胀ǖ恼?qǐng)求我們都會(huì)對(duì)請(qǐng)求參數(shù)進(jìn)行驗(yàn)證。
Java也提供了@notNull和@notBlank這種驗(yàn)證方式,但是對(duì)@RequestBody 這種只能驗(yàn)證是不是非空,對(duì)數(shù)據(jù)兩端的空格未進(jìn)行處理,同時(shí)大家也不想遍歷一遍參數(shù)然后再處理再封裝到對(duì)象中,正好項(xiàng)目中有這個(gè)需要,所以就參考別的做了Post請(qǐng)求中針對(duì)application/json格式的有@RequestBody注解的參數(shù)進(jìn)行了去空格處理
二、 解決方法
2.1 新建一個(gè)過濾器
@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() {
}
}
2.2 實(shí)現(xiàn)ParameterRequestWrapper
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
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 com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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;
/**
* @author :
* @description
* @date : 2021/4/22
*/
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map<String , String[]> params = new HashMap<>();
public ParameterRequestWrapper(HttpServletRequest request) {
super(request);
Map<String, String[]> requestMap=request.getParameterMap();
this.params.putAll(requestMap);
this.modifyParameterValues();
}
@Override
public ServletInputStream getInputStream() throws IOException {
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();
}
Map<String,Object> map= jsonStringToMap(json);
ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8"));
return new MyServletInputStream(bis);
}
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];
}
@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();
}
}
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) {
map.put(k.toString(), jsonStringToMap(o.toString()));
} else {
if (o instanceof String) {
map.put(k.toString(), o.toString().trim());
} else {
map.put(k.toString(), o);
}
}
}
return map;
}
}
三、 完美解決

參數(shù)前后空格完美去除!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
Java實(shí)現(xiàn)數(shù)據(jù)脫敏的方法詳細(xì)講解
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)數(shù)據(jù)脫敏的相關(guān)資料,數(shù)據(jù)脫敏是指對(duì)某些敏感信息通過脫敏規(guī)則進(jìn)行數(shù)據(jù)的變形,實(shí)現(xiàn)敏感隱私數(shù)據(jù)的可靠保護(hù),需要的朋友可以參考下2023-06-06
IntelliJ Idea 2020.1 正式發(fā)布,官方支持中文(必看)
這篇文章主要介紹了IntelliJ Idea 2020.1 正式發(fā)布,官方支持中文了,本文通過截圖的形式給大家展示,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
一篇文章帶你了解mybatis的動(dòng)態(tài)SQL
這篇文章主要為大家介紹了mybatis的動(dòng)態(tài)SQL?,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01
淺談java 字符串,字符數(shù)組,list間的轉(zhuǎn)化
下面小編就為大家?guī)硪黄獪\談java 字符串,字符數(shù)組,list間的轉(zhuǎn)化。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11

