Http是一种无状态的应用层传输协议。可以理解成请求之间没有联系。但是很多场景,比如需要知道上次是哪个用户登录了。这时就要用到cookie和session了。 一. Cookie Cookie是一种客户端技术,可以理解成用户信息存储在客户端。客户端第一次请求服务器时,如果需要记录用户状态,就用response特意给客户端生成一个Cookie,客户端会自动保存起来。当再次请求时,客户端把Cookie也提交给服务器。服务器通过request拿到cookie,就可以判断用户状态。下面举个简单的代码应用。
//自定义拦截器,要结合MyWebConfig使用 @Component public class CookieInterceptor implements HandlerInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(CookieInterceptor.class); /** * 在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理; */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("CookieInterceptor preHandle"); String requestURI = request.getRequestURI(); Cookie[] cookies = request.getCookies(); //1.如果是登录接口,则设置cookie if (requestURI.contains("/loginInfo/login")) { response.addCookie(new Cookie("hasLogined", "true")); //2.如果不是登录接口,则校验有无cookie } else { boolean flag = false; if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("hasLogined")) { flag = true; break; } } } if (!flag) { LOGGER.error("please login first"); return false; } } return true; }举例代码里,我们把Cookie处理放在拦截器里,一般项目里也都可以这样处理,拦截器可以用请求做一些预处理,比如这里用Cookie校验用户的登录状态。如果请求是登录接口,那么生成一个Cookie(客户端可以存储多个cookie),用response.addCookie方法即可传给客户端。当不是登录的请求过来时,就先从request里拿到所有Cookie,看看是否有用户登录状态,如果没有直接被拦截。这里只是个简单的应用,实际场景会相对复杂,也可以给cookie设置域,存活时间等。 二. Session Session是一种服务器端技术,可以理解成把用户登录状态存在服务器端。登录接口里,服务器生成一个Session,里面可以保存用户信息。当请求业务接口时,先获取Session,再进一步核对用户信息。那么客户端是怎么获取到Session的呢,实际上Session还是要配合Cookie使用,在生成Session时候,底层会把这个Session对应的SessionId存到Cookie中传给客户端,再次请求时就可以拿到SessionId去服务器里找对应的Session。下面举个简单的代码应用。
private Set<String> sessionIds = Sets.newHashSet(); /** * 在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理; */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("SessionInterceptor preHandle"); String requestURI = request.getRequestURI(); //1.如果是登录接口,则设置session if (requestURI.contains("/loginInfo/login")) { // 用户登陆时如果携带了sessionid,则先将session做invalid处理 HttpSession session = request.getSession(false); if (null != session) { session.invalidate(); } // ture,则如果获取不到session,会生成一个;因为上面已失效,所以这里会新生成一个 session = request.getSession(true); String sessionId = session.getId(); System.out.println("preHandle sessionId=" + sessionId); //可以将sessionID存到数据库,redis,内存中;分布式场景中一般会存到redis;此处存在内存中 sessionIds.add(sessionId); //额外业务 InfoVO infoVO = new InfoVO(); infoVO.setName("libai"); session.setAttribute("myKey",infoVO); } else { String sessionId = request.getSession().getId(); System.out.println("request sessionId = " + sessionId); if (!sessionIds.contains(sessionId)) { LOGGER.error("please login first"); return false; } //额外业务 HttpSession session = request.getSession(); InfoVO myKey =(InfoVO) session.getAttribute("myKey"); System.out.println(myKey); } return true; }同样把Session处理放到拦截器里。可以看到生成Session很简单,就是request.getSession(boolean flag)。flag为false表示获取Session,如果获取不到为null。如果flag为true,如果获取不到,则新生成一个Session。上面的业务场景每次登陆都把原来的Session失效,新生成一个Session。然后把Session对应的SessionId(随机生成的字符串,大概长这样:D8F5058D22978D71D14644777571AD18)存到内存里。再次请求时,Cookie就会附带SessionId(叫JSESSIONID),简单的场景用SessionId就可以判断登陆状态了。复杂场景里,也可以把真个用户信息放到Session里,如上面代码里注释的额外业务里。 三. 总结 Cookie有安全问题,因为用户信息直接放到客户端,可以被别人看到。另外Cookie存的信息也有限。 Session有性能问题,因为Session一般也会存额外一些信息,比如可以存购物车信息,存在服务器端,用占用服务器的性能。 标签:Session,理解,request,session,Cookie,cookie,客户端 From: https://www.cnblogs.com/zeenzhou/p/17601368.html