最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring boot 自定義參數(shù)過濾器,把傳入的空字符轉換成null方式

 更新時間:2021年08月28日 10:21:53   作者:Orgin5  
這篇文章主要介紹了spring boot 自定義參數(shù)過濾器,把傳入的空字符轉換成null方式。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

spring boot 濾器,把傳入的空字符轉換成null

廢話不多說直接上代碼

自定義參數(shù)處理器

public class MyStringArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
    @Override
    protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
        return  new NamedValueInfo("", false, ValueConstants.DEFAULT_NONE);
    }
    @Override
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
        String[] param = request.getParameterValues(name);
        if(param==null){
            return null;
        }
        if(StringUtils.isEmpty(param[0])){
            return null;
        }
        return param[0];
    }
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(String.class);
    }
}

應用啟動類

public class Applicaction extends WebMvcConfigurerAdapter {
    public static void main(String[] ags) {
        SpringApplication.run(Applicaction.class, ags);
    }
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new MyStringArgumentResolver());
    }
}

springboot過濾器對請求參數(shù)去空格處理

測試人員提出,對所有接口的請求參數(shù)去空格處理。 因為接口比較多,所以考慮使用spring mvc的攔截器來實現(xiàn),但是使用攔截器能獲取到請求參數(shù),卻無法將修改后的參數(shù)返給HttpServletRequest 對象。

HttpServletRequest 提供的獲取參數(shù)的方法:

String getParameter(String name);//鍵值對參數(shù)
Map<String,String[]> getParameterMap();//鍵值對參數(shù)
Enumeration <String> getParameterNames();//鍵值對參數(shù)
String[] getParameterValues(String name);//鍵值對參數(shù)
ServletInputStream getInputStream();// 文本參數(shù),例如類型 application/json 等
BufferedReader getReader(); //文本參數(shù),例如類型 application/json 等
Collection<Part> getParts();//表單提交, multipart/form-data 

之后考慮使用過濾器,在網上找到了方案。使用自定義Request對象繼承HttpServletRequestWrapper,獲取從過濾器傳入的HttpServletRequest對象提取參數(shù),并重寫HttpServletRequestWrapper獲取參數(shù)的方法。

springboot添加過濾器有兩種方式:

  • 1、通過創(chuàng)建FilterRegistrationBean的方式
  • 2、 使用@WebFilter

在spring中這些過濾器的創(chuàng)建都需要交給spring容器管理

使用 FilterRegistrationBean 注冊過濾器

1、封裝request對象實體

