一、会话管理

  会话管理: 管理浏览器客户端 和 服务器端之间会话过程中产生的会话数据。

  域对象: 实现资源之间的数据共享。

  request域对象

  context域对象

  会话技术:  

    Cookie技术:会话数据保存在浏览器客户端。

    Session技术:会话数据保存在服务器端。存放在内存里面,客户端与服务器端之前的通讯使用SessionId

二、Cookie技术

2.1 特点:Cookie技术:会话数据保存在浏览器客户端。

2.2 Cookie技术核心

  Cookie类:用于存储会话数据

    1)构造Cookie对象

      New  Cookie(java.lang.String name, java.lang.String value)

    2)设置cookie

      void setPath(java.lang.String uri)   :设置cookie的有效访问路径

      void setMaxAge(int expiry) : 设置cookie的有效时间

      void setValue(java.lang.String newValue) :设置cookie的值

    3)发送cookie到浏览器端保存

      void response.addCookie(Cookie cookie)  : 发送cookie

    4)服务器接收cookie

      Cookie[] request.getCookies()  : 接收cookie

2.3 Cookie原理

  1)服务器创建cookie对象,把会话数据存储到cookie对象中。

    new Cookie("name","value");

  2)  服务器发送cookie信息到浏览器

    response.addCookie(cookie);

    举例: set-cookie: name=eric  (隐藏发送了一个set-cookie名称的响应头)

  3)浏览器得到服务器发送的cookie,然后保存在浏览器端。

  4)浏览器在下次访问服务器时,会带着cookie信息

    举例: cookie: name=eric  (隐藏带着一个叫cookie名称的请求头)

  5)服务器接收到浏览器带来的cookie信息

    request.getCookies();

2.4 Coolie的细节  

  1)void setPath(java.lang.String uri)   :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。

  2)void setMaxAge(int expiry) : 设置cookie的有效时间。

    正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。

    负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!

    零:表示删除同名的cookie数据

  3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

2.5 Cookie 问题

  1) cookie不能跨浏览器

  2)浏览器关闭,默认失效cookie

  3)127.0.0.1和localhost,操作cookie时不共享

2.6 Cookie的局限:

  1)Cookie只能存字符串类型,不能保存对象

  2)只能存非中文

  3)1个cookie的容量不超过4KB

2.7 案例-显示用户上次访问时间

@WebServlet("/LastAccessTime")
public class LastAccessTime extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");// 防止浏览器显示乱码
String lastAccessTime = null;
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals("lastAccessTime")) {
lastAccessTime = cookie.getValue();
break;
}
}
if (StringUtils.isEmpty(lastAccessTime)) {
resp.getWriter().print("您是首次访问!");
} else {
resp.getWriter().print("你上次访问时间:" + lastAccessTime);
}
// 保存访问时间
// 创建cookie 将当前时间作为cookie保存到浏览器
String currenttime = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(new Date());
Cookie cookie = new Cookie("lastAccessTime", currenttime);
cookie.setMaxAge(60 * 60 * 24);
// 发送cookie
resp.addCookie(cookie);
}
String addCookie(String key, String value, HttpServletResponse resp) {
return key;
}
}

三、Session技术

3.1 由于Cookie的局限性和问题,想要突破这些限制只能使用session技术!

  Session特点:会话数据保存在服务器端。(内存中)

3.2 Session 技术核心

  HTTPSession类:用于保存会话数据

  1)创建或得到session对象

    HttpSession getSession()

    HttpSession getSession(boolean create)   //true,没有session,会创建。False则不会创建

  2)设置session对象

    void setMaxInactiveInterval(int interval)  : 设置session的有效时间

    void invalidate()     : 销毁session对象

    java.lang.String getId()  : 得到session编号

  3)保存会话数据到session对象

    void setAttribute(java.lang.String name, java.lang.Object value)  : 保存数据

    java.lang.Object getAttribute(java.lang.String name)  : 获取数据

    void removeAttribute(java.lang.String name) : 清除数据

