在項(xiàng)目開發(fā)時(shí)喇勋,大部分操作時(shí)都是基于用戶登錄狀態(tài)下的。攔截器是最經(jīng)常使用的方式偎行,這里我結(jié)合了自定義注解川背。https://github.com/XMUTLZY/login-check-demo
項(xiàng)目結(jié)構(gòu)
項(xiàng)目結(jié)構(gòu).png
Demo主要用Springboot搭建
- vo包:定義了一個(gè)用戶實(shí)體類
- annotation包:存放自定義的注解
- config包:配置類贰拿,主要用于初始化攔截器
- controller包:一些操作,比如登錄校驗(yàn)熄云、訪問(wèn)主頁(yè)
- interceptor包:定義攔截器
具體實(shí)現(xiàn)
自定義注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by lin on 2020/04/10
*/
@Target(ElementType.METHOD) //標(biāo)記在方法上
@Retention(RetentionPolicy.RUNTIME) //生命周期(運(yùn)行時(shí)有效)
public @interface LoginRequired {
}
這里主要用到2個(gè)元注解膨更,其中@Target和@Retention有多個(gè)枚舉型可以設(shè)置,具體看源碼缴允。
攔截器
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import redis.clients.jedis.Jedis;
import sch.jake.logincheckdemo.web.annotation.LoginRequired;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
/**
* Created by lin on 2020/04/10
* @Tip: 登錄校驗(yàn)攔截器
*/
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) { //判斷處理請(qǐng)求的handler類型
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod(); //獲取處理請(qǐng)求的方法
if (method.getAnnotation(LoginRequired.class) != null) { //判斷該方法上是否有自定義的注解
Jedis jedis = new Jedis("127.0.0.1", 6379);
String userJsonStr = jedis.get("USER_INFO");
if (!StringUtils.hasText(userJsonStr)) { //判斷緩存中是否有用戶數(shù)據(jù)
return false;
}
}
return true;
}
}
簡(jiǎn)單來(lái)說(shuō)就是荚守,攔截器攔截請(qǐng)求,當(dāng)注解標(biāo)記在該請(qǐng)求方法上時(shí)练般,查詢緩存中是否有用戶信息矗漾。
配置類
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import sch.jake.logincheckdemo.web.interceptor.LoginInterceptor;
/**
* Created by lin on 2020/04/10
* @Tip: 配置類,用于初始化攔截器
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor());
}
@Bean
public LoginInterceptor loginInterceptor() {
return new LoginInterceptor();
}
}
這里就是初始化攔截器踢俄,并注冊(cè)到配置中缩功。
Controller
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Jedis;
import sch.jake.logincheckdemo.vo.User;
import sch.jake.logincheckdemo.web.annotation.LoginRequired;
/**
* Created by lin on 2020/04/10
*/
@Controller
public class TestController {
//登錄校驗(yàn)(成功時(shí)在緩存中存放用戶信息)
@PostMapping("/verify")
@ResponseBody
public String verify(@RequestBody User user) {
if ("Jake.lin".equals(user.getUserName()) && "test123".equals(user.getPassword())) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
String userJsonStr = JSONObject.toJSONString(user);
jedis.set("USER_INFO", userJsonStr);
return "success";
}
return "failure";
}
//進(jìn)入主頁(yè)
@GetMapping("/index")
@LoginRequired
public String index() {
return "index.html";
}
}
這里主要定義了兩個(gè)方法晴及。
(1)當(dāng)用戶調(diào)用/verify接口時(shí)都办,如果用戶密碼輸入正確,將用戶信息序列化之后存入Redis緩存中虑稼。
(2)自定義注解標(biāo)記在index()方法琳钉,表示當(dāng)訪問(wèn)該方法時(shí),會(huì)對(duì)登錄狀態(tài)進(jìn)行校驗(yàn)(因?yàn)橹耙呀?jīng)定義過(guò)攔截器對(duì)方法上是否存在自定義注解進(jìn)行判斷)
總結(jié)
這樣當(dāng)用戶請(qǐng)求的操作需要登錄狀態(tài)時(shí)蛛倦,只需要在對(duì)應(yīng)請(qǐng)求的方法上添加注解即可歌懒。這里我使用的是Redis替代了session的功能,意思一樣