복붙노트

[SPRING] Spring MVC : 컨트롤러 메소드 매개 변수에 요청 속성을 바인드한다.

SPRING

Spring MVC : 컨트롤러 메소드 매개 변수에 요청 속성을 바인드한다.

Spring MVC에서는 요청 매개 변수를 요청을 처리하는 메소드 매개 변수에 쉽게 바인딩 할 수있다. 방금 @RequestParameter ( "name")을 사용합니다. 하지만 요청 속성을 사용하여 동일한 작업을 수행 할 수 있습니까? 현재 요청 속성에 액세스하려면 다음을 수행해야합니다.

MyClass obj = (MyClass) request.getAttribute("attr_name");

하지만 난 정말 이런 식으로 뭔가를 대신 사용하고 싶습니다 :

@RequestAttribute("attr_name") MyClass obj

불행히도이 방법으로는 작동하지 않습니다. 어떻게 든 스프링 기능을 확장하고 내 "바인더"를 추가 할 수 있습니까?

편집 (내가 달성하기 위해 노력하고있어) : 나는 현재 요청한 속성 안에 로그 된 사용자를 저장합니다. 그래서 내가 현재 로그인 한 사용자 (모든 메소드 내부에 있음)에 액세스 할 때마다이 추가 행 user = (User) request.getAttribute ( "user");를 작성해야합니다. 가능한 한 짧게 만들고 싶습니다. 메소드 매개 변수로 삽입하는 것이 바람직합니다. 아니면 인터셉터와 컨트롤러를 통해 무언가를 전달하는 또 다른 방법을 알고 있다면 나는 그것을 듣게 될 것이다.

