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

1.關(guān)閉spring自動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)先級
在項(xiàng)目中配置好這三項(xiàng)后,url中的參數(shù)已經(jīng)可以正常解析了(注意需要讓接口使用法把帶/的參數(shù)encode之后再調(diào)用我們的接口)


常見的錯誤答案
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);
}
}看起來很有效,實(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的特定位置,可以使用這種方式來找到它并進(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)戰(zhàn)項(xiàng)目之記賬軟件
這篇文章主要介紹了java實(shí)戰(zhàn)項(xiàng)目之記賬軟件,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Spring?Boot?MQTT?Too?many?publishes?in?progress錯誤的解決方
本文介紹Spring?Boot?MQTT?Too?many?publishes?in?progress錯誤的解決方案,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-07-07
Java實(shí)現(xiàn)為Word每一頁設(shè)置不同圖片水印的效果
Word中設(shè)置水印時(shí),可加載圖片設(shè)置為水印效果,但通常添加水印效果時(shí),會對所有頁面都設(shè)置成統(tǒng)一效果。所以本文為大家介紹了一個(gè)方法,可以實(shí)現(xiàn)對每一頁或者某個(gè)頁面設(shè)置不同的水印效果,需要的可以參考一下2022-02-02

