首页 > 技术文章 > 注解控制接口权限的简单示例

lightbc 2021-03-12 23:04 原文

一、依赖引入

  <!--AOP-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
  </dependency>

二、自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Description:需要登录访问注解
 * Package:com.example.core
 *
 * @author lightbc
 * @version 1.0
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedLogin {
}

三、注解处理

import com.example.core.annotations.NeedLogin;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * Description:反射处理接口方法是否需要登录访问
 * Package:com.example.core.reflect
 *
 * @author lightbc
 * @version 1.0
 */
@Aspect
@Component
public class ProcessLogin {

    @Pointcut("@annotation(com.example.core.annotations.NeedLogin)")// 切点
    public void doLogin(){}

    @Before("doLogin()")// 前置增强
    public void before(JoinPoint joinPoint){// joinPoint连接点
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod(); // 获取方法
        if(method.isAnnotationPresent(NeedLogin.class)){// 判断方法上是否包含@NeedLogin注解
            Class[] cls = method.getParameterTypes();// 获取方法中参数类型
            Object attribute = null;
            for(int i=0;i<cls.length;i++){
                if(cls[i].getName().equals(HttpServletRequest.class.getName())){// 判断方法参数类型的名称是否和HtttpServletRequest的类型名称相等
                    HttpServletRequest request = (HttpServletRequest) joinPoint.getArgs()[i];// 转化类型
                    attribute = request.getSession().getAttribute("user");// 获取session中的属性
                    if(attribute == null){
                        continue;
                    }
                }else if(cls[i].getName().equals(HttpServletResponse.class.getName()) && attribute == null){// 判断方法参数类型的名称是否和HttpServletResponse的类型名称相等,以及获取到的用户对象是否为空
                    HttpServletResponse response = (HttpServletResponse) joinPoint.getArgs()[i];// 转化类型
                    try {
                        response.sendRedirect("/login/login/p");// 当用户对象为空是,重定向请求
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

四、控制器层

import com.example.core.annotations.NeedLogin;
import com.example.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Description:登录控制器
 * Package:com.example.controller
 *
 * @author lightbc
 * @version 1.0
 */
@Controller
@RequestMapping("/login")
public class LoginController {

    /**
     * 获取登录页面视图
     *
     * @return string 视图名
     */
    @RequestMapping(value = "/login/p", method = RequestMethod.GET)
    public String login() {
        return "/login/login";
    }

    /**
     * 处理登录请求
     *
     * @param username string 用户名
     * @param password string 密码
     * @param request  HttpServletRequest 请求
     * @param response HttpServletResponse 响应
     * @return
     */
    @RequestMapping(value = "/do/login", method = RequestMethod.POST)
    @ResponseBody
    public String doLogin(String username, String password, HttpServletRequest request, HttpServletResponse response) {
        if (username != "" && password != "") {
            User user = new User();
            user.setUser(username);
            user.setPw(password);
            request.getSession().setAttribute("user", user);
        }
        return "sucess";
    }

    /**
     * 需要登录访问的方法
     *
     * @param request  HttpServletRequest 请求
     * @param response HttpServletResponse 响应
     * @return
     */
    @RequestMapping(value = "/t", method = RequestMethod.GET)
    @ResponseBody
    @NeedLogin
    public String test(HttpServletRequest request, HttpServletResponse response) {
        return "test sucess";
    }
}

五、前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post" action="/login/do/login">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" value="提交">
    </form>
</body>
</html>

六、总结

  • 以上均在springboot框架下进行,springboot传送:点击传送
  • 因为是示例所以控制器层使用的是@Controller+@ResponseBody的形式进行注解,而非直接使用@RestController@Controller返回的是视图,配合@ResponseBody使用就可返回对象数据。@RestController相当于是@Controller+@ResponseBody
  • 当某些接口需要登录访问是,通过使用以上方法判断用户未登录的情况下,将请求重定向到登录页面让用户登录后访问。
  • 该实例仅简单阐明一个思路,具体还需视具体情况。

推荐阅读