Back-End ์ž‘์—…์‹ค/Spring Framework

[Spring Boot] OncePerRequestFilter๋ž€?

์ฃผ๋‹ˆ์“ฐ๐Ÿง‘‍๐Ÿ’ป 2023. 2. 3. 20:57
728x90
๋ฐ˜์‘ํ˜•




 

 

 

๐Ÿš€ OncePerRequestFilter

    ๐Ÿ”ฝ  ๊ฐœ์š”

        ๐Ÿ“ฆ Filter์™€ OncePerRequestFilter ์ฐจ์ด

Filter์— ๋Œ€ํ•ด ์„ค๋ช…ํ•œ ๋‚ด์šฉ์€ ์ด ๊ณณ์„ ํ†ตํ•ด ์ค€๋น„ํ•ด ๋‘์—ˆ์–ด์š”.

OncePerRequestFilter Class๋Š” ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ Http Request์˜ ํ•œ ๋ฒˆ์˜ ์š”์ฒญ์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰ํ•˜๋Š” Filter์—์š”.

์˜ˆ๋ฅผ ๋“ค์–ด Forwarding์ด ๋ฐœ์ƒํ•˜๋ฉด Filter Chain์ด ๋‹ค์‹œ ๋™์ž‘ํ•˜์—ฌ ์ธ์ฆ์ฒ˜๋Ÿผ ๋”ฑ ํ•œ๋ฒˆ๋งŒ ํ•ด์•ผ ํ•˜๋Š” Logic์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์—ฌ๋Ÿฌ๋ฒˆ ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ์–ด์š”.

๋ฐ˜์‘ํ˜•

ํฌ์›Œ๋”ฉ ๊ณผ์ •



        ๐Ÿ“ฆ doFilter()

doFilter()๋Š” ์ตœ์ดˆ ์‹คํ–‰ ์‹œ ServletRequest ๊ฐ์ฒด์— ์ž์‹ ์˜ ์ด๋ฆ„๊ณผ ์ˆ˜ํ–‰ํ•˜์˜€์„์Œ ํ‘œ์‹œ๊ฐ€ํžˆ ์œ„ํ•œ Boolean์˜ true ๊ฐ’์„ ํ•จ๊ป˜ ๋„ฃ์–ด ๋‘์–ด์š”. ๊ทธ๋Ÿฐ ๋’ค doFilterInternal()์„ ํ†ตํ•ด ์ž์‹ ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ ํ•œ๋‹ต๋‹ˆ๋‹ค.

๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋“ฑ์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ ์ด ์ „ ์ˆ˜ํ–‰์—์„œ ์š”์ฒญ ๊ฐ์ฒด์— ๋‹ด์•„๋’€๋˜ ์ˆ˜ํ–‰ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ฒŒ ๋˜๊ณ , ์ด๋ฏธ ์ˆ˜ํ–‰๋˜์—ˆ๋‹ค๊ณ  ํ‘œ์‹œ๊ฐ€ ๋˜๋ฉด Filter Chain์—๊ฒŒ ์š”์ฒญ๊ณผ ์‘๋‹ต ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ด์š”.

public abstract class OncePerRequestFilter extends GenericFilterBean {

    public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
            HttpServletRequest httpRequest = (HttpServletRequest)request;
            HttpServletResponse httpResponse = (HttpServletResponse)response;
            String alreadyFilteredAttributeName = this.getAlreadyFilteredAttributeName();
            boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;
            if (!this.skipDispatch(httpRequest) && !this.shouldNotFilter(httpRequest)) {
                if (hasAlreadyFilteredAttribute) {
                    if (DispatcherType.ERROR.equals(request.getDispatcherType())) {
                        this.doFilterNestedErrorDispatch(httpRequest, httpResponse, filterChain);
                        return;
                    }
                    filterChain.doFilter(request, response);
                } else {
                    request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
                    try {
                        this.doFilterInternal(httpRequest, httpResponse, filterChain);
                    } finally {
                        request.removeAttribute(alreadyFilteredAttributeName);
                    }
                }
            } else {
                filterChain.doFilter(request, response);
            }
        } else {
            throw new ServletException("OncePerRequestFilter just supports HTTP requests");
        }
    }
}
728x90


์ฆ‰, ์–ด๋Š Filter์—์„œ Header๋ฅผ ํ™•์ธ ํ•œ ๋’ค ํŠน์ • URL๋กœ Forwarding ํ•œ๋‹ค๊ณ  ํ•  ๋•Œ, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด URL๋กœ ํฌ์›Œ๋”ฉ ์‹œํ‚ค๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ์„œ๋ธ”๋ฆฟ ์‹คํ–‰ ์ค‘ ์š”์ฒญ์ด ์˜ฌ ๊ฒƒ์ด์—์š”.

OncePerRequestFilter๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์•ž์—์„œ ๊ฑฐ์นœ Filter๋ฅผ ๋˜ ๊ฑฐ์น˜๊ฒŒ ๋˜๊ณ , ์ž์› ๋‚ญ๋น„๋ฅผ ํ•˜๋Š” ์…ˆ์ด ๋˜์–ด ๋ฒ„๋ ค์š”.

์ด ๋•Œ, ๋™์ผํ•œ ์š”์ฒญ์•ˆ์—์„œ ํ•œ๋ฒˆ๋งŒ Filtering ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด OncePerRequestFilter์˜ ์—ญํ• ์ด๋ฉฐ, ์ธ์ฆ ๋˜๋Š” ์ธ๊ฐ€์™€ ๊ฐ™์ด ํ•œ๋ฒˆ๋งŒ ๊ฑฐ์ณ์•ผ ํ•˜๋Š” Logic์— ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ต๋‹ˆ๋‹ค.

์ธ์ฆ, ์ธ๊ฐ€๋ฅผ ๊ฑฐ์น˜๊ณ  ํŠน์ • URL๋กœ ํฌ์›Œ๋”ฉํ•˜๋ฉด ์š”์ฒญ์ด ๋“ค์–ด์™”์œผ๋‹ˆ ์ธ์ฆ, ์ธ๊ฐ€ Filter๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ ์‹œ์ผœ์•ผ ํ•˜์ง€๋งŒ, OncePerRequestFilter๋ฅผ ์ด์šฉํ•˜๋ฉด ์ธ์ฆ, ์ธ๊ฐ€๋ฅผ ํ•œ๋ฒˆ๋งŒ ๊ฑฐ์น˜๊ณ  ๋ฐ”๋กœ ๋‹ค์Œ Logic์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.



 

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•