3.3 Session原理

  服务器端创建session,通过响应头将sessionId保存到客户端本地。客户端通过请求头,将sessionId传递到服务器端。

  关闭浏览器只会清楚客户端的sessionID,服务器端的session由创建时的时间失效决定。

代码解读:HttpSession session = request.getSession();

  1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID

     new HttpSession();

  2)把JSESSIONID作为Cookie的值发送给浏览器保存

    Cookie cookie = new Cookie("JSESSIONID", sessionID);

    response.addCookie(cookie);

  3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器

  4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。

    if(找到){

      return map.get(sessionID);

    }else{

      new HttpSession();

    }

  5)如果找到对应编号的session对象,直接返回该对象

  6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程

  结论:通过JSESSION的cookie值在服务器找session对象!

3.4 Session细节

  1)java.lang.String getId()  : 得到session编号

  2)两个getSession方法:

    getSession(true) / getSession()  : 创建或得到session对象。没有匹配的session编号,自动创建新的session对象。

    getSession(false):              得到session对象。没有匹配的session编号,返回null

  3)void setMaxInactiveInterval(int interval)  : 设置session的有效时间

    session对象销毁时间:

    3.1 默认情况30分服务器自动回收

    3.2 修改session回收时间

    3.3 全局修改session有效时间

<!-- 修改session全局有效时间:分钟 -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>

    3.4.手动销毁session对象  

      void invalidate()     : 销毁session对象

  4)如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题

  /**
  * 手动发送一个硬盘保存的cookie给浏览器
  */
  Cookie c = new Cookie("JSESSIONID",session.getId());
  c.setMaxAge(60*60);
  response.addCookie(c);

总结:

  1)会话管理: 浏览器和服务器会话过程中的产生的会话数据的管理。

  2)Cookie技术:

    new Cookie("name","value")

    response.addCookie(coookie)

    request.getCookies()

  3)Session技术

    request.getSession();

    setAttrbute("name","会话数据");

    getAttribute("会话数据")

四、自定义缓存

4.1定义缓存实体类

public class Cache {
public Cache(String key, Object value, Long timeOut) {
super();
this.key = key;
this.value = value;
this.timeOut = timeOut;
}
public Cache() {
}
/**
* key
*/
private String key;
/**
* 缓存数据
*/
private Object value;
/**
* 超时时间
*/
private Long timeOut;
}

4.2 定义缓存类

/**
* @classDesc: 功能描述:(缓存map)
*/
public class CacheManager {
private Map<String, Cache> cacheMap = new HashMap<>();
/**
* @methodDesc: 功能描述:(往缓存存值)
*/
public void put(String key, Object oj) {
put(key, oj, null);
}
/**
* @methodDesc: 功能描述:(往缓存存值)
*/
public synchronized void put(String key, Object oj, Long timeOut) {
if (oj == null) {
return;
}
Cache cache = new Cache();
cache.setKey(key);
if (timeOut != null)
cache.setTimeOut(timeOut + System.currentTimeMillis());
cache.setValue(oj);
cacheMap.put(key, cache);
}
/**
* @methodDesc: 功能描述:(删除)
*/
public synchronized void deleteCache(String key) {
cacheMap.remove(key);
}
/**
* @methodDesc: 功能描述:(获取缓存中数据)
*/
public synchronized Object get(String key) {
Cache cache = cacheMap.get(key);
Object oj = null;
if (cache != null) {
oj = cache.getValue();
}
return oj;
}
/**
* @methodDesc: 功能描述:(检查数据是否在有效期内)
*/
public synchronized void checkValidityData() {
for (String key : cacheMap.keySet()) {
Cache cache = cacheMap.get(key);
Long timeOut = cache.getTimeOut();
if (timeOut == null) {
return;
}
long currentTime = System.currentTimeMillis();
long endTime = timeOut;
long result = (currentTime - endTime);
if (result > 0) {
System.out.println("清除:"+key);
cacheMap.remove(key);
}
}
}
public static void main(String[] args) throws InterruptedException {
CacheManager cacheManager = new CacheManager();
// cacheManager.put("lisi", 0);
cacheManager.put("zhangsan", "jj", 5000l);
// 多线程,验证session的有效时间
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
public void run() {
cacheManager.checkValidityData();
}
}, 5000, TimeUnit.MILLISECONDS);
Thread.sleep(5000);
System.out.println(cacheManager.get("zhangsan"));
}
}

