欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

廢話不多說直接上代碼

自定義參數處理器

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過濾器對請求參數去空格處理

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

HttpServletRequest 提供的獲取參數的方法:

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

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

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

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

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

使用 FilterRegistrationBean 注冊過濾器

1、封裝request對象實體

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

	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,并對請求參數做去空格處理
	 */
	public class ParameterTrimRequest  extends HttpServletRequestWrapper{
	
		 private Map<String, String[]> params = new HashMap<String, String[]>();//保存處理后的參數			
		 private byte[] content; 
		 
		    public ParameterTrimRequest(HttpServletRequest request) {
		        super(request);
		        this.params.putAll(request.getParameterMap());
		        this.modifyParameterValues(); //自定義方法,用于參數去重
		        if(ContentType.APPLICATION_JSON.getMimeType().equals(request.getContentType())){//對application/json數據格式的數據進行去空格處理
		        	this.content=IOUtils.toByteArray(request.getInputStream());//獲取文本數據;
					// 對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 {  
      	//  這種獲取的參數的方式針對于內容類型為文本類型,比如Content-Type:text/plain,application/json,text/html等
      	//在springmvc中可以使用@RequestBody 來獲取 json數據類型
  	 	//其他文本類型不做處理,重點處理json數據格式
			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參數處理,則getInputStream()方法需要重寫。網上比較流行的做法是,將字節(jié)數據保存,然后封裝成字節(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 方法重寫最好限定數據類型。比如說文本類型(application/json,text/plain)。

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

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

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

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

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

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;
/**
 * 自定義過濾器,用于對請求參數去空格處理。
 */
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 {
	/**
	 *該過濾器用于對請求參數做去空格處理
	 *@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字符串的處理

以上處理的是簡單的數據類型,如果是json字符串,應當先解析json字符串,將其中的value字符串前后去空格??梢詤⒖家韵麓a處理。

     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 數組
            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 數組
            parseJSONArray(((JSONArray) keyObj));
        }
    }

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

相關文章

  • Spring Boot創(chuàng)建可執(zhí)行jar包的實例教程

    Spring Boot創(chuàng)建可執(zhí)行jar包的實例教程

    這篇文章主要介紹了Spring Boot創(chuàng)建可執(zhí)行jar包的實例教程,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • spring boot hutool整合email的詳細過程

    spring boot hutool整合email的詳細過程

    這篇文章主要介紹了spring boot hutool整合email的相關知識,本文介紹兩種方式發(fā)送email文件,結合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • intellij idea設置統(tǒng)一JavaDoc模板的方法詳解

    intellij idea設置統(tǒng)一JavaDoc模板的方法詳解

    這篇文章主要介紹了intellij idea設置統(tǒng)一JavaDoc模板的方法詳解,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • MyBatis實現萬能Map和模糊查詢

    MyBatis實現萬能Map和模糊查詢

    本文主要介紹了MyBatis實現萬能Map和模糊查詢,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • Java實現企業(yè)微信回調配置的詳細步驟與測試

    Java實現企業(yè)微信回調配置的詳細步驟與測試

    這篇文章主要給大家介紹了關于Java實現企業(yè)微信回調配置的詳細步驟與測試,企業(yè)微信回調是指企業(yè)微信通過HTTP?POST請求將業(yè)務數據回調到指定的URL上,文中給出了詳細的代碼示例,需要的朋友可以參考下
    2023-09-09
  • Java求最小生成樹的兩種算法詳解

    Java求最小生成樹的兩種算法詳解

    最小生成樹(Minimum Spanning Tree):在連通圖的所有生成樹中,所有邊的權值和最小的生成樹,稱為最小生成樹。這篇文章主要介紹了求最小生成樹的兩種方法:Prim算法和Kruskal算法,需要的可以參考一下
    2022-01-01
  • 【spring-boot】快速構建spring-boot微框架的方法

    【spring-boot】快速構建spring-boot微框架的方法

    本篇文章主要介紹了【spring-boot】快速構建spring-boot微框架的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java 括號匹配問題案例詳解

    Java 括號匹配問題案例詳解

    這篇文章主要介紹了Java 括號匹配問題案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • Java中JDBC連接池的基本原理及實現方式

    Java中JDBC連接池的基本原理及實現方式

    本文詳細講解了Java中JDBC連接池的基本原理及實現方式,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-12-12
  • Springmvc ResponseBody響應json數據實現過程

    Springmvc ResponseBody響應json數據實現過程

    這篇文章主要介紹了Springmvc ResponseBody響應json數據實現過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10

最新評論