복붙노트

[SPRING] Spring : 필터에서 컨트롤러로 객체를 전달하는 방법

SPRING

Spring : 필터에서 컨트롤러로 객체를 전달하는 방법

Spring 부트 애플리케이션의 컨트롤러 내에서 사용될 객체를 생성하는 필터를 추가하려고합니다.

이 필터는이 객체의 "중앙 집중식"생성기로 필터를 사용하는 것입니다. 즉, 요청을 특정하며 컨트롤러에서만 유용합니다. HttpServletRequest request.getSession (). setAttribute 메서드를 사용하려고했습니다 : 컨트롤러에서 내 개체에 액세스 할 수 있지만 세션에 (분명히) 추가됩니다.

필터는 올바른 방법입니까? 그렇다면 컨트롤러에서 사용하는 필터에 의해 생성 된 임시 객체를 어디에 보관할 수 있습니까?

해결법

  1. ==============================

    1.ServletRequest.setAttribute (String name, Object o)를 사용할 수 있습니다.

    ServletRequest.setAttribute (String name, Object o)를 사용할 수 있습니다.

    예를 들면

    @RestController
    @EnableAutoConfiguration
    public class App {
    
        @RequestMapping("/")
        public String index(HttpServletRequest httpServletRequest) {
            return (String) httpServletRequest.getAttribute(MyFilter.passKey);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    
        @Component
        public static class MyFilter implements Filter {
    
            public static String passKey = "passKey";
    
            private static String passValue = "hello world";
    
            @Override
            public void init(FilterConfig filterConfig) throws ServletException {
    
            }
    
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                    throws IOException, ServletException {
                request.setAttribute(passKey, passValue);
                chain.doFilter(request, response);
            }
    
            @Override
            public void destroy() {
    
            }
        }
    }
    
  2. ==============================

    2.@Scope ( 'request')와 함께 Bean을 사용하지 않는 이유는 무엇입니까?

    @Scope ( 'request')와 함께 Bean을 사용하지 않는 이유는 무엇입니까?

    @Component
    @Scope(value="request", proxyMode= ScopedProxyMode.TARGET_CLASS)
    class UserInfo {
       public String getPassword() {
          return password;
       }
    
       public void setPassword(String password) {
          this.password = password;
       }
    
       private String password;
    }
    

    그런 다음 필터와 컨트롤러 모두에서이 bean을 Autowire하여 데이터를 설정하고 가져올 수 있습니다.

    이 UserInfo 빈의 라이프 사이클은 요청 내에서만 존재하므로 일단 http 요청이 완료되면 인스턴스도 종료됩니다

  3. ==============================

    3.나는 실제로 시나리오가 무엇인지 모르지만 필터에 객체를 만들고 코드의 어딘가에서 사용하려는 경우 ThreadLocal 클래스를 사용하면됩니다.

    나는 실제로 시나리오가 무엇인지 모르지만 필터에 객체를 만들고 코드의 어딘가에서 사용하려는 경우 ThreadLocal 클래스를 사용하면됩니다.

    이 작품이 그 질문에서 가장 득표 한 답변을 어떻게 볼 수 있는지 알기 위해서 ThreadLocal의 목적은 무엇입니까?

    일반적으로 ThreadLocal을 사용하면 현재 스레드에서만 사용할 수있는 객체를 저장할 수있는 클래스를 만들 수 있습니다.

    때로는 최적화를 위해 같은 스레드가 후속 요청을 처리하는 데 사용될 수 있으므로 요청이 처리 된 후에 threadLocal 값을 정리하는 것이 좋습니다.

    class MyObjectStorage {
      static private ThreadLocal threadLocal = new ThreadLocal<MyObject>();
    
      static ThreadLocal<MyObject> getThreadLocal() {
        return threadLocal;
      }
    }
    

    필터에

    MyObjectStorage.getThreadLocal().set(myObject);
    

    및 컨트롤러

    MyObjectStorage.getThreadLocal().get();
    

    필터 대신 @ControllerAdvice를 사용하고 모델을 사용하여 지정된 컨트롤러로 개체를 전달할 수 있습니다.

    @ControllerAdvice(assignableTypes={MyController.class})
    class AddMyObjectAdvice {
    
        // if you need request parameters
        private @Inject HttpServletRequest request; 
    
        @ModelAttribute
        public void addAttributes(Model model) {
            model.addAttribute("myObject", myObject);
        }
    }
    
    
    @Controller
    public class MyController{
    
       @RequestMapping(value = "/anyMethod", method = RequestMethod.POST)
       public String anyMethod(Model model) {
          MyObjecte myObject = model.getAttribute("myObject");
    
          return "result";
       }
    }
    
  4. ==============================

    4.이 작업을 한 가지 방법은 HttpServletRequest 객체를 원본 객체와 임시 객체를 인식하는 자체 구현으로 래핑하는 것입니다. 이점은 요청 범위에만 국한되며 스레드 또는 세션에 저장되지 않는다는 것입니다. 이렇게 이렇게 :

    이 작업을 한 가지 방법은 HttpServletRequest 객체를 원본 객체와 임시 객체를 인식하는 자체 구현으로 래핑하는 것입니다. 이점은 요청 범위에만 국한되며 스레드 또는 세션에 저장되지 않는다는 것입니다. 이렇게 이렇게 :

    public class MyServletRequest extends HttpServletRequestWrapper {
      private MyObject obj;
      public MyServletRequest(HttpServletRequest request){
        super(request);
      }
      //set your object etc
    }
    

    그런 다음 서블릿에서 :

    public void doGet(HttpServletRequest req, HttpServletResponse resp){
       MyServletRequest myRequest = (MyServletRequest)req;
       //now you can access your custom objects
    }
    
  5. from https://stackoverflow.com/questions/35444633/spring-how-to-pass-objects-from-filters-to-controllers by cc-by-sa and MIT license