Servlet 学习(六)
会话
1、定义
- 一般意义会话:指两人以上的对话(多用于学习别种语言或方言时)
- 计算机中的会话:客户端和服务器的通讯
web客户端 A ------>Tomcat
web客户端 B ------>Tomcat
会话追踪
1、定义
- 一 个客户端可以发起多次请求,对多次请求进行追踪
web客户端 A ------>Tomcat
first request -------> response
second request -------> response
2、进行会话追踪的原因
- http是无状态的协议,不记录用户的信息(是否登录)
- 上下文的缺失引起许多困难
3、会话跟踪的实现方式
- 隐藏表单域<input type="hidden" name="paramName" value="paramValue">
- URL 重写http://localhost:8080/loginservlet ,http://localhost:8080/loginservlet;jsessionid=1234
- 基于客户端的跟踪: Cookie javax.servlet.http.Cookie
- 基于服务器端的跟踪: Session javax.servlet.http.HttpSession
Cookie
1、定义
- Cookie 是由服务器创建,保存在客户端的key-value 形式的小文本数据
- Cookie 中含有的信息Cookie的名字、Cookie的值、Cookie的失效日期、Cookie的域名和路径
2、使用cookie
- 创建Cookie 对象
Cookie 类的构造public Cookie ( String name , String value )
Cookie的name 和value 的命名要求
»不论是name 和value 都不能含有空格和[ ] ( ) = , " / ? @ : ;
»对于name ,其命名还必须满足不能是以下单词或单词组合(大小写不一样都不行)
Comment、Discard、Domain、Expires、Max-Age、Path、Secure、Version
»对于name ,其命名还必须满足不能以$ 为开头
- 显式设置Cookie 最大时效
通过当前Cookie 对象的setMaxAge() 方法设置public void setMaxAge(int expiry)
本方法中的expiry 参数
»默认的时间单位是秒( seconds )
»将最大时效设置为0 ,即expiry = 0意思是命令浏览器删除该Cookie
»如果没有显式设置最大时效,默认为-1意思是当浏览器关闭时,删除相应的Cookie
- 将Cookie 添加到http 响应报头
调用的方法response.addCookie( cookie );
该方法不修改之前的set-cookie 报头
该方法是创建新的报头
该方法会把服务器上的操作"同步"到客户端
创建Cookie对象以及调用setMaxAge是在服务器中完成的
- 从客户端读取Cookie
通过request 获取当前所关联的所有cookie 数组Cookie[] cookies = request.getCookies();
遍历cookie 数组,根据名称,可以找到相应的值
for( Cookie cookie : cookies){
System.out.println( cookie.getName() +" - " + cookie.getValue() );
}
Cookie自动登录测试案例:
package ecut.tracking.cookie; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet( "/cookie/page/login" )
public class LoginPageServlet extends HttpServlet { private static final long serialVersionUID = 2075180219363356668L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); PrintWriter w = response.getWriter(); w.println( "<!DOCTYPE html>" );
w.println( "<html>" );
w.println( "<head>" );
w.println( "<meta charset='UTF-8'>" );
w.println( "<title>登录</title>" );
w.println( "</head>" );
w.println( "<body>" );
w.println( " <h5>登录</h5>" ); String un = "" ;
String pwd = "" ; // 尝试 从 请求报头中获取 Cookie,所有的 Cookie 都是通过 请求报头 "回传" 给服务器
Cookie[] cookies = request.getCookies();
System.out.println( "cookies : " + cookies );
if ( cookies != null ){
for( Cookie c : cookies ){
String name = c.getName() ;
if( "username".equals( name ) ){
un = c.getValue() ;
continue;
}
if( "password".equals( name ) ){
pwd = c.getValue() ;
continue ;
}
}
} w.println( " <form action='" + request.getContextPath() + "/cookie/action/login' method='post' >" );
w.println( " <input type='text' name='username' value='" + un + "' placeholder='用户名'>" );
w.println( " <br>" );
w.println( " <input type='password' name='password' value='" + pwd + "' placeholder='输入密码'>" );
w.println( " <br>" );
w.println( " <input type='checkbox' name='autologin' value='auto'>两周内自动登录" );
w.println( " <br>" );
w.println( " <input type='submit' value='登录'>" );
w.println( " </form>" ); w.println( "</body>" );
w.println( "</html>" ); } }
package ecut.tracking.cookie; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet( "/cookie/action/login" )
public class LoginActionServlet extends HttpServlet { private static final long serialVersionUID = 6978052887387276476L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); String username = request.getParameter( "username" );
String password = request.getParameter( "password" ); String autologin = request.getParameter( "autologin" ); System.out.println( "username : " + username + " , password : " + password ); if( "zhangsanfeng".equals( username ) && "hello2017".equals( password ) ){ if( autologin != null && autologin.trim().equalsIgnoreCase( "auto" ) ) {
System.out.println( "需要保存用户名和密码 : " + autologin ); String contextPath = request.getContextPath(); int expiry = 60 * 60 * 24 * 14 ;
//Cookie 由服务器创建
Cookie usernameCookie = new Cookie( "username" , username );
usernameCookie.setPath( contextPath );
usernameCookie.setMaxAge( expiry ); response.addCookie( usernameCookie ); Cookie passwordCookie = new Cookie( "password" , password );
// 设置 Path(只有和其相同路径的请求才可以获得cookie), 这个工程下的所有的请求的都将可以接收到这个cookie,否则只有/cookie/action下的才可以获得这个cookie
passwordCookie.setPath( contextPath );
// 设置 Cookie 的有效期 ( 单位是 秒 )
// max-age 的默认值是 -1 ,表示 浏览器关闭 即删除相应的 Cookie
// 如果 max-age 的取值 是 0 表示 浏览器需要立即删除 该 Cookie
passwordCookie.setMaxAge( expiry );
// 通过 响应报头 将 Cookie 发送到 客户端进行保存
response.addCookie( passwordCookie ); } response.sendRedirect( request.getContextPath() + "/cookie/login/success" );
return ;
} else {
response.sendRedirect( request.getContextPath() + "/cookie/page/login" );
return ;
} } }
package ecut.tracking.cookie; import java.io.IOException;
import java.io.PrintWriter; 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( "/cookie/login/success" )
public class LoginSuccessServlet extends HttpServlet { private static final long serialVersionUID = -7565331422887485255L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); PrintWriter w = response.getWriter(); w.println( "<h2>登录成功</h2>" ); w.println( "<a href='" + request.getContextPath() + "/cookie/page/login'>重新登录</a>" ); } }
运行结果如下:
在浏览器中访问http://localhost:8080/Servlet/cookie/page/login
输入用户名和密码后勾选自动登录,然后点击登录页面如下
点击重新登录后显示如下页面
Session
1、定义
- Session也是一种记录客户状态的机制
- 服务器把客户信息以某种方式记录在服务器
- Session 的本质 是 在 WEB 容器内 ( Tomcat ) 划分一块内存存放跟某个用户关联的数据
- 每个 WEB 客户端在同一时刻只能对应一个 Session ( 同一时刻,客户端持有的编号与 Session 编号必须一致 )
- Cookie 把客户状态记录在客户端,Session 把客户状态记录在服务器上
2、Session中数据的特点
- 由服务器创建,存储在服务器上
- 类似于Cookie ,也是以key-value 形式存放数据
不同的是value 可以是任何形式,比如可以是Java 对象等
- 通常Session 中也包含了失效时间等信息
- 每个"用户"都会有且仅有一个Session
访问动态资源比如JSP、Servlet 等会导致创建Session
访问静态资源,比如html 、image 等不会导致创建Session
也可以通过request.getSession( true ) 强制开启Session
- 使用Session 可以实现跨请求的数据共享
同一个"用户"的多次请求所共用的数据可以存放在Session 中
»比如用户登录后的信息,可以记录在Session 中,以后的请求可以这些数据
必须是同一个"用户"的不同请求才能共享Session 中的数据
»不同"用户"使用不同的Session
»不同"用户"的请求不能共享Session 中的数据
3、Session的有效期
- 服务器会把长时间没有活跃的Session 从内存中删除
为了防止服务器端内存溢出,减轻服务器端负荷
- 通常Session 在超过一定时间后,Session 就自动失效
这个时间就是Session 的有效期
超时时间可以通过设置maxInactiveInterval 属性来设置
- 可以通过修改web.xml 设置Session 的有效期(默认30分钟)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
- 通过Session 的invalidate() 可以使Session 失效
比如,用户注销时,可以使用该方法
4、 Session - HttpSession中的常用方法
- String getId() 返回 当前的 session 对象的 编号 ( 默认与客户端的 jsessionid 对应 )
- boolean isNew() 判断当前的 session 对象是否是新创建的,如果是新创建的就返回 true ,否则就是 false
- void setAttribute( String name , Object value ) 将 name - value 对 保存到 session 对象中
- Object getAttribute( String name ) 根据 指定的 属性名称 获得相应的取值
- void removeAttribute( String name ) 从 session 对象中移除指定属性名称对应的 name-value 对
5、Session - Session 对浏览器的要求
- Session使用Cookie作识别标志
因为HTTP 是无状态协议,因此不能根据HTTP 链接来标识客户
服务器向客户端发送一个JSESSIONID 的Cookie 来标识客户
»通过该jsessionid 可以惟一地标识一个客户
»该jsessionid 的值就是当前session 对象的id ,在服务器是惟一的
服务器会自动生成JSESSIONID 的Cookie
»它的maxAge 默认为-1 ,表示当前浏览器有效
»一旦用户关闭浏览器,立即失效,同时各个窗口之间互不共享
»但当前浏览器窗口的子窗口可以共享父窗口的Cookie (亦即共享Session)
- Session对浏览器的要求是支持并开启Cookie功能
一般而言,对于Linux / Windows 都开启了Cookie 功能
早期的wap 浏览器都不支持Cookie 功能
»如果你用的是早期的手机,其中的wap 浏览器是不支持Cookie 的
6、使用session
- 获得与当前请求相关联的会话对象,HttpSession session = request.getSession();
- 查找与会话相关联的信息,通过session.getAttribute( attrName ); 获取
- 存储会话中的信息,通过session.setAttribute( key , value ); 存入
- 废弃会话,通过session.removeAttribute( attrName ); 废弃指定的值,调用session.invalidate() 废弃整个会话,会话有效期超出,会话被服务器干掉
Session登录测试案例:
登录:
1、输入用户名和密码
2、点击登录 ,验证 用户名 和 密码 是否正确
3、如果 用户名 或 密码不正确,给出提示,并重新输入
4、如果 用户名 和 密码 都正确,
则 将用户的信息存储到 当前会话中 ( 目的是让当前客户端的多次请求都能获取到该用户的信息 )
注: 用户的信息一般以 对象的形式 存储到 会话 中,而不是仅仅存储一个用户名
package ecut.tracking.session; import java.io.IOException;
import java.io.PrintWriter; 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( "/session/page/login" )
public class LoginPageServlet extends HttpServlet { private static final long serialVersionUID = 2075180219363356668L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); PrintWriter w = response.getWriter(); w.println( "<!DOCTYPE html>" );
w.println( "<html>" );
w.println( "<head>" );
w.println( "<meta charset='UTF-8'>" );
w.println( "<title>登录</title>" );
w.println( "</head>" );
w.println( "<body>" );
w.println( " <h5>登录</h5>" ); w.println( " <form action='" + request.getContextPath() + "/session/action/login' method='post' >" );
w.println( " <input type='text' name='username' placeholder='用户名'>" );
w.println( " <br>" );
w.println( " <input type='password' name='password' placeholder='输入密码'>" );
w.println( " <br>" );
w.println( " <input type='submit' value='登录'>" );
w.println( " </form>" ); w.println( "</body>" );
w.println( "</html>" ); } }
package ecut.tracking.session; 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;
import javax.servlet.http.HttpSession; import ecut.tracking.entity.User; @WebServlet( "/session/action/login" )
public class LoginActionServlet extends HttpServlet { private static final long serialVersionUID = 6978052887387276476L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" );
// 通过 request 对象来获得 与当前的 客户端关联的 session 对象
// 通过 获取 请求报头 中的 cookie 然后获得 jsessionid 对应的值,再根据 jsessionid 来寻找相应的 session 对象
// 如果没有找到 jsessionid 对应的 session 对象,则 容器会创建一个 新的 session 对象
HttpSession session = request.getSession();
// 如果是新创建的 session 对象,则通过 响应报头 向客户端发送一个 cookie ( 其中包含了 session id )
boolean isNew = session.isNew(); // 如果是新创建的 session 对象,则返回 true
System.out.println( "is new: "+isNew );
String username = request.getParameter( "username" );
String password = request.getParameter( "password" ); System.out.println( "username : " + username + " , password : " + password ); if( "zhangsanfeng".equals( username ) && "hello2017".equals( password ) ){
User user = new User(); // 构造用户对应的对象
user.setUsername( username ); // 将 用户名 设置到 用户对象中
user.setPassword( password );
session.setAttribute( "user" , user ); // 把 session 当作 Map< String , Object >
response.sendRedirect( request.getContextPath() + "/session/login/success" );
return ;
} else {
response.sendRedirect( request.getContextPath() + "/session/page/login" );
return ;
} }
}
package ecut.tracking.session; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import ecut.tracking.entity.User; @WebServlet( "/session/login/success" )
public class LoginSuccessServlet extends HttpServlet { private static final long serialVersionUID = -7565331422887485255L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); PrintWriter w = response.getWriter(); // 通过 request 对象来获得 与当前的 客户端关联的 session 对象
HttpSession session = request.getSession();
// 尝试从 session 中获取 名称是 user 的属性 ( attribute )
Object o = session.getAttribute( "user" ); // 如果获取到的 属性值 存在 且 是 User 类型,说明用户已经登陆
if( o instanceof User ) { // o 所引用的对象 是 User 类型吗 ?
User u = (User) o ;
w.println( "<h2>欢迎 " + u.getUsername() + " 登录.</h2>" ); w.println( "<a href='" + request.getContextPath() + "/session/action/logout' >注销</a>" ); } else {
response.sendRedirect( request.getContextPath() + "/pages/tracking/index.html" );
return ;
} } }
package ecut.tracking.session; 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;
import javax.servlet.http.HttpSession; @WebServlet( "/session/action/logout" )
public class LogoutActionServlet extends HttpServlet { private static final long serialVersionUID = 6162020347616177699L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException { HttpSession session = request.getSession(); session.removeAttribute( "user" ); response.sendRedirect( request.getContextPath() + "/pages/tracking/index.html" ); } }
运行结果如下:
点击登录后跳转如下页面,点击注销跳转到首页
Cookie和Session比较
1、存取方式
cookie存储在客户端,session存储在服务器
2、隐私安全
由于cookie存储在客户端,session存储在服务器,因此session的安全性高一些
3、有效期
cookie的默认有效期是-1意思是当浏览器关闭时,删除相应的Cookie,由于session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的maxAge默认为-1,只要关闭了浏览器该session就会失效,因此Session不能实现信息永久有效的效果。
4、服务器负荷
由于session存储在服务器,因此session的服务器负荷高一些
5、浏览器支持
session是通过服务器向客户端发送一个JSESSIONID 的Cookie 来标识客户,因此也依赖于cookie,若浏览器不支持cookie则session也无法使用
6、跨域名支持
- 对于浏览器不支持Cookie 的情况,可以使用URL 重写(本身就是对客户端不支持Cookie 的解决方案)
- 实际上,对于绝大多数的wap 应用,都采用了URL 重写
- 将该用户Session 的id 信息重写到URL 地址中
- 服务器可以解析重写后的URL 从而获取Session 的id
- 即便客户端不支持Cookie 也可以使用Session 来记录客户状态
response.encodeRedirectURL( String url )
package ecut.tracking.urlrewrite; import java.io.IOException;
import java.io.PrintWriter; 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( "/urlrewrite/page/login" )
public class LoginPageServlet extends HttpServlet { private static final long serialVersionUID = 2075180219363356668L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); PrintWriter w = response.getWriter(); w.println( "<!DOCTYPE html>" );
w.println( "<html>" );
w.println( "<head>" );
w.println( "<meta charset='UTF-8'>" );
w.println( "<title>登录</title>" );
w.println( "</head>" );
w.println( "<body>" );
w.println( " <h5>登录</h5>" ); String url = request.getContextPath() + "/urlrewrite/action/login?hello=world" ; System.out.println( "login page , before encode : " + url );
url = response.encodeURL( url );
System.out.println( "login page , after encode : " + url ); w.println( " <form action='" + url + "' method='post' >" );
w.println( " <input type='text' name='username' placeholder='用户名'>" );
w.println( " <br>" );
w.println( " <input type='password' name='password' placeholder='输入密码'>" );
w.println( " <br>" );
w.println( " <input type='submit' value='登录'>" );
w.println( " </form>" ); w.println( "</body>" );
w.println( "</html>" ); } }
package ecut.tracking.urlrewrite; 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;
import javax.servlet.http.HttpSession; import ecut.tracking.entity.User; @WebServlet( "/urlrewrite/action/login" )
public class LoginActionServlet extends HttpServlet { private static final long serialVersionUID = 6978052887387276476L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); HttpSession session = request.getSession(); String username = request.getParameter( "username" );
String password = request.getParameter( "password" ); System.out.println( "username : " + username + " , password : " + password ); if( "zhangsanfeng".equals( username ) && "hello2017".equals( password ) ){
User user = new User(); // 构造用户对应的对象
user.setUsername( username ); // 将 用户名 设置到 用户对象中
user.setPassword( password );
session.setAttribute( "user" , user ); // 把 session 当作 Map< String , Object > String url = request.getContextPath() + "/urlrewrite/login/success" ;
System.out.println( "login action , before encode : " + url );
url = response.encodeURL( url );
System.out.println( "login action , after encode : " + url );
response.sendRedirect( url );
return ;
} else {
String url = request.getContextPath() + "/urlrewrite/page/login" ;
System.out.println( "login action , before encode : " + url );
url = response.encodeRedirectURL( url );
System.out.println( "login action , after encode : " + url );
response.sendRedirect( url );
return ;
} } }
package ecut.tracking.urlrewrite; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import ecut.tracking.entity.User; @WebServlet( "/urlrewrite/login/success" )
public class LoginSuccessServlet extends HttpServlet { private static final long serialVersionUID = -7565331422887485255L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" );
response.setContentType( "text/html;charset=UTF-8" ); PrintWriter w = response.getWriter(); // 通过 request 对象来获得 与当前的 客户端关联的 session 对象
HttpSession session = request.getSession();
// 尝试从 session 中获取 名称是 user 的属性 ( attribute )
Object o = session.getAttribute( "user" ); // 如果获取到的 属性值 存在 且 是 User 类型,说明用户已经登陆
if( o instanceof User ) { // o 所引用的对象 是 User 类型吗 ?
User u = (User) o ;
w.println( "<h2>欢迎 " + u.getUsername() + " 登录.</h2>" );
String url = request.getContextPath() + "/urlrewrite/action/logout" ;
System.out.println( "login success , before encode : " + url );
url = response.encodeURL( url );
System.out.println( "login success , after encode : " + url );
w.println( "<a href='" + url + "' >注销</a>" );
} else {
response.sendRedirect( request.getContextPath() + "/pages/tracking/index.html" );
return ;
} } }
package ecut.tracking.urlrewrite; 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;
import javax.servlet.http.HttpSession; @WebServlet( "/urlrewrite/action/logout" )
public class LogoutActionServlet extends HttpServlet { private static final long serialVersionUID = 6162020347616177699L; @Override
protected void service( HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException { HttpSession session = request.getSession(); session.removeAttribute( "user" ); response.sendRedirect( request.getContextPath() + "/pages/tracking/index.html" ); } }
转载请于明显处标明出处
Servlet 学习(六)的更多相关文章
- Hbase深入学习(六) Java操作HBase
Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...
- TweenMax动画库学习(六)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- JSP&Servlet学习手册
JSP&Servlet学习手册 沙琪玛 书 目录 JSP 指令... 3 书写方式... 3 指令列表... 3 JSP 内置对象... 3 内置对象特点... 3 常用内置对象... 3 o ...
- Servlet 学习笔记
Servlet 运行在服务器上的 java 类: Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据. 现在我们知道了 ...
- Servlet学习:(三)Servlet3.0 上传文件
转: Servlet学习:(三)Servlet3.0 上传文件 2018年08月03日 11:57:58 iDark_CSDN 阅读数:362 一.注意事项 客户端(浏览器) 表单的提交方法必须是 ...
- SVG 学习<六> SVG的transform
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- C#多线程学习(六) 互斥对象
如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先 ...
- Unity学习(六)5.x依赖打包
http://blog.sina.com.cn/s/blog_89d90b7c0102w2ox.html unity5已经封装好了接口,所以依赖打包并没有那么神秘和复杂了. 打包: 1.定义好资源的a ...
- (转)MyBatis框架的学习(六)——MyBatis整合Spring
http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...
- Servlet学习(九)——request
request运行流程在Servlet学习(四)——response已介绍,不再赘述 1.通过抓包工具获取Http请求 因为request代表请求,所以我们可以通过该对象分别获得Http请求的请求行, ...
随机推荐
- 修改eclipse工程jdk版本
在eclipse中项目jdk版本不匹配的时候需要修改项目工程的jdk版本,但是网上的一些版本修改不是很完全,经过一些摸索之后,参考总结了我在项目中的具体配置实践 问题: 修改eclipse中的项目jd ...
- GO学习之 为什么选择GO
一.Go语言为并发而生 如上所述,硬件制造商正在为处理器添加越来越多的内核以提高性能.所有数据中心都在这些处理器上运行,更重要的是,今天的应用程序使用多个微服务来维护数据库连接,消息队列和维护缓存.因 ...
- ubuntu14.04安装好Hadoo之后接着安装hbase和介绍常用命令
1.解压 tar -zxvf hbase-1.0.0-bin.tar.gzsudo mv hbase-1.0.0 /opt/hbasecd /optsudo chmod -R 775 hbase 2. ...
- 如何切换虚拟机(centos6)和windows
通过设置热键,选择Ctrl+Alt+Fx即可.重启linux之后按Ctrl+Alt+Fx切换不同的终端的就可以了 图一. 图二.
- C# 酒店管理系统知识点
identity (m,n)自增 m开始n每次增加的值 默认(1,1) 列名 数据类型 约束 identity(m,n) 重新设置identity的值 1.语法 dbcc checkident ...
- 消息队列(四)--- RocketMQ-消息发送
概述 RocketMQ 发送普通消息有三种 可靠同步发送 可靠异步发送 单向(oneway)发送 :只管发送,直接返回,不等待消息服务器的结果,也不注册回调函数,简单地说,就是只管发,不管信息是否发送 ...
- nginx 配置Tp5项目时出现 404 Not Found nginx
1.首先看了nginx报错日志 报 signal process started signal process started表示还有 产生原因 1.可能你的nginx.conf 内容配置的有问题. ...
- JAVA单例实现方式(常用)
JAVA单例实现方式(常用) public class Singleton { // Q1:为什么要使用volatile关键字? private volatile static Singleton u ...
- Java笔记 02-LinkedList
介绍:List 接口的链接列表实现.实现所有可选的列表操作,并且允许所有元素(包括 null).除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get.remove 和 i ...
- put、patch与post区别
idempotent 幂等的 如果一个方法重复执行多次,产生的效果是一样的,那就是idempotent的: idempotent的意思是如果相同的操作再執行第二遍第三遍,結果還是一樣. POST方法 ...