之前写后台主要是用jsp写的,所以直接在页面上使用java比较方便,然后禁止非登录用户查看页面也比较快捷,直接在jsp里面判断session就好了,但是页面少的话还行,但是页面一多后续修改就会变得比较麻烦。
另一方面近些项目都是使用springboot写了,springboot要想直接访问jsp就需要再配置一下,但是本来页面上的那些循环都已经用vue完成了,然后我是觉得jsp本身也不够简练,莫名其妙的喜欢纯粹的html,所以就找了个拦截器看看。
搞拦截器的话本质上在捕获所有的请求之后会加入一个判断机制,在判断机制中写入session的判断就好了,很简单,逻辑也很简洁,首先是拦截器的主体:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LinsHandlerInterceptor2 implements HandlerInterceptor {
private static Logger log= LoggerFactory.getLogger(LinsHandlerInterceptor2.class);
//这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//logconfirm是提交时登录页面HttpServletRequest request保存进session的确认信息
String logconfirm = (String) request.getSession().getAttribute("logconfirm");
if(logconfirm=="0" || logconfirm==null){
log.info("用户未登录,返回登录页面!");
// 服务器内部转发,sign-in.html为登录页面,如果没有登陆就都回到登录页面
request.getRequestDispatcher("/sign-in.html").forward(request, response);
return false;
}else{
//返回true才会往下执行
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
然后为了让拦截器生效,需要在程序中注册拦截器:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebMvcCofig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截规则:除了sign-in.html,其他都拦截判断
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(new LinsHandlerInterceptor2()).
addPathPatterns("/**").
excludePathPatterns("/sign-in.html","/css/signin.css","/simpleselect/Login","/login");
}
}
但是呢,到这里还没有结束,因为发现一个问题,就是浏览器会有缓存,本来如果各个页面都是独立的倒也好说,在访问页面的时候就直接转发到sign-in.html了,但是好巧不巧我是用iframe内嵌网页搞的,本来是如果登陆成功的话,就会重定向到index.html里面,但是我的index.html的主体是这样的:
<body>
<header class="p-3 bg-dark text-white">
<!-- <div class="container" style="padding:0">-->
<div class="row" style="padding-left: 2rem">
<a href="#" class="col-lg-8 text-white text-decoration-none">
<span class="fs-4" ><b>test</b></span>
</a>
<!-- <span class="col-lg-4"></span>-->
<ul class="nav nav-pills col-lg-4" style="float: right;">
<!-- <li class="nav-item"><a href="#" class="nav-link active" aria-current="page">Home</a></li>-->
<li class="nav-item"><a href="#" class="nav-link" onclick="$('iframe')[0].src='index2.html'">主页</a></li>
<li class="nav-item"><a href="#" class="nav-link" onclick="$('iframe')[0].src='index3.html'">test1</a></li>
<li class="nav-item"><a href="#" class="nav-link" onclick="$('iframe')[0].src='index4.html'">test2</a></li>
<li class="nav-item"><a href="#" class="nav-link" onclick="$('iframe')[0].src='index5.html'">test3</a></li>
<li class="nav-item" style="margin-left:7rem;font-size:10px;"><a href="#" class="nav-link" style="color:#b1a3a3" >测试版</a></li>
</ul>
</div>
<!-- </div>-->
</header>
<iframe src="index2.html"></iframe>
</body>
所以就导致,只要这个浏览器之前成功登录了一次,后续再打开网页即使这次的使用者没有登录,但是输入index.html,这时就会出现虽然index2.html被转发称为了sign-up.html的页面,但是<header></header>中的内容已经加载出来了,就很奇怪,这不合理,本来也不是什么大事儿,但是不好看,所以我索性直接禁止页面缓存了,加了三行头:
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
然后才算是解决了吧。