해결법

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

    1.음, 마침내 모델이 작동하는 방식과 @ModelAttribute가 무엇인지 조금 이해했습니다. 여기 내 해결책이있다.

    음, 마침내 모델이 작동하는 방식과 @ModelAttribute가 무엇인지 조금 이해했습니다. 여기 내 해결책이있다.

    @Controller 
    class MyController
    {
        @ModelAttribute("user")
        public User getUser(HttpServletRequest request) 
        {
            return (User) request.getAttribute("user");
        }
    
        @RequestMapping(value = "someurl", method = RequestMethod.GET)
        public String HandleSomeUrl(@ModelAttribute("user") User user)  
        {
            // ... do some stuff
        }
    }
    

    @ModelAttribute 주석이 표시된 getUser () 메소드는 @ModelAttribute로 표시된 모든 User 사용자 매개 변수를 자동으로 채 웁니다. 따라서 HandleSomeUrl 메서드가 호출되면이 호출은 MyController.HandleSomeUrl (MyController.getUser (request))와 비슷하게 보입니다. 적어도 이것이 상상하는 방법입니다. 멋진 점은 JSP 뷰에서 사용자가 더 이상 노력하지 않아도 액세스 할 수 있다는 것입니다.

    이것은 정확하게 나의 문제를 해결하지만 나는 더 이상의 질문을 가지고있다. @ModelAttribute 메서드를 모든 컨트롤러에 공통으로 사용할 수있는 곳이 있습니까? 인터셉터의 preHandle () 메소드 내부에서 모델 속성을 어떻게 든 추가 할 수 있습니까?

  2. ==============================

    2.사용 (Spring 4.3 현재) @RequestAttribute :

    사용 (Spring 4.3 현재) @RequestAttribute :

    @RequestMapping(value = "someurl", method = RequestMethod.GET)
    public String handleSomeUrl(@RequestAttribute User user) {
        // ... do some stuff
    }
    

    또는 요청 속성 이름이 메소드 매개 변수 이름과 일치하지 않는 경우 :

    @RequestMapping(value = "someurl", method = RequestMethod.GET)
    public String handleSomeUrl(@RequestAttribute(name="userAttributeName") User user) {
        // ... do some stuff
    }
    
  3. ==============================

    3.나는 당신이 찾고있는 것이라고 생각합니다 :

    나는 당신이 찾고있는 것이라고 생각합니다 :

    @ModelAttribute("attr_name") MyClass obj
    

    컨트롤러의 메소드 매개 변수에서 사용할 수 있습니다.

    Spring MVC에서 @ModelAttribute 란 무엇인가?

    그 질문은 Spring Documentation을 사용하는 몇 가지 예와 함께 Spring Documentation에 링크됩니다. 너는 그것을 여기에서 볼 수있다.

    최신 정보

    어떻게 페이지를 설정하는지 모르겠지만 사용자를 모델 속성으로 몇 가지 다른 방법으로 추가 할 수 있습니다. 아래에 간단한 예제를 설정했습니다.

    @RequestMapping(value = "/account", method = RequestMethod.GET)
    public ModelAndView displayAccountPage() {
        User user = new User(); //most likely you've done some kind of login step this is just for simplicity
        return new ModelAndView("account", "user", user); //return view, model attribute name, model attribute
    }
    

    그런 다음 사용자가 요청을 제출하면 Spring은 메소드 매개 변수의 User 객체에 사용자 속성을 바인딩합니다.

    @RequestMapping(value = "/account/delivery", method = RequestMethod.POST)
    public ModelAndView updateDeliverySchedule(@ModelAttribute("user") User user) {
    
        user = accountService.updateDeliverySchedule(user); //do something with the user
    
        return new ModelAndView("account", "user", user);
    }
    
  4. ==============================

    4.가장 우아한 것은 아니지만 적어도 작품은 ...

    가장 우아한 것은 아니지만 적어도 작품은 ...

    @Controller
    public class YourController {
    
        @RequestMapping("/xyz")
        public ModelAndView handle(
            @Value("#{request.getAttribute('key')}") SomeClass obj) {
    
            ...
            return new ModelAndView(...);
        }
    
    }
    

    출처 : http://blog.crisp.se/tag/requestattribute

  5. ==============================

    5.Spring 3.2부터는 Springs ControllerAdvice 주석을 사용하여 훨씬 더 멋지게 처리 할 수 ​​있습니다. 이렇게하면 별도의 클래스에 @ModelAttributes를 추가하는 조언을 받아 모든 컨트롤러에 적용 할 수 있습니다.

    Spring 3.2부터는 Springs ControllerAdvice 주석을 사용하여 훨씬 더 멋지게 처리 할 수 ​​있습니다. 이렇게하면 별도의 클래스에 @ModelAttributes를 추가하는 조언을 받아 모든 컨트롤러에 적용 할 수 있습니다.

    완성을 위해 실제로 @RequestAttribute ( "attr-name")을 그대로 만들 수도 있습니다. (아래에서 우리의 요구에 맞게이 기사에서 수정)

    먼저 주석을 정의해야합니다.

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    public @interface RequestAttribute {
        String value();
    }
    

    그런 다음 속성이 바인딩 될 때 수행해야 할 작업을 처리하기 위해 [WebArgumentResolver]가 필요합니다.

    public class RequestAttributeWebArgumentResolver implements WebArgumentResolver {
    
        public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest nativeWebRequest) throws Exception {
            // Get the annotation       
            RequestAttribute requestAttributeAnnotation = methodParameter.getParameterAnnotation(RequestAttribute.class);
    
            if(requestAttributeAnnotation != null) {
                HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
    
                return request.getAttribute(requestAttributeAnnotation.value);
            }
    
            return UNRESOLVED;
        }
    }
    

    이제이 customresolver를 config에 추가하여 해결할 수 있습니다.

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="customArgumentResolver">
            <bean class="com.sergialmar.customresolver.web.support.CustomWebArgumentResolver"/>
        </property>
    </bean>
    

    그리고 우리는 끝났어!

  6. ==============================

    6.예, 요청 속성에 자신의 '바인더'를 추가 할 수 있습니다. spring-mvc-3-showcase를 보거나 @Peter Szanto의 솔루션을 사용하십시오.

    예, 요청 속성에 자신의 '바인더'를 추가 할 수 있습니다. spring-mvc-3-showcase를 보거나 @Peter Szanto의 솔루션을 사용하십시오.

    또는 다른 답변에서 권장하는 것처럼 ModelAttribute로 바인딩하십시오.

    컨트롤러에 전달하고자하는 로그인 사용자이므로 Spring Security를 ​​고려할 수 있습니다. 그럼 당신은 원리를 당신의 방법에 주입시킬 수 있습니다 :

    @RequestMapping("/xyz")
    public String index(Principal principle) {
        return "Hello, " + principle.getName() + "!";
    }
    
  7. ==============================

    7.Spring WebMVC 4.x에서는 HandlerMethodArgumentResolver 구현을 선호한다.

    Spring WebMVC 4.x에서는 HandlerMethodArgumentResolver 구현을 선호한다.

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterAnnotation(RequestAttribute.class) != null;
    }
    
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        return webRequest.getAttribute(parameter.getParameterAnnotation(RequestAttribute.class).value(), NativeWebRequest.SCOPE_REQUEST);
    }
    

    }

    그런 다음 RequestMappingHandlerAdapter에 등록하십시오.

  8. from https://stackoverflow.com/questions/15032063/spring-mvc-bind-request-attribute-to-controller-method-parameter by cc-by-sa and MIT license