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