springmvc 通过aop方式进行登录控制
登录控制,大体上的流程就是登陆的时候,在HttpSession中存放本次登录的用户名和密码。然后在进行每次页面跳转和后台请求的时候需要判断Session中是否有这个用户名和密码,如果有,说明用户在本浏览器上登录过,能够进行继续的操作,后台能够返回数据,支持页面跳转。如果没有登录,那么直接跳转到登录页面。
一开始,想使用filter或者listener进行控制一下,如果session中没有直接跳转到登录页面,齐活儿。但是,想来想去,这样做有点low了。因为后期肯定要加入权限控制,一旦加入权限控制,再和这个登录控制结合起来,业务层的代码不知道会乱成什么样子了。所以,最后决定使用aop。
这里使用的是spring aop。具体的步骤如下:
1、springmvc的controller层不能直接的进行Around切面操作,需要使用cglib做代理,然后才能加入切面。
2、在切面中判断Session中是否有username和password。如果有继续进行访问,如果没有,返回未登录的提示信息,或者直接跳转到登录界面。
3、在切面中需要利用HttpSession,可以参考springmvc 得到HttpServletRequest、HttpServletResponse、HttpSession
好,下面上货:
1、annotation
package com.xueyou.ssm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by wuxueyou on 16/10/2.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ControllerAnnotationLogin {
String name() default "";
}
2、controller
package com.xueyou.ssm.controller;
import com.xueyou.ssm.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* Created by wuxueyou on 16/10/1.
*/
@RestController
@RequestMapping(value = "/login" , method = {RequestMethod.GET,RequestMethod.POST}, produces = "application/json;charset=UTF-8;")
public class LoginController {
@Autowired
private LoginService loginService;
@RequestMapping(value = "/ssmlogin")
public Map<String,Object> ssmLogin(String username,String password){
Map<String,Object> params = new HashMap<>();
System.out.println(username);
System.out.println(password);
params.put("username",username);
params.put("password",password);
return loginService.login(params);
}
}
package com.xueyou.ssm.controller;
import com.xueyou.ssm.annotation.ControllerAnnotationLogin;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Created by wuxueyou on 16/10/1.
*/
@Controller
@RequestMapping(value = "/web", method = {RequestMethod.GET, RequestMethod.POST})
public class UrlPageController {
@RequestMapping(value = "/login")
public String login() {
return "login";
}
@ControllerAnnotationLogin
@RequestMapping(value = "/main")
public String main() {
return "main";
}
}
3、loginServiceImpl
package com.xueyou.ssm.serviceimpl;
import com.xueyou.ssm.dao.LoginDao;
import com.xueyou.ssm.service.LoginService;
import com.xueyou.ssm.utils.Base;
import com.xueyou.ssm.utils.SysContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by wuxueyou on 16/10/1.
*/
@Service("LoginService")
public class LoginServiceimpl implements LoginService{
@Autowired
LoginDao loginDao;
@Override
public Map<String, Object> login(Map<String, Object> params) {
Map<String,Object> resMap = new HashMap<>();
List<Map<String,Object>> tempUserList = loginDao.login(params);
if(tempUserList.size() == 0){
resMap.put("resCode", Base.MSG_CODE_ERROR);
resMap.put("resMsg",Base.MSG_USERNAMEORPASSWORDWRONG);
}else {
HttpSession session = SysContent.getSession();
session.setAttribute("username",params.get("username").toString());
session.setAttribute("password",params.get("password").toString());
resMap.put("resCode",Base.MSG_CODE_SUCCESS);
resMap.put("resMsg",Base.MSG_SUCCESS);
}
return resMap;
}
}
4、切面
package com.xueyou.ssm.aspect;
import com.xueyou.ssm.utils.Base;
import com.xueyou.ssm.utils.SessionTimeOutException;
import com.xueyou.ssm.utils.SysContent;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
/**
* Created by wuxueyou on 16/10/1.
*/
@Aspect
@Component("TestAspect")
public class TestAspect {
private static Logger logger = Logger.getLogger(TestAspect.class);
// @Around("execution(* com.xueyou.ssm.controller.*.*(..)) " +
// "and !execution(* com.xueyou.ssm.controller.LoginController.ssmLogin(..)) " +
// "and !execution(* com.xueyou.ssm.controller.UrlPageController.*(..))")
@Around("@annotation(com.xueyou.ssm.annotation.ControllerAnnotationLogin)")
public Object sessionTimeOutAdvice(ProceedingJoinPoint pjp) throws SessionTimeOutException{
Object args[] = pjp.getArgs();
Object result = null;
String targetName = pjp.getTarget().getClass().getSimpleName();
String methodName = pjp.getSignature().getName();
logger.info("----------------执行方法-----------------");
logger.info("类名:" + targetName + " 方法名:" + methodName);
HttpSession session = SysContent.getSession();
if (session.getAttribute("username") != null) {
try {
result = pjp.proceed(args);
} catch (Throwable e) {
e.printStackTrace();
}
return result;
} else {
// System.out.println(((MethodSignature)pjp.getSignature()).getReturnType().getSimpleName().toString());
String redirectStr = "login";
String returnType = ((MethodSignature)pjp.getSignature()).getReturnType().getSimpleName().toString();
if(returnType.equals("String")){
return redirectStr;
}else if(returnType.equals("Map")){
Map<String,Object> resMap = new HashMap<>();
resMap.put("resCode", Base.MSG_CODE_SESSIONOUTOFDATE);
resMap.put("resMsg",Base.MSG_SESSIONOUTOFDATE);
return resMap;
}else {
throw new SessionTimeOutException(Base.MSG_SESSIONOUTOFDATE);
}
}
}
}
5、自定义Exception
package com.xueyou.ssm.utils;
/**
* Created by wuxueyou on 16/10/2.
*/
public class SessionTimeOutException extends Exception{
public SessionTimeOutException(String message) {
super(message);
}
}
6、springmvc统一处理Exception
package com.xueyou.ssm.utils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by wuxueyou on 16/10/2.
*/
@Component("MyExceptionHandler")
public class MyExceptionHandler extends SimpleMappingExceptionResolver {
private Logger logger = Logger.getLogger(MyExceptionHandler.class);
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
return getModelAndView("error", ex);
}
}
7、下面是运行结果:
登录成功后:
清除缓存,直接访问/web/main