五、自定义Token

5.1 什么是token

  token其实就是一个令牌,具有随机性,类似于sessionId。在对接一些第三方平台的时候,为了能够保证数据安全性,通常会使用一些令牌进行交互。

5.2 如何自定义token

  token生成规则,只要保证token生成一个不重复的唯一字符串即可。使用jdk自带的uuid生成规则。

5.3 什么是UUID

  UUID含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织应用在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部分。

  UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 UUID。

5.4 UUID的组成

  UUID保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字
  UUID由以下几部分的组合:
    (1)当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
    (2)时钟序列。
    (3)全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。
  UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函数很简单地生成UUID,其格式为:xxxxxxxx-xxxx-
xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(8-4-4-4-12)。

5.5 UUID代码

  UUID。randomUUID().toString()

六、表单重复提交解决方案(防止http重复提交) 

6.1 场景描述:

  网络延时:在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。

  重复刷新:表单提交后用户点击【刷新】按钮导致表单重复提交。

  后退再提交:点击浏览器的【后退】按钮回退到表单页面后进行再次提交

6.2 解决方案

  6.2.1 使用javascript 解决

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Form表单</title>
<script type="text/javascript">
var isFlag = false; //表单是否已经提交标识,默认为false
function submitFlag() {
if (isFlag == false) {
isFlag = true;
return true;
} else {
return false;
}
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post" onsubmit="return submitFlag()">
用户名:<input type="text" name="userName"> <input type="submit"
value="提交" id="submit">
</form>
</body>
</html>

  6.2.2 使用后端提交解决

  对于【重复刷新】、【后退再提交】导致表单重复提交的问题,前端无法解决,只能在服务器端解决。

  在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token。然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。

  在下列情况下,服务器端将拒绝处理用户提交的表单请求:

  1. 存储Session域中的Token(令牌)与表单提交的Token(令牌)不同。
  2. 当前用户的Session中不存在Token(令牌)
  3. 用户提交的表单数据中没有Token(令牌)

  转发代码:

@WebServlet("/ForwardServlet")
public class ForwardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().setAttribute("sesionToken", TokenUtils.getToken());
req.getRequestDispatcher("form.jsp").forward(req, resp);
}
}

  转发页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Form表单</title> </head> <body>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post" onsubmit="return dosubmit()">
<input type="hidden" name="token" value="${sesionToken}"> 用户名:<input type="text"
name="userName"> <input type="submit" value="提交" id="submit">
</form>
</body>
</html>

  后端代码:

@WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
boolean flag = isFlag(req);
if (!flag) {
resp.getWriter().write("已经提交...");
System.out.println("数据已经提交了..");
return;
}
String userName = req.getParameter("userName");
try {
Thread.sleep(300);
} catch (Exception e) {
}
System.out.println("往数据库插入数据...." + userName);
resp.getWriter().write("success");
} public boolean isFlag(HttpServletRequest request) {
HttpSession session = request.getSession();
String sesionToken = (String) session.getAttribute("sesionToken");
String token = request.getParameter("token");
if (!(token.equals(sesionToken))) {
return false;
}
session.removeAttribute("sesionToken");
return true;
}
}

七、Servlet之Filter

