如何在控制器方法之前获取请求会话

时间:2017-08-01 07:16:51

标签: java spring servlets aspectj

我有一个服务器和简单的auth使用控制器。如何在运行控制器方法之前获取请求会话并修改响应体?

我想检查(仅针对我自己的注释标记的方法)会话是否具有属性(登录),并发送我的错误响应正文或转到控制器。

我尝试使用aspectj和拦截器,但结果是我可以在控制器方法完成后管理会话。因为拦截器preHandle方法在aspectJ @Before之前运行。

@Retention(RUNTIME)
@Target({ TYPE, METHOD })
public @interface CheckSession {

}

-

@Aspect
@Component 
public class CheckSessionAspect {

public CheckSessionAspect() {
    super();
}

@Before("@annotation(path.to.CheckSession)")
public void check(JoinPoint joinPoint) throws Throwable {

    ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    requestAttributes.setAttribute(SESSION_MARKER, "1", RequestAttributes.SCOPE_REQUEST);

   }

}

-

@ControllerAdvice
public class ResponseModifierAdvice implements ResponseBodyAdvice<Object> {

@Autowired
ErrorService errorService;

@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    return true;
}

@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {

    HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();

    if (servletRequest.getAttribute(SESSION_MARKER) != null)
        if (servletRequest.getSession().getAttribute(LOGIN) == null || StringUtils.isBlank(servletRequest.getSession().getAttribute(LOGIN).toString())) {
            ResponseEntity<Object> newResponseBody = errorService.sessionError(request, returnType.getMethod().getName(), NO_SESSION, getClass().toString());
            body = newResponseBody.getBody();
        }

    return body;
}
}

1 个答案:

答案 0 :(得分:0)

我做到了。如果用户没有会话,您可以使用@Around并返回ResponseEntity对象。

@Aspect
@Component 
public class CheckSessionAspect {

public CheckSessionAspect() {
    super();
}

@Around("@annotation(path.to.CheckSession)")
    public Object check(ProceedingJoinPoint pjp) throws Throwable {

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        if ((request.getSession().getAttribute(LOGIN) == null || StringUtils.isBlank(request.getSession().getAttribute(LOGIN).toString())) ||
                (request.getSession().getAttribute(IP) == null || StringUtils.isBlank(request.getSession().getAttribute(IP).toString()) ||
                        request.getSession().getAttribute(IP) != null && !request.getSession().getAttribute(IP).toString().equals(request.getRemoteAddr()))) 
        {
            requestAttributes.setAttribute(WRONG_SESSION_MARKER, "1", RequestAttributes.SCOPE_REQUEST);
            return new ResponseEntity<Object>(  new YourResponse(ERROR, "Invalid session"), HttpStatus.BAD_REQUEST);
        }

    Object proceed = pjp.proceed();

    return proceed;

   }
}