Springboot中路徑參數(shù)帶 (%2F)的問題徹底解決方案
徹底解決Springboot中路徑參數(shù)帶/(%2F)的問題
背景
前兩天突然出現(xiàn)了一個線上問題,有同事反應(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
}這里的.+只是一個示例,還有很多種正則的寫法。這是很多人的博客中被提及的方案,但并不能解決問題
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使用super和this來重載構(gòu)造方法
這篇文章主要介紹了詳解Java使用super和this來重載構(gòu)造方法的相關(guān)資料,這里提供實(shí)例來幫助大家理解這部分內(nèi)容,需要的朋友可以參考下2017-08-08
深入剖析Java中的synchronized關(guān)鍵字
在 Java 程序中,我們可以利用 synchronized 關(guān)鍵字來對程序進(jìn)行加鎖,它既可以用來聲明一個 synchronized 代碼塊,也可以直接標(biāo)記靜態(tài)方法或者實(shí)例方法,本文就帶大家深入了解Java中的synchronized關(guān)鍵字,感興趣的同學(xué)可以參考閱讀2023-06-06
http中g(shù)et請求與post請求區(qū)別及如何選擇
這篇文章主要介紹了http中g(shù)et請求與post請求在應(yīng)用中應(yīng)該如何選擇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-09-09