繼承HttpServletRequestWrapper 類用于擴展request。同時如果修改了原來request中參數(shù)內容,需要將其修改后的數(shù)據返回,所以需要重寫獲取參數(shù)的方法。

	package com.demo.springBootProject;	
	import java.io.ByteArrayInputStream;
	import java.io.IOException;
	import java.io.InputStream;
	import java.util.Enumeration;
	import java.util.HashMap;
	import java.util.Map;
	import java.util.Map.Entry;
	import java.util.Set;
	import java.util.Vector;
	import javax.servlet.ReadListener;
	import javax.servlet.ServletInputStream;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletRequestWrapper;
	import org.apache.http.entity.ContentType;
	import org.apache.poi.util.IOUtils;
	
	/**
	 *重新封裝request,并對請求參數(shù)做去空格處理
	 */
	public class ParameterTrimRequest  extends HttpServletRequestWrapper{
	
		 private Map<String, String[]> params = new HashMap<String, String[]>();//保存處理后的參數(shù)			
		 private byte[] content; 
		 
		    public ParameterTrimRequest(HttpServletRequest request) {
		        super(request);
		        this.params.putAll(request.getParameterMap());
		        this.modifyParameterValues(); //自定義方法,用于參數(shù)去重
		        if(ContentType.APPLICATION_JSON.getMimeType().equals(request.getContentType())){//對application/json數(shù)據格式的數(shù)據進行去空格處理
		        	this.content=IOUtils.toByteArray(request.getInputStream());//獲取文本數(shù)據;
					// 對json字符串進行處理	
					//....................
		        	}
		    }
		 
			public void modifyParameterValues() {//將parameter的值去除空格后重寫回去
				Set<Entry<String,String[]>> entrys=params.entrySet();
				for(Entry<String,String[]> entry :entrys) {
					String[] values=entry.getValue();
					for(int i=0;i<values.length;i++) {
						values[i] = values[i].trim();
					}
					this.params.put(entry.getKey(), values);
				}
		    }
		 
		    @Override
		    public Enumeration<String> getParameterNames() {//重寫getParameterNames()
		        return new Vector<String>(params.keySet()).elements();
		    }
		    
		    
		    @Override
		    public String getParameter(String name) {//重寫getParameter()
		        String[] values = params.get(name);
		        if (values == null || values.length == 0) {
		            return null;
		        }
		        return values[0];
		    }
		    
		    @Override
		    public String[] getParameterValues(String name) {//重寫getParameterValues()
		        return params.get(name);
		    }
		    
		   @Override
		   public Map<String,String[]> getParameterMap(){ //重寫getParameterMap()
			   return this.params;
		   }
		@Override  
  		public ServletInputStream getInputStream() throws IOException {  
      	//  這種獲取的參數(shù)的方式針對于內容類型為文本類型,比如Content-Type:text/plain,application/json,text/html等
      	//在springmvc中可以使用@RequestBody 來獲取 json數(shù)據類型
  	 	//其他文本類型不做處理,重點處理json數(shù)據格式
			if(!super.getHeader("Content-Type").equalsIgnoreCase("application/json")){  
            	   return super.getInputStream();  
        	 }else{
        	 //根據自己的需要重新指定方法
        	 	ByteArrayInputStream in =new ByteArrayInputStream(this.content);
				return new ServletInputStream() {
					@Override
					public int read() throws IOException {
						return in.read();
					}
					
					@Override
					public int read(byte[] b, int off, int len) throws IOException {
						return in.read(b, off, len);
					}
	
					@Override
					public int read(byte[] b) throws IOException {
						return in.read(b);
					}
					
					@Override
					public void setReadListener(ReadListener listener) {
					}
					
					@Override
					public boolean isReady() {
						return false;
					}
					
					@Override
					public boolean isFinished() {
						return false;
					}
	
					@Override
					public long skip(long n) throws IOException {
						return in.skip(n);
					}
	
					@Override
					public void close() throws IOException {
						in.close();
					}
	
					@Override
					public synchronized void mark(int readlimit) {
						in.mark(readlimit);
					}
	
					@Override
					public synchronized void reset() throws IOException {
						in.reset();
					}
					};
        	 }  
     	} 			
	}

返回結果是一個ServletInputStream它是InputStream的子類,因為沒有重寫reset方法,所以該字節(jié)流只能被獲取一次。所以如果需要對表單提交的json參數(shù)處理,則getInputStream()方法需要重寫。網上比較流行的做法是,將字節(jié)數(shù)據保存,然后封裝成字節(jié)流。

ServletRequest 源碼中獲取字節(jié)流和字符流的方法

/**
*  Either this method or {@link #getInputStream} may be called to read the body, not both.
*  @exception IllegalStateException
*       if {@link #getInputStream} method has been called on this request
**/
public ServletInputStream getInputStream() throws IOException;
public BufferedReader getReader() throws IOException;

getInputSteam和getReader()方法是互斥的,只能調用一次。同時調用會拋出異常 IllegalStateException。

getInputSteam 方法重寫最好限定數(shù)據類型。比如說文本類型(application/json,text/plain)。

對于Multipart/form-data提交類型,Tomcat會先調用了getInputStream方法獲取請求體中的數(shù)據。

//Request.class      parseParameters
 if ("multipart/form-data".equals(contentType)) {
                parseParts(false);
                success = true;
                return;
   }

這樣在后邊再使用getInputSteam方法流中的數(shù)據就已經被讀取完了。如果再不小心調用了getReader 方法 ,就會拋出異常。

java.lang.IllegalStateException: getInputStream() has already been called for this request

:::本地測試的結果,在filter中和spring mvc的攔截器中可以反復獲取流數(shù)據。但是在controller中無法獲取到空數(shù)據,很疑惑。 最后發(fā)現(xiàn)導錯包了 【苦笑】

2、自定義過濾器

package com.demo.springBootProject.filter;
import java.io.IOException;
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.http.HttpServletRequest;
/**
 * 自定義過濾器,用于對請求參數(shù)去空格處理。
 */
