programing

스프링 부트 - 인터셉터에서 컨트롤러의 메서드로 인수 전달

subpage 2023. 7. 28. 22:07
반응형

스프링 부트 - 인터셉터에서 컨트롤러의 메서드로 인수 전달

학습 목적으로, 저는 토큰을 클라이언트에서 서버로 전달하는 사용자 정의 인증 시스템을 만들었습니다.Authorization표제의

서버 측에서는 요청이 컨트롤러의 메서드에 도달하기 전에 토큰의 전자 메일을 속성으로 사용하는 사용자 개체를 인터셉트기에 생성한 다음 이 사용자 개체를 필요한 모든 요청에 전달할 수 있는지 알고 싶습니다.

예를 들어, 다음과 같은 것을 얻고 싶습니다.

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index(final User user) {
        return user.getEmail();
    }

}

public class User {
    private String email;
}

여기서 user는 요청을 사용하여 사전 인터셉터에 만든 개체입니다.Authorization머리글을 쓰고 나서 나는 어떤 방법으로도 전달할 수 있고, 그렇지 않을 수 있습니다.RestController.

이것이 가능합니까?

#권장 솔루션 내가 만들 것입니다.@Bean와 함께@Scope사용자를 보유한 다음 해당 엔티티를 해당 홀더에 넣은 다음 해당 홀더에서 메소드 내부로 가져오는 요청.

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class CurrentUser {
    private User currentUser;

    public User getCurrentUser() {
        return currentUser;
    }

    public void setCurrentUser(User currentUser) {
        this.currentUser = currentUser;
    }
}

그리고 나서.

@Component
public class MyInterceptor implements HandlerInterceptor {

   private CurrentUser currentUser;

   @Autowired
   MyInterceptor(CurrentUser currentUser) {
       this.currentUser = currentUser;
   }

   @Override
   public boolean preHandle(
      HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      this.currentUser.setCurrentUser(new User("whatever"));
      return true;
   }
}

및 컨트롤러에서

@RestController
public class HelloController {

    private CurrentUser currentUser;

    @Autowired
    HelloController(CurrentUser currentUser) {
        this.currentUser = currentUser;
    }

    @RequestMapping("/")
    public String index() {
        return currentUser.getCurrentUser().getEmail();
    }

}

#대안해

당신이 갖고 싶은 당신의 객체가 하나의 필드만 포함하는 경우, 당신은 그것을 속이고 그 필드를 추가할 수 있습니다.HttpServletRequest매개 변수를 사용하여 마법이 발생하는 것을 확인합니다.

@Component
public class MyInterceptor implements HandlerInterceptor {
   @Override
   public boolean preHandle(
      HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      //TRY ONE AT THE TIME: email OR user
      //BOTH SHOULD WORK BUT SEPARATELY OF COURSE
      request.setAttribute("email", "login@domain.com");
      request.setAttribute("user", new User("login@domain.com"));
      return true;
   }
}

로컬 스레드 컨텍스트 개체를 다음과 같이 사용할 수 있습니다. 이 개체는 요청 스레드(스레드 세이프)당 하나의 매개 변수를 처리합니다.

public abstract class LoggedUserContext {

private static ThreadLocal<User> currentLoggedUser = new ThreadLocal<>();

public static void setCurrentLoggedUser(User loggedUser) {
    if (currentLoggedUser == null) {
        currentLoggedUser = new ThreadLocal<>();
    }
    currentLoggedUser.set(loggedUser);
}

public static User getCurrentLoggedUser() {
    return currentLoggedUser != null ? currentLoggedUser.get() : null;
}

public static void clear() {
    if (currentLoggedUser != null) {
        currentLoggedUser.remove();
    }
}

}

그런 다음 절편 사전 처리 기능에서 다음을 수행합니다.

LoggedUserContext.setCurrentLoggedUser(loggedUser);

그리고 인터셉터 postHandler 함수에서:

  LoggedUserContext.clear();

다른 장소에서:

User loggedUser = LoggedUserContext.getCurrentLoggedUser();

언급URL : https://stackoverflow.com/questions/58942591/spring-boot-pass-argument-from-interceptor-to-method-in-controller

반응형