Springboot中路徑參數(shù)帶 (%2F)的問題徹底解決方案
徹底解決Springboot中路徑參數(shù)帶/(%2F)的問題
背景
前兩天突然出現(xiàn)了一個(gè)線上問題,有同事反應(yīng)我提供的接口報(bào)400的錯(cuò)誤。接口路徑如下 PATCH /v1/basic/owners/{owner_code}/skus/{sku}
,經(jīng)過排查發(fā)現(xiàn)是sku參數(shù)中有/
因此springboot轉(zhuǎn)義后直接報(bào)錯(cuò)了。由于已經(jīng)有很多團(tuán)隊(duì)對(duì)接了相關(guān)接口,且有很多的其他接口都使用了類似的傳參方式,因此需要考慮怎么在系統(tǒng)中不讓springboot自動(dòng)解碼
解決方案
我先列出可用的解決方案,然后在列出網(wǎng)上常見錯(cuò)誤方案
在項(xiàng)目中添加環(huán)境變量
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
1.關(guān)閉spring自動(dòng)decode url的開關(guān)
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setUrlDecode(false); configurer.setUrlPathHelper(urlPathHelper); } }
1.開啟Spring security中允許url中存在/的功能(如果項(xiàng)目中沒有用到Spring security 可跳過此配置)
@Order(Ordered.LOWEST_PRECEDENCE) @Configuration public class SecurityFirewallConfig extends WebSecurityConfigurerAdapter { @Bean public HttpFirewall allowUrlEncodedSlashHttpFirewall() { DefaultHttpFirewall firewall = new DefaultHttpFirewall(); firewall.setAllowUrlEncodedSlash(true); return firewall; } }
注意大部分項(xiàng)目中都有Spring security相關(guān)的設(shè)置,所以這里注意一下優(yōu)先級(jí)
在項(xiàng)目中配置好這三項(xiàng)后,url中的參數(shù)已經(jīng)可以正常解析了(注意需要讓接口使用法把帶/的參數(shù)encode之后再調(diào)用我們的接口)
常見的錯(cuò)誤答案
1.使用正則匹配獲取參數(shù)
@PostMapping("/v1/basic/owner-code/{ownerCode}/skus/{sku:.+}/ext-info") public ResponseEntity<String> getInfo(@PathVariable("ownerCode") String ownerCode, @PathVariable("sku") String sku) { // your logic here }
這里的.+只是一個(gè)示例,還有很多種正則的寫法。這是很多人的博客中被提及的方案,但并不能解決問題
1.覆蓋Spring MVC默認(rèn)URL解碼行為的配置類
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper() { @Override public Map<String, String> decodePathVariables(HttpServletRequest request, Map<String, String> vars) { return vars; } }; urlPathHelper.setUrlDecode(false); configurer.setUrlPathHelper(urlPathHelper); } }
看起來(lái)很有效,實(shí)際上也不行
1.使用@MatrixVariable接受參數(shù)
@PostMapping("/v1/basic/owner-code/{ownerCode}/skus/{sku:.+}/ext-info") public ResponseEntity<String> getInfo(@PathVariable("ownerCode") String ownerCode, @MatrixVariable("sku") String sku) { // your logic here }
1.自定義filter并添加到spring中
public class UrlEncodingFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; String url = request.getRequestURL().toString(); // 如果你的SKU部分總是在URL的特定位置,可以使用這種方式來(lái)找到它并進(jìn)行二次編碼 String encodedUrl = url.replace("skus/", "skus/").replace("/ext-info", "%2Fext-info"); HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) { @Override public StringBuffer getRequestURL() { return new StringBuffer(encodedUrl); } }; chain.doFilter(requestWrapper, res); } }
到此這篇關(guān)于徹底解決Springboot中路徑參數(shù)帶 (%2F)的問題的文章就介紹到這了,更多相關(guān)Springboot路徑參數(shù)帶 (%2F)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)戰(zhàn)項(xiàng)目之記賬軟件
這篇文章主要介紹了java實(shí)戰(zhàn)項(xiàng)目之記賬軟件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Spring?Boot?MQTT?Too?many?publishes?in?progress錯(cuò)誤的解決方
本文介紹Spring?Boot?MQTT?Too?many?publishes?in?progress錯(cuò)誤的解決方案,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-07-07Java實(shí)現(xiàn)為Word每一頁(yè)設(shè)置不同圖片水印的效果
Word中設(shè)置水印時(shí),可加載圖片設(shè)置為水印效果,但通常添加水印效果時(shí),會(huì)對(duì)所有頁(yè)面都設(shè)置成統(tǒng)一效果。所以本文為大家介紹了一個(gè)方法,可以實(shí)現(xiàn)對(duì)每一頁(yè)或者某個(gè)頁(yè)面設(shè)置不同的水印效果,需要的可以參考一下2022-02-02springboot配置flyway(入門級(jí)別教程)
本文介紹了springboot配置flyway,主要介紹基于SpringBoot集成flyway來(lái)管理數(shù)據(jù)庫(kù)的變更,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09