问题
设置后台接口session超时
过程
本来想用Spring Session+Spring Security来实现,在实现过程中,最后遇到Spring Security检验session超时后,提示自定义json响应没有处理成功。最后,就放弃Spring Security,使用一个HandlerInterceptor拦截器来拦截所有请求,解决session超时响应自定义json问题。
解决
Spring Session
在pom.xml设置如下:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
</dependencies>
在application.yml文件,设置如下:
server:
servlet:
session:
timeout: 30s
spring:
session:
store-type: redis
redis:
flush-mode: on_save
namespace: myapp:session
redis:
host: localhost
port: 6379
password: passwd
这样就保证让Spring Session能够使用Redis来保存Session相关数据。
HandlerInterceptor
自定义拦截器,拦截所有请求(除了登录接口),检查session中是否存在有效用户数据,如下:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
public class SessionTimeOutInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
// 获取登录的session信息
Object user = session.getAttribute("userinfor");
if (user != null) {
return true;
} else {
// 未登录自动跳转界面
// response.sendRedirect(request.getContextPath() + "/login.do");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print(
new ObjectMapper()
.writeValueAsString(Result.builder().code("200").message("请先登录").build()));
out.flush();
return false;
}
}
}
配置拦截器
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 WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SessionTimeOutInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/api/login")
// swagger-ui
.excludePathPatterns("/swagger-resources/**", "/webjars/**",
"/v2/**", "/swagger-ui.html/**");
}
}
模拟登录
写入session
@RestController
@RequestMapping("/api")
public class Controller {
@Resource
private ObjectMapper jacksonObjectMapper;
@PostMapping("/login")
public ResponseEntity<?> login(HttpSession session, @RequestBody UserInfor userInfor) throws JsonProcessingException {
session.setAttribute("userinfor", jacksonObjectMapper.writeValueAsString(userInfor));
return ResponseEntity.ok().build();
}
}
项目地址
https://github.com/fxtxz2/spring-session-redis-timeout