亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

本次斗毆事件起因全部歸IOS,為啥這么說,http請(qǐng)求都不會(huì)發(fā),瞎寫的什么玩意(ps:他應(yīng)該不會(huì)看到...)。

在處理本次沖突中,意外發(fā)現(xiàn)了另外一個(gè)存在已久的bug,我們先說說這個(gè)玩意,再說我們之間的恩怨。因?yàn)檫@是息息相關(guān)的。

SpringBoot中的過濾器

過濾器這東西應(yīng)該很常見了,但是你的過濾器真的起到攔截的作用了嗎?這里就算你起到攔截的作用了,但是你的過濾器能攔截到指定的路徑嗎?先看一下我原始寫法。

謹(jǐn)慎參考:

@WebFilter(filterName = "baseFilter", urlPatterns = "/*")
public class BaseFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) {

        System.out.println("baseFilter 攔截了 /*");
        
        filterChain.doFilter(req, resp);
    }
}

首先這里說下,如果你這是特別單純的加個(gè)@WebFilter就以為ok了,那我告訴你,臉會(huì)被打的很疼的。

因?yàn)檫@個(gè)注解是servlet的,所以你一定要記得在啟動(dòng)類上加@ServletComponentScan此注解,這樣在應(yīng)用啟動(dòng)的時(shí)候,過濾器才會(huì)被掃描到。

我們寫了一個(gè)Controller的接口訪問了下,可以看到攔截器確實(shí)攔截到了我們的請(qǐng)求。

 

你以為的只是你以為

我們項(xiàng)目有時(shí)候大了,不知道引入了什么東西,有時(shí)候會(huì)導(dǎo)致這個(gè)過濾器呢就無法被注入,看到那行報(bào)錯(cuò)呢可能腦子還沒反應(yīng)過來,但是CV大法已經(jīng)打開了度娘,找到了問題原因,度娘說你加個(gè)@Commponent注解好了。然后也確實(shí)好了,然后接下來他都如何操作。

@Component
@WebFilter(filterName = "baseFilter", urlPatterns = "/user/*")
public class BaseFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) {

        HttpServletRequest request = (HttpServletRequest) req;

        String url = request.getRequestURL().toString();

        System.out.println(url);
        System.out.println("baseFilter 攔截了 /*");
        
        filterChain.doFilter(req, resp);
    }
}

然而,不巧的是加了@Component注解雖然解決了問題,但是呢urlPatterns攔截的指定路徑卻沒有生效。

我這里是一個(gè)pub開頭的請(qǐng)求,攔截器攔截的user開頭的,然后如下:

 

他居然將所有的請(qǐng)求給我攔截了下來,不是我想象的那樣,那我們?cè)撊绾谓鉀Q這種問題呢?往下看同學(xué)。

SpringBoot如何注入過濾器

這里我就不列舉眾多的注入方式了,以免混淆大家,我就直接告訴你們?cè)趺凑_注入就ok了,本人已經(jīng)親測(cè),而且管理起來很是方便。

過濾器寫法

過濾器除了實(shí)現(xiàn)Filter之外,不要加任何的東西,就是這么簡(jiǎn)單。

public class BaseFilter implements Filter {


    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) {

        HttpServletRequest request = (HttpServletRequest) req;

        String url = request.getRequestURL().toString();

        System.out.println(url);
        System.out.println("baseFilter 攔截了 /*");
        
        filterChain.doFilter(req, resp);
    }
}

過濾器注入

我們這里直接通過配置類的方式將過濾器注入,這樣呢,我們這里也一目了然,看到我們所有的過濾器,以及過濾器規(guī)則。

下面的這些參數(shù)都是基本配置,基本都是必填,name你就寫過濾器的類名,首字母小寫就好了,order就是過濾器的執(zhí)行順序,數(shù)字越小,越先執(zhí)行。

這樣我們一個(gè)完整的過濾器就配置好了。當(dāng)你再訪問/pub接口時(shí),是不會(huì)被BaseFilter攔截到的。