7.1 什么是Filter

  Filter 也称之为过滤器,它是 Servlet 技术中最实用的技术,Web 开发人员通过 Filter 技术,对 web 服务器管理的所有 web 资源:例如 Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现 URL 级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

  它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理。使用 Filter 的完整流程:Filter 对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再对服务器响应进行后处理。

7.2 Fileter使用

import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 使用Filter 打印参数
*
*/
public class FilterDemo implements Filter {
public FilterDemo(){
System.out.println("FilterDemo 构造函数被执行...");
}
/**
* 销毁
*/
public void destroy() {
  System.out.println("destroy");
}
public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse,
FilterChain paramFilterChain) throws IOException, ServletException {
System.out.println("doFilter");
HttpServletRequest request = (HttpServletRequest) paramServletRequest;
HttpServletResponse response = (HttpServletResponse) paramServletResponse;
// 请求地址
String requestURI = request.getRequestURI();
System.out.println("requestURI:"+requestURI);
// 参数
Map<String, String[]> parameterMap = request.getParameterMap();
for (String key : parameterMap.keySet()) {
String[] arr=parameterMap.get(key);
}
}
/**
* 初始化
*/
public void init(FilterConfig paramFilterConfig) throws ServletException {
System.out.println("init");
}
}

  web.xml配置

<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>com.stu.servlet.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

7.3 使用Filter防止XSS攻击

  7.3.1 什么是XSS攻击

    XSS攻击使用Javascript脚本注入进行攻击,例如在表单中注入: <script>location.href='http://www.baidu.com'</script>

  fromToXss.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="XssDemo" method="post">
<input type="text" name="userName"> <input type="submit">
</form>
</body>
</html>
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet("/XssDemo")
public class XssDemo extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userName = req.getParameter("userName");
req.setAttribute("userName", userName);
req.getRequestDispatcher("showUserName.jsp").forward(req, resp);
}
}

  show.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>userName:${userName}
</body>
</html>

  73..2 解决方案:使用Filter过滤器过滤注入标签

import java.io.IOException;
import java.util.Map; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class FilterDemo implements Filter {
public FilterDemo() {
System.out.println("FilterDemo 构造函数被执行...");
}
/**
* 销毁
*/
public void destroy() {
System.out.println("destroy");
}
public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse,
FilterChain paramFilterChain) throws IOException, ServletException {
System.out.println("doFilter");
HttpServletRequest request = (HttpServletRequest) paramServletRequest;
XssAndSqlHttpServletRequestWrapper xssRequestWrapper = new XssAndSqlHttpServletRequestWrapper(request);
// HttpServletResponse response = (HttpServletResponse)
// paramServletResponse;
// // 请求地址
// String requestURI = request.getRequestURI();
// System.out.println("requestURI:" + requestURI);
// // 参数
// Map<String, String[]> parameterMap = request.getParameterMap();
// for (String key : parameterMap.keySet()) {
// String[] arr = parameterMap.get(key);
// System.out.print("key:");
// for (String string : arr) {
// System.out.println(string);
// }
// }
paramFilterChain.doFilter(xssRequestWrapper, paramServletResponse);
}
/**
* 初始化
*/
public void init(FilterConfig paramFilterConfig) throws ServletException {
System.out.println("init");
}
}

  XssAndSqlHttpServletRequestWrapper

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils; /**
* 防止XSS攻击
*/
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
HttpServletRequest request;
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
public String getParameter(String name) {
String value = request.getParameter(name);
System.out.println("name:" + name + "," + value);
if (!StringUtils.isEmpty(value)) {
// 转换Html
value = StringEscapeUtils.escapeHtml4(value);
}
return value;
}
}

