본문 바로가기

spring boot

Filter 추가 후 HTTP가 무조건 200으로 전달되는 에러(filterChain.doFilter)

필터를 추가한 후 컨트롤러가 제대로 작동하는지 다시 테스트를 해보니, 원래 201로 전달되어야 하는 테스트가 200으로 전달되면서 실패로 떨어졌다. 

 

문제의 필터

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.tlog.backend.login.JwtProvider;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
@Component
public class JwtFilter extends OncePerRequestFilter{

	private final JwtProvider jwtProvider;
    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String HEADER_STRING = "Authorization";
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		logger.info("jwt filter start");
		//로그인이나 회원가입이면 필터 종료
		if(request.getMethod().equals("POST")&&request.getRequestURI().startsWith("/member")
				|| request.getMethod().equals("POST")&&request.getRequestURI().startsWith("/login")) {
			return;
		}
		
		//토큰 검사
			
		
	}

}

 

테스트 대상인 컨트롤러

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.tlog.backend.member.service.MemberService;
import com.tlog.backend.member.web.dto.MemberSignUpRequest;
import com.tlog.backend.member.web.dto.MemberSignUpResponse;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
@RestController
public class MemberController {
	
	private final MemberService memberService;
	
	@PostMapping("/member")
	public ResponseEntity<MemberSignUpResponse> signUp(@Validated @RequestBody MemberSignUpRequest request) {
		log.info("request url: /memper \n method: post");
		return ResponseEntity.status(HttpStatus.CREATED).body(new MemberSignUpResponse(memberService.signUp(request)));
	}
}

 

혹시나 해서 로그를 찍어보니 필터에서는 로그가 찍히는데 컨트롤러에서는 로그가 안찍힌다. 그리고 response body에도 값이 담겨져 오지 않았다.

 

혹시나 해서 필터에 filterChain.doFilter(request, response); 를 추가했더니 정상적으로 작동되었다.

doFilter 함수의 역할이 무엇인지 파악이 안되어 다른 사람의 코드를 보고도 추가해야 한다는 생각을 못했다.

 

doFilter 설명

Causes the next filter in the chain to be invoked, or if the calling filter is the last filter in the chain, causes the resource at the end of the chain to be invoked.

번역:

체인의 다음 필터가 호출되도록 하거나 호출 필터가 체인의 마지막 필터인 경우 체인 끝에 있는 리소스가 호출되도록 합니다.

 

앞부분만 읽고 다음 필터가 없으니 굳이 추가하지 않았는데, 다음 필터가 없으니 해당 필터가 마지막이고 리소스가 호출되도록 doFilter를 호출해야하는 것이였다.

리소스가 호출되지 않았으니 컨트롤러의 로그도 찍히지 않고 응답 body에도 아무것도 안담겨온 듯 하다.

 

수정한 코드

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.tlog.backend.login.JwtProvider;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
@Component
public class JwtFilter extends OncePerRequestFilter{

	private final JwtProvider jwtProvider;
    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String HEADER_STRING = "Authorization";
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		logger.info("jwt filter start");
		//로그인이나 회원가입이면 필터 종료
		if(request.getMethod().equals("POST")&&request.getRequestURI().startsWith("/member")
				|| request.getMethod().equals("POST")&&request.getRequestURI().startsWith("/login")) {
			filterChain.doFilter(request, response); //추가
            return;
		}
		
		//토큰 검사
			
		
	}

}