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)義請使用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)テ胀ǖ恼埱笪覀兌紩?huì)對(duì)請求參數(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請求中針對(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)文章
Spring Boot整合tk.mybatis代碼實(shí)例
這篇文章主要介紹了Spring Boot整合tk.mybatis代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11Java基于正則表達(dá)式獲取指定HTML標(biāo)簽指定屬性值的方法
這篇文章主要介紹了Java基于正則表達(dá)式獲取指定HTML標(biāo)簽指定屬性值的方法,涉及java基于正則的HTML元素匹配相關(guān)操作技巧,需要的朋友可以參考下2017-01-01Rabbitmq延遲隊(duì)列實(shí)現(xiàn)定時(shí)任務(wù)的方法
這篇文章主要介紹了Rabbitmq延遲隊(duì)列實(shí)現(xiàn)定時(shí)任務(wù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05SSM框架使用poi導(dǎo)入導(dǎo)出Excel的詳細(xì)方法
這篇文章主要介紹了SSM框架使用poi導(dǎo)入導(dǎo)出Excel,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03SpringMVC項(xiàng)目異常處理機(jī)制詳解
SpringMVC是一種基于Java,實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式,請求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦?;谡埱篁?qū)動(dòng)指的就是使用請求-響應(yīng)模型,框架的目的就是幫助我們簡化開發(fā),SpringMVC也是要簡化我們?nèi)粘eb開發(fā)2022-08-08