SpringMVC 구현 controller에서 세션을 가져오는 실례 코드

평소에springMVC를 사용하는데 방법에서 session에 접근하면 Servlet API를 자연스럽게 호출합니다.사용하기에 매우 직관적이고 편리해서 줄곧 아무런 고려도 하지 않았다.
예:

@RequestMapping(value = "/logout")
public String logout(HttpSession session) {
 session.removeAttribute("user");
 return "/login";
} 
그러나 이렇게 해서 Servlet API에 의존하게 되었기 때문에 포조가 부족하다고 느낀다.
그래서 나는 이 문제를 해결하려고 시도했다.
저는 주석을 하나 쓸 생각입니다. 이름은'sessionScope'입니다. Target은 하나의 Method일 수도 있고 Parameter일 수도 있습니다.
즉,

 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 @Target({ ElementType.PARAMETER,ElementType.METHOD })
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface SessionScope {
  String value();
 }

그리고 저는 Argument Resolver를 등록해서 주해된 동동을 전문적으로 해결하고 그들을 모두 세션의 물건으로 바꾸겠습니다.
코드는 다음과 같습니다.

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public class SessionScopeMethodArgumentResolver implements
  HandlerMethodArgumentResolver {

 @Override
 public boolean supportsParameter(MethodParameter parameter) {
  // , target 
  if(parameter.hasParameterAnnotation(SessionScope.class))return true;
  else if (parameter.getMethodAnnotation(SessionScope.class) != null)return true;
  return false;
 }

 @Override 
 public Object resolveArgument(MethodParameter parameter,
   ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
   WebDataBinderFactory binderFactory) throws Exception {
  String annoVal = null;

  if(parameter.getParameterAnnotation(SessionScope.class)!=null){
   logger.debug("param anno val::::"+parameter.getParameterAnnotation(SessionScope.class).value());
   annoVal = parameter.getParameterAnnotation(SessionScope.class).value();
  }else if(parameter.getMethodAnnotation(SessionScope.class)!=null){
   logger.debug("method anno val::::"+parameter.getMethodAnnotation(SessionScope.class).value());
   annoVal = parameter.getMethodAnnotation(SessionScope.class)!=null?
          StringUtils.defaultString(parameter.getMethodAnnotation(SessionScope.class).value())
            :StringUtils.EMPTY;
  }
                                
  if (webRequest.getAttribute(annoVal,RequestAttributes.SCOPE_SESSION) != null){
   return webRequest.getAttribute(annoVal,RequestAttributes.SCOPE_SESSION);
  }
  else
   return null;
 }
                                      
 final Logger logger = LoggerFactory.getLogger(SessionScopeMethodArgumentResolver.class);
}

supportParameter는 대상이 주해되었는지 판단하고, 주해되었는지는resolve를 진행합니다.
resolve에서 주석 값을 가져옵니다. 주석 값은 session key이고 웹 Request로 session scope에서 값을 가져옵니다.
또한 이 설정을 org에 두어야 합니다.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter의customArgumentResolvers 목록에서 bean 탭 설정을 사용할 수도 있고 mvc 탭을 직접 사용할 수도 있습니다.
즉,
namespace: xmlns: mvc = "http://www.springframework.org/schema/mvc"
schema location은:http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd

<mvc:annotation-driven>
 <mvc:argument-resolvers>
  <bean class="pac.common.SessionScopeMethodArgumentResolver" />
 </mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:default-servlet-handler />
그런데 mvc:annotation-driven과 mvc:default-servlet-handler의 순서가 뒤바뀌면 안 돼요. 저만 이런 상황이 생기는 건 아니겠죠--...
이제 controller에서 사용할 수 있습니다. 예를 들면:

@RequestMapping(value = "/index")
@SessionScope("currentUser")
public ModelAndView index(User currentUser) {
 ModelAndView mav;
 if (currentUser==null || currentUser.getId()==null)
  mav = new ModelAndView("/login");
 else {
  mav = new ModelAndView("/index");
 }
 return mav;
}

또는 매개변수에 메모:

@RequestMapping(value = "/welcome")
public String welcome(@SessionScope("currentUser")User currentUser) {
 return "/main";
}
세션 업데이트는 현재 @sessionAttributes로 모델맵에 맞추는 방식입니다.
아니면 이렇게 하지 않고 Apache Shiro를 통합해서 controller에서 getSubject()를 직접 사용할 수 있습니다.
사용자 정보를 완전히shiro에게 맡기세요. 응, 이게 좋아요.
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

좋은 웹페이지 즐겨찾기