「這里也推薦大家以后盡量這樣去配置。」

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<BaseFilter> baseFilter() {
        FilterRegistrationBean<BaseFilter> filterBean = new FilterRegistrationBean<>();
        filterBean.setFilter(new BaseFilter());
        filterBean.setName("baseFilter");
        filterBean.addUrlPatterns("/user/*");
        filterBean.setOrder(1);
        return filterBean;
    }
}

我與iOS的一戰(zhàn)

我們先看報(bào)的錯(cuò),再來聊聊這次的鍋我是怎么甩的

RequestRejectedException: The request was rejected because the URL was not normalized.

看到?jīng)]因?yàn)榫W(wǎng)址不標(biāo)準(zhǔn),導(dǎo)致請(qǐng)求被拒絕。

非說我接口有問題,本來想奮起反抗,看到對(duì)方比我身材威猛,想想還是抓到實(shí)質(zhì)性證據(jù)在甩他吧。

既然說請(qǐng)求網(wǎng)址不正確,我猜測(cè)就是請(qǐng)求路徑中是不是有什么貓膩,那我們就抓包唄。

最后在我們各種手段之下拿到了真憑實(shí)據(jù)。諸位法官請(qǐng)看:

他的請(qǐng)求路徑:http://127.0.0.1:8080//user/list

他的請(qǐng)求路徑中出現(xiàn)了雙斜杠,這樣肯定報(bào)錯(cuò)啊。這里需要說明下,報(bào)錯(cuò)是因?yàn)橐肓薙ecurity安全框架。

既然已經(jīng)確定問題,那我必須奮起反抗,找他甩鍋,當(dāng)他看到這個(gè)時(shí)候,對(duì)吧自己也無話可說,只能默默的把鍋背上。

就這樣我這次又順利的甩鍋成功。

解決與反思

雖然鍋甩出去了,但是問題還是要解決的。

其實(shí)按正常邏輯來說,不管我們引入了什么東西,只要請(qǐng)求路徑正確,即使路徑中出現(xiàn)再多的斜杠,我們也應(yīng)該做好處理,不能影響用戶的訪問。所以我們就通過過濾器進(jìn)行一個(gè)處理。

public class UriFormatFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain)
            throws ServletException, IOException {

        // 路徑隔離符號(hào)
        String separateSymbol = "/";

        String uri = req.getRequestURI();
        StringBuilder newUrl = new StringBuilder();

        String[] split = uri.split(separateSymbol);

        for (String s : split) {
            if (StringUtils.isNotBlank(s)) {
                newUrl.Append(separateSymbol).append(s);
            }
        }

        req = new HttpServletRequestWrapper(req) {
            @Override
            public String getRequestURI() {
                return newUrl.toString();
            }
        };
        filterChain.doFilter(req, res);
    }
}

最后將過濾器注入

這里order為啥寫-100,如果你寫1,你以為它會(huì)是第一個(gè)執(zhí)行,其實(shí)不然,在執(zhí)行他之前,可能框架的一些過濾器會(huì)先執(zhí)行,所以為了保險(xiǎn)起見,我們就設(shè)置為-100,確保請(qǐng)求進(jìn)來之后先走它。

@Bean
public FilterRegistrationBean<UriFormatFilter> uriFormatFilter() {
    FilterRegistrationBean<UriFormatFilter> filterBean = new FilterRegistrationBean<>();
    filterBean.setFilter(new UriFormatFilter());
    filterBean.setName("uriFormatFilter");
    filterBean.addUrlPatterns("/*");
    filterBean.setOrder(-100);
    return filterBean;
}

注意

如果你在過濾器中注入了一些Mapper、Service之類的話,可能會(huì)出現(xiàn)問題,調(diào)用的時(shí)候被注入的對(duì)象可能是個(gè)null,這就涉及到類的加載順序,我就不在這里bibi了,真有人遇到了再說。反正我已經(jīng)解決了[Doge]。

撕逼階段

開發(fā)中,特別是小公司,很需要會(huì)多端的人來協(xié)調(diào)問題;有時(shí)候這種問題惡心之處在于:后端可以解決,移動(dòng)端也可以解決,誰處理了顯得就是誰的問題。

各位你們平時(shí)都是怎么拉扯的呢?

分享到:
標(biāo)簽:iOS
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定