4.0.0
com.weichai
SpringSession
0.0.1-SNAPSHOT
war
SpringSession
http://maven.apache.org
org.springframework.boot
spring-boot-starter-parent
2.0.0.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
2.0.0.RELEASE
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.0
mysql
mysql-connector-java
6.0.5
org.springframework.boot
spring-boot-starter-data-redis
2.0.0.RELEASE
org.springframework.session
spring-session-data-redis
org.springframework.session
spring-session
1.3.5.RELEASE
com.alibaba
fastjson
1.2.24
junit
junit
3.8.1
test
src/main/java
**/*.properties
**/*.xml
false
src/main/resources
**/*.properties
**/*.xml
false
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6380
spring.redis.password=123456
spring.redis.pool.max-active=10
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=10
spring.redis.pool.min-idle=0
spring.redis.timeout=2000
server.session.timeout=1800
mybatis.mapper-locations=classpath:mappings/modules/user/*.xml
server.port=8090
package com.weichai.SpringSession.entity;
import java.io.Serializable;
public class User implements Serializable {
private Integer id;
private String userName;
private String userPwd;
private Integer age;
private String address;
public User(Integer id, String userName, String userPwd, Integer age, String address) {
super();
this.id = id;
this.userName = userName;
this.userPwd = userPwd;
this.age = age;
this.address = address;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + ", age=" + age + ", address="
+ address + "]";
}
}
package com.weichai.SpringSession.entity;
import java.io.Serializable;
/**
* 数据接口返回结果
* @author linhaiy
* @date 2019.03.01
* @param
*/
public class ResponseResult implements Serializable {
public static final int STATE_ERROR=-1;
public static final int STATE_OK=1;
private static final long serialVersionUID = 2158690201147047546L;
private int status; //返回状态
private String message; //返回信息
private T data; //返回数据
public ResponseResult() {
super();
// TODO Auto-generated constructor stub
}
public ResponseResult(int status, String message, T data) {
super();
this.status = status;
this.message = message;
this.data = data;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((message == null) ? 0 : message.hashCode());
result = prime * result + status;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ResponseResult other = (ResponseResult) obj;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data))
return false;
if (message == null) {
if (other.message != null)
return false;
} else if (!message.equals(other.message))
return false;
if (status != other.status)
return false;
return true;
}
@Override
public String toString() {
return "ResponseResult [status=" + status + ", message=" + message + ", data=" + data + "]";
}
}
a.id as "id",
a.userName as "userName",
a.userPwd as "userPwd",
a.age as "age",
a.address as "address"
package com.weichai.SpringSession.dao;
import com.weichai.SpringSession.entity.User;
public interface UserDao {
public User findByUserNameAndUserPwd(String userName,String userPwd);
public User findById(Integer id);
}
package com.weichai.SpringSession.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.weichai.SpringSession.dao.UserDao;
import com.weichai.SpringSession.entity.User;
@Service
public class UserService {
@Resource
private UserDao userDao;
public User findByUserNameAndUserPwd(String userName,String userPwd) {
return userDao.findByUserNameAndUserPwd(userName, userPwd);
}
public User findById(Integer id) {
return userDao.findById(id);
}
}
package com.weichai.SpringSession.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
* 添加@EnableRedisHttpSession来开启spring session支持
* @author linhaiy
* @date 2019.03.01
*/
@Configuration
//maxInactiveIntervalInSeconds 默认是1800秒过期,这里测试修改为60秒
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60)
public class RedisSessionConfig {
}
package com.weichai.SpringSession.config;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSONObject;
import com.weichai.SpringSession.entity.ResponseResult;
/**
* 登录状态拦截器RedisSessionInterceptor
* @author linhaiy
* @date 2019.03.01
*/
public class RedisSessionInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisTemplate;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 无论访问的地址是不是正确的,都进行登录验证,登录成功后的访问再进行分发,404的访问自然会进入到错误控制器中
HttpSession session = request.getSession();
if (session.getAttribute("loginSessionId") != null) {
try {
// 验证当前请求的session是否是已登录的session
String loginSessionId = redisTemplate.opsForValue()
.get("loginUser:" + (Integer) session.getAttribute("loginSessionId"));
System.out.println("用户已登录,sessionId为: " + loginSessionId);
if (loginSessionId != null && loginSessionId.equals(session.getId())) {
return true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
response401(response);
return false;
}
private void response401(HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try {
System.out.println("用户未登录!");
response.getWriter().print(JSONObject.toJSONString(new ResponseResult<>(404, "用户未登录!", null)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
package com.weichai.SpringSession.config;
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.WebMvcConfigurerAdapter;
/**
* Session配置拦截器
* @author linhaiy
* @date 2019.03.01
*/
@Configuration
public class WebSecurityConfig extends WebMvcConfigurerAdapter {
@Bean
public RedisSessionInterceptor getSessionInterceptor() {
return new RedisSessionInterceptor();
}
public void addInterceptors(InterceptorRegistry registry) {
// 所有已api开头的访问都要进入RedisSessionInterceptor拦截器进行登录验证,并排除login接口(全路径)。必须写成链式,分别设置的话会创建多个拦截器。
// 必须写成getSessionInterceptor(),否则SessionInterceptor中的@Autowired会无效
registry.addInterceptor(getSessionInterceptor()).addPathPatterns("/api/**")
.excludePathPatterns("/api/user/login");
super.addInterceptors(registry);
}
}
package com.weichai.SpringSession.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 多端口,多浏览器session共享测试类
* 可以开启多个端口,如8088,8090,8080等几个端口测试以下接口,发现获取的session是一致的,说明redis实现了session共享
* @author linhaiy
*
*/
@RestController
@RequestMapping("/Spring")
public class HelloController {
@RequestMapping("/getSessionId")
@ResponseBody
public Map SessionIdTest(HttpServletRequest request){
Map sessionIdMap = new HashMap();
String SessionId = request.getSession().getId(); //获取SessionId
int Port = request.getServerPort();
sessionIdMap.put("服务器端口:", Port);
sessionIdMap.put("sessionId:", SessionId);
return sessionIdMap;
}
@RequestMapping(value = "setSessionId", method = RequestMethod.GET)
@ResponseBody
public Map SetSessionId (HttpServletRequest request){
request.getSession().setAttribute("SessionKey", "Haige");
Map map = new HashMap<>();
map.put("SessionKey", "Haige");
return map;
}
@RequestMapping(value = "getSessionId", method = RequestMethod.GET)
@ResponseBody
public Object GetSessionId(HttpServletRequest request) {
Map map = new HashMap<>();
map.put("sessionId", request.getSession().getId());
map.put("SessionKey", request.getSession().getAttribute("SessionKey"));
return map;
}
}
package com.weichai.SpringSession.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.weichai.SpringSession.entity.ResponseResult;
import com.weichai.SpringSession.entity.User;
import com.weichai.SpringSession.service.UserService;
/**
* 单点登录测试类
* @author linhaiy
*
*/
@RestController
@RequestMapping(value = "/api/user")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private StringRedisTemplate redisTemplate;
@RequestMapping("/login")
public ResponseResult login(HttpServletRequest request, String userName,String userPwd){
User user = userService.findByUserNameAndUserPwd(userName, userPwd);
ResponseResult resData = new ResponseResult<>();
if(user !=null) {
HttpSession session = request.getSession();
session.setAttribute("loginSessionId", user.getId());
redisTemplate.opsForValue().set("loginUser:" + user.getId(), session.getId());
resData.setData(user);
resData.setStatus(0);
resData.setMessage("登录成功!");
}else {
resData.setData(null);
resData.setStatus(1);
resData.setMessage("用户信息输入错误!");
}
return resData;
}
@RequestMapping(value = "/getUserInfo")
public ResponseResult get(Integer id) {
User user = userService.findById(id);
ResponseResult resData = new ResponseResult<>();
if (user != null)
{
resData.setData(user);
resData.setStatus(0);
resData.setMessage("查询成功!");
}
else
{
resData.setData(user);
resData.setStatus(1);
resData.setMessage("没有符合该查询条件的数据!");
}
return resData;
}
}
HttpSession session = request.getSession();
session.setAttribute("loginSessionId", user.getId());
redisTemplate.opsForValue().set("loginUser:" + user.getId(), session.getId());