Session与Cookie(自定义Session)的更多相关文章

  1. 【荐】PHP Session和Cookie,Session阻塞,Session垃圾回收,Redis共享Session,不推荐Memcached保存Session

    什么是 Session 在 web 应用开发中,Session 被称为会话.主要被用于保存某个访问者的数据. 由于 HTTP 无状态的特点,服务端是不会记住客户端的,对服务端来说,每一个请求都是全新的 ...

  2. 牛客网Java刷题知识点之什么是cookie、什么是session、cookie和session有什么区别

    不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?tpId=31&tqId=21170&query=&asc= ...

  3. Django - Cookie、Session、自定义分页和Django分页器

    2. 今日内容 https://www.cnblogs.com/liwenzhou/p/8343243.html 1. Cookie和Session 1. Cookie 服务端: 1. 生成字符串 2 ...

  4. Tornado-Secure cookie and Session

    这一节涉及的内容有: 1.客户端和服务端操作cookie的方法 2.secure cookie的机制 3.基本/自定义session 文件结构 三个启动文件由下往上对应的分别是三种服务端:使用secu ...

  5. Django:Admin,Cookie,Session

    一. Admin的配置 1.Admin基础设置 admin是django强大功能之一,它能够从数据库中读取数据,呈现在页面中,进行管理.默认情况下,它的功能已经非常强大,如果你不需要复杂的功能,它已经 ...

  6. Session、Cookie与Token

    http协议是无状态协议 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到 ...

  7. Cookie与Session的区别-总结很好的文章

    Cookie与Session的区别-总结很好的文章 本文分别对Cookie与Session做一个介绍和总结,并分别对两个知识点进行对比分析,让大家对Cookie和Session有一个更深入的了解,并对 ...

  8. Cookie与Session的区别

    cookie机制 Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器.IETF RFC 2965 HTTP State Management Mechanism 是通用c ...

  9. Session与Cookie

    Session与Cookie的比较 Cookie与Session都可以进行会话跟踪,但是实现的原理不太一样.一般情况下二者均可以满足需求,但有时候不可以使用Cookie,有时候不可以使用Session ...

随机推荐

  1. Egg.js 中入参的校验

    日常作业中免不了频繁处理 GET/POST 的入参,你当然可以每个 action 中都重复地去做这些事情, 从 query 或 body 取出入参, 对可选的入参进行判空, 处理入参的类型转换, 对入 ...

  2. springboot~rabbitmq的队列初始化和绑定

    配置文件,在rabbit中自动建立exchange,queue和绑定它们的关系 代码里初始化exchange 代码里初始化queue 代码里绑定exchange,queue和routekey 配置文件 ...

  3. SmartSql Map

    SmartSqlMap 属性 说明 Scope 域,用于SqlMap定义Sql声明范围 Statement标签 属性 说明 Id 唯一性编号 Cache 缓存策略编号,引用自Cache标签 State ...

  4. jquery快速入门(二)

    jQuery 效果 1.隐藏,显示 1.1显示 hide() 和隐藏 show() 语法:$(selector).hide(speed,callback); $(selector).show(spee ...

  5. 我的python渗透测试工具箱之自制netcat

    此工具的目的是实现在目标主机上的文件传输,控制命令行的功能,主要逻辑依靠python的subprocess模块.`sys`模块和`getopt`模块. 知识准备 studin和studut studi ...

  6. 树莓派linux系统中显示隐藏文件的几种方法

    一.如果直接使用可视化文件管理器 1.直接点击右键,直接选择“显示隐藏文件”选项. 2.快捷键 CTRL + H 二.在终端命令行模式下 可以使用ls命令的-a参数来显示隐藏的文件及文件夹. ls - ...

  7. [转]Blue Prism Architecture

    本文转自:https://mindmajix.com/blue-prism-architecture Introduction Automation technology is widely bloo ...

  8. MySQL 笔记整理(17) --如何正确地显示随机消息?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 17) --如何正确地显示随机消息? 如果有这么一个英语单词表,需要每次 ...

  9. SpringBoot2 application.properties方式加载配置文件

    application.properties jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:33 ...

  10. 中介者模式 调停者 Mediator 行为型 设计模式(二十一)

      中介者模式(Mediator)   调度.调停   意图 用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散 而且可以独立地改变它们之间的交互. ...