Springboot中路徑參數(shù)帶 (%2F)的問題徹底解決方案
徹底解決Springboot中路徑參數(shù)帶/(%2F)的問題
背景
前兩天突然出現(xiàn)了一個線上問題,有同事反應我提供的接口報400的錯誤。接口路徑如下 PATCH /v1/basic/owners/{owner_code}/skus/{sku},經(jīng)過排查發(fā)現(xiàn)是sku參數(shù)中有/因此springboot轉義后直接報錯了。由于已經(jīng)有很多團隊對接了相關接口,且有很多的其他接口都使用了類似的傳參方式,因此需要考慮怎么在系統(tǒng)中不讓springboot自動解碼
解決方案
我先列出可用的解決方案,然后在列出網(wǎng)上常見錯誤方案
在項目中添加環(huán)境變量
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");

1.關閉spring自動decode url的開關
@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中存在/的功能(如果項目中沒有用到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;
}
}注意大部分項目中都有Spring security相關的設置,所以這里注意一下優(yōu)先級
在項目中配置好這三項后,url中的參數(shù)已經(jīng)可以正常解析了(注意需要讓接口使用法把帶/的參數(shù)encode之后再調用我們的接口)


常見的錯誤答案
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
}這里的.+只是一個示例,還有很多種正則的寫法。這是很多人的博客中被提及的方案,但并不能解決問題
1.覆蓋Spring MVC默認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);
}
}看起來很有效,實際上也不行
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的特定位置,可以使用這種方式來找到它并進行二次編碼
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);
}
}到此這篇關于徹底解決Springboot中路徑參數(shù)帶 (%2F)的問題的文章就介紹到這了,更多相關Springboot路徑參數(shù)帶 (%2F)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring?Boot?MQTT?Too?many?publishes?in?progress錯誤的解決方
本文介紹Spring?Boot?MQTT?Too?many?publishes?in?progress錯誤的解決方案,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-07-07
Java實現(xiàn)為Word每一頁設置不同圖片水印的效果
Word中設置水印時,可加載圖片設置為水印效果,但通常添加水印效果時,會對所有頁面都設置成統(tǒng)一效果。所以本文為大家介紹了一個方法,可以實現(xiàn)對每一頁或者某個頁面設置不同的水印效果,需要的可以參考一下2022-02-02

