目录
一. 退出
1.1 开发控制层
1.2 退出前端
二. 阻止未登录用户(拦截器实现版)
2.1 关于springboot配置类
2.2 使用启动类实现WebMvcConfigurer接口来配置拦截器
2.3 使用启动类或其它配置类中添加返回WebMvcConfigurer对象的方法来实现配置拦截器
2.4 新建带有@Configuration注解的类,既可以作为配置类,配置拦截器
2.5 对axios的配置:
@RestController
@RequestMapping("/security/home")
public class HomeController {
@Autowired
private HomeService homeService;
@GetMapping("/menu")
public Result> userMenuList(HttpSession session){
//sesssion中取出来的数据都是object的
CurrentUser currentUser = (CurrentUser) session.getAttribute(OaConstants.SESSION_NAME_CURRENT_USER);
List menuDtoList = homeService.getUserMenuList(currentUser.getUserId());
return Result.ok(menuDtoList);
}
@DeleteMapping("/exit")
public Result loginout(HttpSession session){
//从session中清除当前用户信息
session.removeAttribute(OaConstants.SESSION_NAME_CURRENT_USER);
return Result.ok();
}
}
退出主要就是从session中清除当前登录用户,所以不涉及业务层和持久层。
/*退出*/
//定义退出函数
const exit = ()=>{
ajax.delete('/security/home/exit').then(result=>{
xTip.success("您已成功退出系统!").then(()=>{
//退出提示结束后,返回登陆页
window.location.href='/login.html';//重新定位到另一个地址
});
});
};
记得导出函数,好绑定在前端退出上。
退出
①:可以新建带有@Configuration注解的类,既可以作为配置类
②:启动类本身就是配置类,内含了@Configuration的作用,作为配置类进行各种配置
③:WebMvc的配置可以通过启动类实现WebMvcConfigurer接口,也可以在启动类或其它配置类中添加返回WebMvcConfigurer对象的方法来实现配置
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xupt.ygq.oa.common.Result;
import com.xupt.ygq.oa.common.page.OaConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
@Slf4j
@SpringBootApplication
@MapperScan("com.xupt.ygq.oa.fun.*.dao")//扫描mybatis映射器,自动放入spring容器中
public class YgqoaApplication2 implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(YgqoaApplication2.class, args);
}
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
/*
* 该方法在controller执行前进行拦截,返回true,不阻止请求,返回false,阻止请求
* */
HandlerInterceptor interceptor = new HandlerInterceptor() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("拦截:{}",request.getServletPath());
/*
* 1.有些地址无条件放行:login.html,/security/login,/assets/**,/css/**,/fonts/**,/js/**。
* 2.有些地址不登陆阻止:其他都需要登录
* */
//1.获取当前请求路径
String path = request.getServletPath();
//2.无条件放行路径
if ("/login.html".equals(path) || "/security/login".equals(path)
||path.startsWith("/assets/")||path.startsWith("/css/")
||path.startsWith("/fonts/")||path.startsWith("/js/")){
return true;
}
//3.登陆放行
HttpSession session = request.getSession();
Object currentUser = session.getAttribute(OaConstants.SESSION_NAME_CURRENT_USER);
if (currentUser!=null){
return true;//放行
}
//4.不放行该怎么办??
/*
* 非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
* Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
* */
/*
* 如何区分是否为ajax请求
* 需要前后端进行配合,前端对ajax请求一个特殊的头数据,后端判断这个特殊的头数据
* 一般习惯上,前端对于ajax请求发送头:X-Requested-With=XMLHttpRequest
* 在axios中配置如下:
* headers:{
* "X-Requested-With":"XMLHttpRequest"
* };
* */
//判断是否为ajax请求 是
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
//Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
Result result = Result.err(Result.CODE_ERR_UNLOGINED,"请登陆后访问");
//将result对象转为json串
ObjectMapper objectMapper = new ObjectMapper();//springMVC提供的转换工具类(可以转json)
String jsonStr = objectMapper.writeValueAsString(result);//对象转为json字符串
//将串输出到浏览器(通过流)
response.setContentType("application/json;charset=UTF-8");//设置字符编码格式
PrintWriter out = response.getWriter();//得到一个字符输出流
out.print(jsonStr);
out.flush();
out.close();
}else{
//非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
//request.getContextPath()获取项目上下文路径(发布路径)
response.sendRedirect(request.getContextPath()+"/login.html");
}
return false;
}
};
//增加一个拦截器
registry.addInterceptor(interceptor);
}
}
首先实现WebMvcConfigurer接口:实现他的addInterceptors方法,添加一个拦截器
使用内部类的方法定义一个HandlerInterceptor(拦截器),实现preHandle方法,在controller执行之前进行拦截,返回结果为true,不阻止请求,返回为false,阻止请求。
接下来就要分析:①:有些地址无条件放行例如登陆页面login.html等
②:有些地址不登陆的话要阻止访问
第一步:通过request对象获取请求路径
第二步:对无条件放行的路径进行放行
第三步:对登录的用户放行
第四步:对没有登录的用户,我们要看它是以什么请求方式请求的
①:非ajax请求怎么办,(例如对html,图片,js等静态资源访问)重定向
②:ajax请求,发送标准化的响应数据(如本案例中的Result对象)
如何区分是不是ajax请求呢?
需要前后端进行配合,前端给ajax请求一个特殊的头数据,后端判断这个特殊的头数据
一般习惯上,前端对于ajax请求发送头:X-Requested-With=XMLHttpRequest
在axios中配置如下: headers:{ "X-Requested-With":"XMLHttpRequest" };
接下里就是分别进行处理
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xupt.ygq.oa.common.Result;
import com.xupt.ygq.oa.common.page.OaConstants;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
@Slf4j
@SpringBootApplication
@MapperScan("com.xupt.ygq.oa.fun.*.dao")//扫描mybatis映射器,自动放入spring容器中
public class YgqoaApplication {
public static void main(String[] args) {
SpringApplication.run(YgqoaApplication.class, args);
}
@Bean //注释掉bean,该mvc配置不再生效
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
/*
* 该方法在controller执行前进行拦截,返回true,不阻止请求,返回false,阻止请求
* */
HandlerInterceptor interceptor = new HandlerInterceptor() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("拦截:{}",request.getServletPath());
/*
* 1.有些地址无条件放行:login.html,/security/login,/assets/**,/css/**,/fonts/**,/js/**。
* 2.有些地址不登陆阻止:其他都需要登录
* */
//1.获取当前请求路径
String path = request.getServletPath();
//2.无条件放行路径
if ("/login.html".equals(path) || "/security/login".equals(path)
||path.startsWith("/assets/")||path.startsWith("/css/")
||path.startsWith("/fonts/")||path.startsWith("/js/")){
return true;
}
//3.登陆放行
HttpSession session = request.getSession();
Object currentUser = session.getAttribute(OaConstants.SESSION_NAME_CURRENT_USER);
if (currentUser!=null){
return true;//放行
}
//4.不放行该怎么办??
/*
* 非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
* Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
* */
/*
* 如何区分是否为ajax请求
* 需要前后端进行配合,前端对ajax请求一个特殊的头数据,后端判断这个特殊的头数据
* 一般习惯上,前端对于ajax请求发送头:X-Requested-With=XMLHttpRequest
* 在axios中配置如下:
* headers:{
* "X-Requested-With":"XMLHttpRequest"
* };
* */
//判断是否为ajax请求 是
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
//Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
Result result = Result.err(Result.CODE_ERR_UNLOGINED,"请登陆后访问");
//将result对象转为json串
ObjectMapper objectMapper = new ObjectMapper();//springMVC提供的转换工具类(可以转json)
String jsonStr = objectMapper.writeValueAsString(result);//对象转为json字符串
//将串输出到浏览器(通过流)
response.setContentType("application/json;charset=UTF-8");//设置字符编码格式
PrintWriter out = response.getWriter();//得到一个字符输出流
out.print(jsonStr);
out.flush();
out.close();
}else{
//非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
//request.getContextPath()获取项目上下文路径(发布路径)
response.sendRedirect(request.getContextPath()+"/login.html");
}
return false;
}
};
//增加一个拦截器
registry.addInterceptor(interceptor);
}
};
}
}
注意Bean注解:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xupt.ygq.oa.common.Result;
import com.xupt.ygq.oa.common.page.OaConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
@Slf4j
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
/*
* 该方法在controller执行前进行拦截,返回true,不阻止请求,返回false,阻止请求
* */
HandlerInterceptor interceptor = new HandlerInterceptor() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("MvcConfig-拦截:{}",request.getServletPath());
/*
* 1.有些地址无条件放行:login.html,/security/login,/assets/**,/css/**,/fonts/**,/js/**。
* 2.有些地址不登陆阻止:其他都需要登录
* */
//1.获取当前请求路径
String path = request.getServletPath();
//2.无条件放行路径
if ("/login.html".equals(path) || "/security/login".equals(path)
||path.startsWith("/assets/")||path.startsWith("/css/")
||path.startsWith("/fonts/")||path.startsWith("/js/")){
return true;
}
//3.登陆放行
HttpSession session = request.getSession();
Object currentUser = session.getAttribute(OaConstants.SESSION_NAME_CURRENT_USER);
if (currentUser!=null){
return true;//放行
}
//4.不放行该怎么办??
/*
* 非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
* Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
* */
/*
* 如何区分是否为ajax请求
* 需要前后端进行配合,前端对ajax请求一个特殊的头数据,后端判断这个特殊的头数据
* 一般习惯上,前端对于ajax请求发送头:X-Requested-With=XMLHttpRequest
* 在axios中配置如下:
* headers:{
* "X-Requested-With":"XMLHttpRequest"
* };
* */
//判断是否为ajax请求 是
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
//Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
Result result = Result.err(Result.CODE_ERR_UNLOGINED,"请登陆后访问");
//将result对象转为json串
ObjectMapper objectMapper = new ObjectMapper();//springMVC提供的转换工具类(可以转json)
String jsonStr = objectMapper.writeValueAsString(result);//对象转为json字符串
//将串输出到浏览器(通过流)
response.setContentType("application/json;charset=UTF-8");//设置字符编码格式
PrintWriter out = response.getWriter();//得到一个字符输出流
out.print(jsonStr);
out.flush();
out.close();
}else{
//非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
//request.getContextPath()获取项目上下文路径(发布路径)
response.sendRedirect(request.getContextPath()+"/login.html");
}
return false;
}
};
registry.addInterceptor(interceptor);
}
}
特别注意:过滤器要比拦截器先生效
①:启动类加注解@ServletComponentScan()扫描过滤器所在的包
②:开发过滤器,实现Filter接口,实现doFilter方法
@Slf4j
@WebFilter("/*")
public class SecurityFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.debug("--过滤器{}启动了---",this.getClass().getName());
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
log.debug("SecurityFilter-拦截:{}",request.getServletPath());
/*
* 1.有些地址无条件放行:login.html,/security/login,/assets/**,/css/**,/fonts/**,/js/**。
* 2.有些地址不登陆阻止:其他都需要登录
* */
//1.获取当前请求路径
String path = request.getServletPath();
//2.无条件放行路径
if ("/login.html".equals(path) || "/security/login".equals(path)
||path.startsWith("/assets/")||path.startsWith("/css/")
||path.startsWith("/fonts/")||path.startsWith("/js/")){
chain.doFilter(request,response);//放行//放行
return;
}
//3.登陆放行
HttpSession session = request.getSession();
Object currentUser = session.getAttribute(OaConstants.SESSION_NAME_CURRENT_USER);
if (currentUser!=null){
chain.doFilter(request,response);//放行
return;
}
//4.不放行该怎么办??
/*
* 非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
* Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
* */
/*
* 如何区分是否为ajax请求
* 需要前后端进行配合,前端对ajax请求一个特殊的头数据,后端判断这个特殊的头数据
* 一般习惯上,前端对于ajax请求发送头:X-Requested-With=XMLHttpRequest
* 在axios中配置如下:
* headers:{
* "X-Requested-With":"XMLHttpRequest"
* };
* */
//判断是否为ajax请求 是
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
//Ajax请求,发送标准化的响应数据(如本案例中的Result对象)
Result result = Result.err(Result.CODE_ERR_UNLOGINED,"请登陆后访问");
//将result对象转为json串
ObjectMapper objectMapper = new ObjectMapper();//springMVC提供的转换工具类(可以转json)
String jsonStr = objectMapper.writeValueAsString(result);//对象转为json字符串
//将串输出到浏览器(通过流)
response.setContentType("application/json;charset=UTF-8");//设置字符编码格式
PrintWriter out = response.getWriter();//得到一个字符输出流
out.print(jsonStr);
out.flush();
out.close();
}else{
//非ajax请求怎么办,重定向(例如对html,图片,js等静态资源访问)
//request.getContextPath()获取项目上下文路径(发布路径)
response.sendRedirect(request.getContextPath()+"/login.html");
}
}
}
过滤器在放行的时候,要调用doFilter方法,之后要return,否则会一直执行下去