public class ParameterTrimFilter implements Filter{
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		ParameterTrimRequest trimReqeust= new ParameterTrimRequest((HttpServletRequest)request);
		chain.doFilter(trimReqeust, response);
	}
	@Override
	public void destroy() {
	}
}

3、創(chuàng)建Java配置類

有多個filter就創(chuàng)建多個FilterRegistrationBean ,若需注明filter的執(zhí)行順序,可通過registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE )配置,值越大,執(zhí)行順序越靠后

package com.demo.springBootProject.config;
import java.util.ArrayList;
import java.util.List;
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.demo.springBootProject.filter.ParameterTrimFilter;
/**
 * 用于添加自定義的bean
 */
@Configuration
public class CustomBean {
	/**
	 *該過濾器用于對請求參數(shù)做去空格處理
	 *@return FilterRegistrationBean<ParameterTrimFilter>
	 */
	@Bean(name="parameterTrimFilter") //不寫name屬性,默認beanName為方法名
	public FilterRegistrationBean<ParameterTrimFilter> parameterTrimFilter() {
		FilterRegistrationBean<ParameterTrimFilter> filter=new FilterRegistrationBean<>();
		filter.setDispatcherTypes(DispatcherType.REQUEST);  
		filter.setFilter(new ParameterTrimFilter()); //必須設置
		filter.addUrlPatterns("/*"); //攔截所有請求,如果沒有設置則默認“/*”
		filter.setName("parameterTrimFilter"); //設置注冊的名稱,如果沒有指定會使用Bean的名稱。此name也是過濾器的名稱
		filter.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);//該filter在filterChain中的執(zhí)行順序
		return filter;
	}
}

注意: 以上配置類所在包或者過濾器所在包必須在spring boot注解可以掃描的包或者子包下。如果springboot沒有設置掃描包,則springboot會掃描啟動類所在的包及其子包。

FilterRegistrationBean提供了多種方式來注冊攔截的請求。

 void addUrlPatterns(String... urlPatterns)//向filter追加注冊url
 void setUrlPatterns(Collection<String> urlPatterns)//覆蓋之前已注冊的url
 void addServletNames(String... servletNames)// 添加過濾的servletName
 void setServletNames(Collection<String> servletNames)//覆蓋之前的攔截的servletName

攔截url和攔截servlet可以一起使用

使用@WebFilter注冊過濾器

package com.demo.springBootProject.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebFilter(filterName="test",urlPatterns= {"/*"})
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
		//doSomthing
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() {
	}
}

增加JSON字符串的處理

