一.Servlet3.0新特性
臃肿的XML配置
<!-- ConfigServlet -->
<servlet>
<servlet-name>ConfigServlet</servlet-name>
<servlet-class>com.dusk._03_conf.ConfigServlet</servlet-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ConfigServlet</servlet-name>
<url-pattern>/con</url-pattern>
</servlet-mapping>
新特性
在web.xml文件的根元素中,存在属性,表示是否忽略扫描Web组件注解:
metadata-complete="true" : 要忽略
metadata-complete="false": 不忽略
@WebServlet(value= {"/nn","/nn2"},loadOnStartup=1,
initParams = {@WebInitParam(name = "enconding", value = "utf-8")})
public class ConfigServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
}
二.传递参数方式
解决Http无状态问题
登录页面login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录界面</title>
</head>
<body>
<h1>登录界面</h1>
<form action="/email/parameter/login" method = 'POST'>
账号<input type = 'text' name = 'username'><br>
密码<input type = 'password' name = 'password'><br>
<input type = 'submit' value = '登录'><br>
</form>
</body>
</html>
登录进去Login
@WebServlet("/parameter/login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置编码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
// 获取值
String username = req.getParameter("username");
String password = req.getParameter("password");
PrintWriter writer = resp.getWriter();
writer.write("下午好:" + username + "<br>");
writer.write("<a href = '/email/parameter/list?username=" + username + "'>邮件(10)</a>");
}
}
邮件列表界面List
@WebServlet("/parameter/list")
public class List extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
PrintWriter writer = resp.getWriter();
writer.write("下午好: " + username + "<br>");
for (int i = 0; i < 10; i++) {
writer.write("<a href = '/email/parameter/detail?username= "+username+"'>邮件"+i+"</a><br>");
}
}
}
邮件内容界面DetailServlet
@WebServlet("/parameter/detail")
public class DetailServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
PrintWriter writer = resp.getWriter();
writer.write("下午好," + username + "<br>");
writer.write("好饿,要吃饭");
}
}
解决get请求中文乱码问题
Tomcat下的conf/server.xml的Connector节点
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
三.Cookie
- 如何创建cookie
Cookie c = new Cookie(String name, String value);
参数1:cookie名字, 类似map集合中 key值
参数2:cookie的值, 类似map集合中value值
- 将cookie交付给浏览器
响应对象(resp).addCookie(cookie对象);
- 获取cookie中的值
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("username".equals(cookie.getName())) {
username = URLDecoder.decode(cookie.getValue(), "UTF-8");
}
}
}
- 修改cookie参数
- 方式1:重新创建一个同名称的Cookie发给客户端覆盖原来的Cookie
- 方式2:在原Cookie对象的基础上调用setValue(“newValue”),再发给客户端覆盖原Cookie
- 注意:要记得把新Cookie发给客户端覆盖原Cookie,比如:resp.addCookie(newCookie);
- cookie分类:
关键方法:cookie对象.setMaxAge(int seconds);
seconds > 0: 持久Cookie
seconds = 0: 删除该Cookie
seconds < 0: 会话Cookie(默认)
四.Session
Session其本质就是一个会话Cookie(浏览器关闭之后,Session就失效了).
- 创建或者获取session
HttpSession session = req.getSession(true);
参数为true: 从请求对象中获取一个session对象, 如果session对象存在, 返回该对象, 如果不存在,则创建一个新的session, 并返回。
HttpSession session = req.getSession(false);
参数为false: 从请求对象中获取一个session对象, 如果session对象存在, 返回该对象, 如果不存在,则返回null。
HttpSession session = req.getSession();
等价于参数为true这种情况。
- 设置session共享数据
session.setAttribute(String name, Object value);
参数1:session属性的key值, 类似map集合中key值
参数2:session属性的value值, 类似map集合中value值, 注意, value是Object
- 获取session中共享数据
Object value = session.getAttribute(String name);
- 删除Session(用户注销登陆).
- 删除Session中指定属性名的值.
session对象.removeAttrbute(属性的key值); - 销毁Session对象(Session中所有的属性都不存在).
session对象.invalidate();
- 删除Session中指定属性名的值.
- Session的超时管理
在超时时间之内,如果客户端和服务端没有交互(用户的两次操作之间不能超过该时间),则自动的销毁Session.
session对象.setMaxInactiveInterval(60 * 10);//超过10分钟,销毁Session.
Tomcat服务器的默认超时时间为:30分钟,Tomcat一般在20多分钟就销毁了.
login.session.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录界面</title>
</head>
<body>
<h1>登录界面</h1>
<form action="/email/session/login" method = 'POST'>
账号<input type = 'text' name = 'username'><br>
密码<input type = 'password' name = 'password'><br>
<input type = 'submit' value = '登录'><br>
</form>
</body>
</html>
用户类User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String username;
private String password;
}
登录结果Login
@WebServlet("/session/login")
public class Login extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//获取值
String username = req.getParameter("username");
String password = req.getParameter("password");
//创建session对象
HttpSession session = req.getSession();
//设置值
session.setAttribute("USER_IN_SESSION", new User(username,password));
PrintWriter writer = resp.getWriter();
writer.write("下午好:" + username + "<br>");
writer.write("<a href = '/email/session/list'>邮件(10)</a>");
}
}
列表List
@WebServlet("/session/list")
public class List extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//获取 Cookie
HttpSession session = req.getSession();
User user = (User)session.getAttribute("USER_IN_SESSION");
PrintWriter writer = resp.getWriter();
writer.write("下午好: " + user.getUsername() + "<br>");
for (int i = 0; i < 10; i++) {
writer.write("<a href = '/email/session/detail'>邮件"+i+"</a><br>");
}
}
}
详细内容DetailServlet
@WebServlet("/session/detail")
public class DetailServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
HttpSession session = req.getSession();
User user = (User)session.getAttribute("USER_IN_SESSION");
PrintWriter writer = resp.getWriter();
writer.write("下午好," + user.getUsername() + "<br>");
writer.write("好饿,要吃饭");
}
}
五.细节
- 一般的,我们存储到Session中的属性名称,要唯一,我们习惯XXX_IN_SESSION:
session对象.setAttribute(“USERNAME_IN_SESSION”,“dafeiji”); - 若需要把多个数据存放到Session中,就得调用setAttribute方法N次,可以的.
一般的,我们把需要存储的数据,封装成一个对象,然后在存储到Session中.
把用户的信息,封装到user对象.
session对象.setAttribute(“USER_IN_SESSION”,user对象); - 如果多台服务器之间需要共享Session,此时Session中的对象,必须实现java.io.Serializable(才能在网络上传输).
序 列 化: 把对象信息存储为二进制.
反序列化: 把二进制信息恢复成对象.
public class User implements java.io.Serializable{…} - URL重写.
Session是一种特殊的Cookie,而浏览器可以禁用Cookie.
此时,需要在每一个资源之后,手动的携带session的ID.
/session/list;jsessionid=地址
String url = response.encodeURL("/day04/session/list");自动的在资源之后拼接;jsessionid=地址
注意:开发中都不会取消接受Cookie的.