1.用戶登錄權(quán)限校驗(yàn)
1.1最初用戶登錄
@RestController
@RequestMapping("/user2")
public class User2Controller {
/**
*
* 某方法1
*/
@RequestMapping("/m")
public Object method(HttpServletRequest request){
//有session就獲取,沒(méi)有不會(huì)創(chuàng)建
HttpSession session=request.getSession(false);
if(session!=null&&session.getAttribute("userinfo")!=null){
//說(shuō)明已經(jīng)登錄,業(yè)務(wù)處理
return true;
}else {
return false;
}
}
/**
*某方法2
*/
@RequestMapping("/m2")
public Object method2(HttpServletRequest request){
HttpSession session=request.getSession(false);
if(session!=null&&session.getAttribute("userinfo")!=null){
return true;
}else {
return false;
}
}
}
2Spring AOP用戶統(tǒng)一登錄驗(yàn)證的問(wèn)題
@Slf4j
@Aspect//定義了一個(gè)切點(diǎn)
@Component //演示統(tǒng)一功能,先去掉
public class LoginAspect {
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object oj=null;
long start=System.currentTimeMillis();
//調(diào)用目標(biāo)方法
try {
//執(zhí)行連接點(diǎn)的方法
oj = joinPoint.proceed();
} catch (Throwable e) {
throw e;
}
log.info(joinPoint.getSignature().toString()+"耗時(shí):"(System.currentTimeMillis()-start));
//必須要寫(xiě)返回結(jié)果
return oj;
}
@Before("execution(* com.example.springaopdemo.controller.TestController.* (..))")
public void before2(){
log.info("before");
}
}
3Spring攔截器
3.1自定義攔截器
/**
* 創(chuàng)建一個(gè)攔截器
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判斷是否登錄
HttpSession session=request.getSession(false);
if(session!=null&&session.getAttribute("username")!=null){
//通過(guò),不進(jìn)行處理
return true;
}
//表示沒(méi)有權(quán)限
response.setStatus(401);
return false;
}
}
3.2將自定義攔截器加入到系統(tǒng)配置
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
//添加攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加攔截器
registry.addInterceptor(loginInterceptor)
//攔截哪些url
.addPathPatterns("/**")
//放過(guò)哪些url
.excludePathPatterns("/api/user/login")
.excludePathPatterns("/api/user/reg");
}
// 所有的接?添加 api 前綴
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("api", c -> true);
}
}
// 攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 攔截所有接?
.excludePathPatterns("/**/*.js")
.excludePathPatterns("/**/*.css")
.excludePathPatterns("/**/*.jpg")
.excludePathPatterns("/login.html")
.excludePathPatterns("/**/login"); // 排除接?
}
登錄攔截器:
@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping("/get")
//獲取用戶信息
public String getInfo(){
log.info("get info");
return "get info";
}
//注冊(cè)
@RequestMapping("/reg")
public String reg(){
log.info("reg");
// int a=10/0;
return "reg";
}
@RequestMapping("/login")
public boolean login(HttpServletRequest request,String username,String password){
log.info("login");
//判斷username和password是否為空
// if(username!=null && "".equals(username)&& password!=null &&"".equals(password)){
//
// }
//Spring
if(!StringUtils.hasLength(username)||!StringUtils.hasLength(password)){
return false;
}
if(!"admin".equals(username) || !"admin".equals(password)) {
return true;
}
HttpSession session = request.getSession(true);
session.setAttribute("username", username);
return true;
}
}
直接訪問(wèn)get會(huì)被攔截,表示攔截器創(chuàng)建成功
4攔截器實(shí)現(xiàn)原理
正常情況下的調(diào)?順序:
?
然?有了攔截器之后,會(huì)在調(diào)? Controller 之前進(jìn)?相應(yīng)的業(yè)務(wù)處理,執(zhí)?的流程如下圖所示:
?
4.1 實(shí)現(xiàn)原理源碼分析

?所有?法都會(huì)執(zhí)? DispatcherServlet 中的 doDispatch 調(diào)度?法,doDispatch 源碼如下:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
// 調(diào)用預(yù)處理【重點(diǎn)】
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 執(zhí)行Contorller層的邏輯
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
// 獲取項(xiàng)目中使用的攔截器, 我們之前就是實(shí)現(xiàn)了這個(gè)類,然后添加的攔截器
// 在這里,我們自定義的攔截器就會(huì)被調(diào)用,用戶登陸權(quán)限驗(yàn)證的方法就會(huì)實(shí)現(xiàn),這就是攔截器實(shí)現(xiàn)的原理
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
if (!interceptor.preHandle(request, response, this.handler)) {
this.triggerAfterCompletion(request, response, (Exception)null);
return false;
}
}
return true;
}

?此時(shí)?戶登錄權(quán)限的驗(yàn)證?法就會(huì)執(zhí)?,這就是攔截器的實(shí)現(xiàn)原理。
?4.2攔截器小結(jié)

5拓展:統(tǒng)一前綴訪問(wèn)
所有請(qǐng)求地址添加 api 前綴:?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-638156.html
// 所有的接?添加 api 前綴
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("api", c -> true);
}

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-638156.html
到了這里,關(guān)于Spring Boot統(tǒng)一處理功能——攔截器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!