以上處理的是簡單的數(shù)據類型,如果是json字符串,應當先解析json字符串,將其中的value字符串前后去空格。可以參考以下代碼處理。

     public static void main(String[] args) {
               String str = "[\" 1\" ,\"2  \",\"4  \"]";
//        str = "{\"name\":\"張三  \"}";
//        str = "{\"name\":  {\"first_name\": \"張  \",\"last_name\":\"  三  \"}}";
        str = "[{'name':'  張三  '},{'name':'  李四  '},{'name':19}]";
       
        Object jsonObj = JSON.parse(str);
        if (jsonObj instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) jsonObj;
            parseJsonObject(jsonObject);
        } else if (jsonObj instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) jsonObj;
            parseJSONArray(jsonArray);
        }
        System.out.println(jsonObj);
    }
    public static void parseJsonObject(JSONObject jsonObject) {
        Set<String> keySet = jsonObject.keySet();
        for (String key : keySet) {
            parseObject(jsonObject, key);
        }
    }
    public static void parseJSONArray(JSONArray jsonArray) {
        if (jsonArray == null || jsonArray.isEmpty()) {
            return;
        }
        for (int i = 0; i < jsonArray.size(); i++) {
            parseArray(jsonArray, i);
        }
    }
    public static void parseObject(JSONObject jsonObject, String key) {
        Object keyObj = jsonObject.get(key);
        if (keyObj == null) {
            return;
        }
        if (keyObj instanceof String) {
            jsonObject.put(key, ((String) keyObj).trim());
        } else if (keyObj instanceof JSONObject) {
            //解析json 對象
            parseJsonObject(((JSONObject) keyObj));
        } else if (keyObj instanceof JSONArray) {
            //解析json 數(shù)組
            parseJSONArray(((JSONArray) keyObj));
        }
    }
    public static void parseArray(JSONArray jsonArray, int index) {
        Object keyObj = jsonArray.get(index);
        if (keyObj == null) {
            return;
        }
        if (keyObj instanceof String) {
            jsonArray.set(index, ((String) keyObj).trim());
        } else if (keyObj instanceof JSONObject) {
            //解析json 對象
            parseJsonObject(((JSONObject) keyObj));
        } else if (keyObj instanceof JSONArray) {
            //解析json 數(shù)組
            parseJSONArray(((JSONArray) keyObj));
        }
    }

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • JVM自定義類加載器在代碼擴展性實踐分享

    JVM自定義類加載器在代碼擴展性實踐分享

    這篇文章主要介紹了JVM自定義類加載器在代碼擴展性實踐分享,一個類型從被加載到虛擬機內存中開始,到卸載出內存為止,它的整個生命周期將會經歷加載、驗證、準備、解析、初始化 、使用和卸載七個階段,其中驗證、準備、解析三個部分統(tǒng)稱為連接
    2022-06-06
  • SpringBoot?web靜態(tài)資源映射實現(xiàn)步驟詳解

    SpringBoot?web靜態(tài)資源映射實現(xiàn)步驟詳解

    在springBoot中的靜態(tài)資源的映射是通過SpringMVC中的resourceHttpRequestHandler來進行實現(xiàn)的。在該請求映射器中默認規(guī)定了,SpringBoot會將classPath或者ServletContext下的/static?(/public、/resources?或?/META-INF/resources)目錄中,存放靜態(tài)資源
    2022-09-09
  • java double類型相加精度問題的解決

    java double類型相加精度問題的解決

    這篇文章主要介紹了java double類型相加精度問題的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Nacos集群模式下服務無法注冊問題

    Nacos集群模式下服務無法注冊問題

    這篇文章主要介紹了Nacos集群模式下服務無法注冊問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • MyBatis動態(tài)SQL中的trim標簽的使用方法

    MyBatis動態(tài)SQL中的trim標簽的使用方法

    這篇文章主要介紹了MyBatis動態(tài)SQL中的trim標簽的使用方法,需要的朋友可以參考下
    2017-05-05
  • Spring MVC請求參數(shù)與響應結果全局加密和解密詳解

    Spring MVC請求參數(shù)與響應結果全局加密和解密詳解

    這篇文章主要給大家介紹了關于Spring MVC請求參數(shù)與響應結果全局加密和解密的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • 在Java中String和Date、Timestamp之間的轉換

    在Java中String和Date、Timestamp之間的轉換

    這篇文章主要介紹了在Java中String和Date、Timestamp之間的轉換 的相關資料,需要的朋友可以參考下
    2015-12-12
  • Java中csv文件讀寫超詳細分析

    Java中csv文件讀寫超詳細分析

    CSV是一種通用的、相對簡單的文件格式,其文件以純文本形式存儲表格數(shù)據,下面這篇文章主要給大家介紹了關于Java中csv文件讀寫分析的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • SpringCloud的那些中間件問題

    SpringCloud的那些中間件問題

    這篇文章主要介紹了SpringCloud的那些中間件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 分布式醫(yī)療掛號系統(tǒng)SpringCache與Redis為數(shù)據字典添加緩存

    分布式醫(yī)療掛號系統(tǒng)SpringCache與Redis為數(shù)據字典添加緩存

    這篇文章主要為大家介紹了分布式醫(yī)療掛號系統(tǒng)SpringCache與Redis為數(shù)據字典添加緩存,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04

最新評論

玉龙| 开化县| 咸宁市| 上高县| 馆陶县| 高安市| 城市| 黑河市| 临沭县| 丰顺县| 乌兰浩特市| 八宿县| 恭城| 张家界市| 通江县| 大关县| 当阳市| 信宜市| 密云县| 碌曲县| 来宾市| 巴彦县| 原阳县| 龙泉市| 尼勒克县| 榕江县| 兰西县| 马龙县| 陕西省| 龙江县| 宜兴市| 鄱阳县| 澄江县| 宜州市| 桃园市| 商都县| 北京市| 洪湖市| 隆尧县| 崇礼县| 五峰|