Spring 解析httpServletRequest注入參數到Bean的攔截包裝

此文並非專業文章,只是隨記。

相關類:
BeanWrapperImpl

ModelAttributeMethodProcessor.resolveArgument()

ServletRequestDataBinder
它可以手動調用,如:
Param param=new Param();//Param是你的參數bean
ServletRequestDataBinder servletRequestDataBinder = new ServletRequestDataBinder(param);
servletRequestDataBinder.bind(new WrapperHttpServletRequest(request));//reqeust是httpServletRequest的實例,Spring controller中可以得到。

WebRequestDataBinder
ServletRequestParameterPropertyValues 構造函數中會有WebUtils.getParametersStartingWith(request, (prefix != null ? prefix + prefixSeparator : null))
這一行代碼把普通的request請求,就是非multipart/form-data,而是普通的key-value形式的參數。
此方法中會調用 request.getParameterNames()
然後再迭代name執行request.getParameterValues(paramName);獲取到參數值,所以這樣是可以傳遞多個值的

setPropertyValue是在BeanWrapperImpl類中。

PropertyMatches這個類是專用於BeanWrapperImpl 用於計算bean和參數的屬性匹配,有一個方法calculateStringDistance(String s1, String s2),看起來並不晚懂,猜測大概是用於計算兩個字符串的相近程度,用於在名稱不完全匹配時也能匹配到。


BeanWrapperImpl 類的
private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv)
值得研究,它能把各種各樣的參數都設置到bean的屬性中,值得考究。
有200多行代碼,基本可以支持普通的所有類型


所以只要能修改了request.getParameterNames()和request.getParameterValues(paramName)這兩個方法的,就能改變spring的動作。

那麼我們就只是需要對request進行一層包裝並覆蓋這兩個方法。
我們只需要繼承自HttpServletRequestWrapper類即可。
getParameterNames()方法返回的是一個Enumeration<String>類型,需要自己實現 Enumeration這個接口,這個接口只有兩個方法,而且,jdk中並沒有一個現在的實現類可用,自己實現吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章