1.关于Servlet的跳转
1.forward---RequestDispatcher接口的
forward(ServletRequest request,ServletResponse response)---该方法用于将请求从一个 Servlet 传递给另一个 Web 资源【Servlet程序/html/JSP】。【请求转发】
forward属于RequestDispatcher接口的
HttpServletRequest接口从ServletRequest接口中继承了一个获取 RequestDispatcher 对象的方法RequestDispatcher getRequestDispatcher (String path)
参数String path---目标路径【必须以“/”开头,用于表示当前 Web 应用的根目录】
需要注意的是,WEB-INF 目录中的内容对 RequestDispatcher 对象也是可见的。因此,传递给 getRequestDispatcher(String path) 方法的资源可以是 WEB-INF 目录中的文件.
RequestDispatcher接口对象=HttpServletRequest接口对象.getRequestDispatcher (String path);
RequestDispatcher接口对象.forward(ServletRequest request,ServletResponse response). 通过HttpServletRequest对象传递数据的。
HttpServletRequest对象的方法:
1.void setAttribute(String name,Object o) 用于将一个对象与一个名称关联后存储到 ServletRequest 对象中
2.Object getAttribute(String name) 用于从 ServletRequest 对象中返回指定名称的属性对象
3.void removeAttribute(String name) 用于从 ServletRequest 对象中删除指定名称的属性
package com.wangxing.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OneServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("OneServlet------");
//forward(ServletRequest request,ServletResponse response)该方法用于将请求从一个 Servlet 传递给另一个 Web 资源【Servlet程序/html/JSP】
//RequestDispatcher requestDispatcher=req.getRequestDispatcher("/test1.html");
//requestDispatcher.forward(req, resp);
//req.getRequestDispatcher("other").forward(req, resp);
//void setAttribute(String name,Object o) 用于将一个对象与一个名称关联后存储到 ServletRequest 对象中
req.setAttribute("name", "zhangsan");
//void removeAttribute(String name) 用于从 ServletRequest 对象中删除指定名称的属性
req.removeAttribute("name");
req.getRequestDispatcher("/other").forward(req, resp);
}
}
package com.wangxing.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OtherServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//Object getAttribute(String name) 用于从 ServletRequest 对象中返回指定名称的属性对象
String name=(String)req.getAttribute("name");
System.out.println("OtherServlet------name=="+name);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>TsetServlet6</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
2.Redirect----HttpServletRespone.sendRedirect()[重定向]
HttpServletResponse 接口定义了一个 sendRedirect(String path) 方法.将请求从一个 Servlet 传递给另一个 Web 资源【Servlet程序/html/JSP】
package com.wangxing.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OneServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("OneServlet------");
//sendRedirect(String path) 方法将请求从一个 Servlet 传递给另一个 Web 资源【Servlet程序/html/JSP】
//resp.sendRedirect("test1.html");
//resp.sendRedirect("/test1.html"); //错误
req.setAttribute("name","zhansgan");
resp.sendRedirect("other");
}
}
package com.wangxing.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OtherServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//Object getAttribute(String name) 用于从 ServletRequest 对象中返回指定名称的属性对象
String name=(String)req.getAttribute("name");
System.out.println("OtherServlet------name=="+name);
}
}
上面的测试是由Servlet程序访问Html/其他的Servlet,我们还可以通过html访问Servlet:
- 通过html的表单元素
- 通过html的超链接
- 通过javascript的ajax发送异步请求
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<!--
<center>
<form action="login" method="post">
<table border="1px">
<tr align="center">
<td colspan="2"><h1>用户登录</h1></td>
</tr>
<tr align="center">
<td>账号:</td>
<td><input type="text" name="usermame"/></td>
</tr>
<tr align="center">
<td>密码:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr align="center">
<td colspan="2"><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
</center>
-->
<h1><a href="login?usermame=zhangsan&password=111111">用户登录</a></h1>
</body>
</html>
package com.wangxing.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//得到账号和密码
String name=req.getParameter("usermame");
String pass=req.getParameter("password");
System.out.println(name+" "+pass);
}
}
Redirect和forward区别:
RequestDispatcher.forward(req, resp) | HttpServletRespone.sendRedirect() |
请求转发 | 重定向 |
使用的是同一个请求对象 | 使用的是不同的请求对象 |
浏览器地址栏中的url不会变 | 浏览器地址栏中的url会变化 |
可以通过HttpServletRequest对象传递数据 | 不可以通过HttpServletRequest对象传递数据 |
设置目标路径时“/”可以写也可以不写 | 设置目标路径时“/”一定不能写 |
依赖ServletRequest接口 | 依赖HttpServletRespone对象 |
2.会话跟踪
1.为什么需要会话跟踪会话跟踪?
使用浏览器发送的http请求,http请求使用的是http协议,而http协议是一种无状态的协议,它不会去主动记录使用这个http协议的用户是谁,一旦请求发送成功,服务器做出响应以后,那么
此时浏览器与服务器之间的链接就会消失,这时服务器就不知道请求来自哪里,是谁发送来的。所以这时我们就需要记录/保存请求/链接的状态,实现这个记录记录/保存请求/链接的状态的过程
就叫会话跟踪。
2.什么是会话跟踪?
服务器处理程序实现记录/保存请求/链接的状态的过程就叫会话跟踪。
3.四种会话跟踪技术有那些,它们各自的优缺点?
1.URL重写:将该用户Session的id信息重写到URL地址中,以便在服务器端进行识别不同的用户。
https://blog.csdn.net/qq_33098039/article/details/78184535?sessionid=123456
URL重写能够在客户端停用cookies或者不支持cookies的时候仍然能够发挥作用。
2.隐藏表单域:将用户Session的id信息添加到HTML表单元素<input type="hidden" name="" value=""/>中提交到服务器,此表单元素并不在客户端显示,浏览时看不到,源代码中有。
3.Cookie:Cookie是Web服务器发送给客户端的一小段信息,客户端请求时可以读取该信息发送到服务器端,进而进行用户的识别。服务器创建保存于浏览器端,不可跨域名性,大小及数
量有限。客户端可以采用两种方式来保存这个Cookie对象,一种方式是 保存在 客户端内存中,称为临时Cookie,浏览器关闭后 这个Cookie对象将消失。另外一种方式是保存在客户机的磁盘
上,称为永久Cookie。以后客户端只要访问该网站,就会将这个Cookie再次发送到服务器上,前提是 这个Cookie在有效期内。 这样就实现了对客户的跟踪。Cookie是可以被禁止的。
4.Session:每一个用户都有一个不同的session,各个用户之间是不能共享的,是每个用户所独享的,在session中可以存放信息。保存在服务器端。需要解决多台服务器间共享问题。如果
Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Session是依赖Cookie的,如果Cookie被禁用,那么session也将失效。
当用户第一次发送http请求到服务器,服务器端会创建一个session对象,产生一个sessionID来标识这个session对象,然后将这个sessionID放入到Cookie中发送到客户端,下一次发送http请求
到服务器时,http请求会连同第一次得到的sessionID会发送到服务器,在服务器端进行识别不同的用户。
上面的会话跟踪的过程与我们去超市的时候,在超市门口的储物柜中保存物品的过程相似。
4.Session和Cookie区别?
Cookie | Session |
数据由服务器创建保存于浏览器端 | 数据放在服务器上 |
cookie不是很安全 | Session很安全 |
减轻服务器性能应当使用cookie。 | 不考虑减轻服务器性能。可以使用Session |
单个cookie保存的数据不能超过4K | 没有限制 |
| Session是依赖Cookie的,如果Cookie被禁用,那么session也将失效。 |
5.HttpSession的常用方法
Servlet中的HttpSession接口--通过HttpServletRequest对象的getSession()方法得到HttpSession接口对象
HttpSession接口对象常用方法:
方法声明 | 功能描述 |
String getId() | 该方法用于得到sessionID |
long getCreationTime() | 该方法用于得到session对象的创建时间[毫秒] |
long getLastAccessedTime() | 该方法用于得到session的最后访问时间[毫秒] |
int getMaxInactiveInterval() | 该方法用于得到session的最大不活动时间[秒] |
boolean isNew() | 该方法用于session对象是否是一个新的session对象 |
void setAttribute(String args0, Object args1); | 该方法用于向创建的session对象中保存数据 |
Object getAttribute(String args0); | 该方法用于获取session对象中保存的指定数据 |
void removeAttribute(String args0); | 该方法用于移除保存在session对象中的指定数据 |
void invalidate() | 该方法用于销毁session对象 |
例如:登陆操作使用了HttpSession对象
package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 创建登陆页面的Servet
* @author Administrator
*
*/
public class LoginServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求的字符编码
req.setCharacterEncoding("utf-8");
//设置响应的字符编码
resp.setCharacterEncoding("utf-8");
//得到输出流对象
PrintWriter out=resp.getWriter();
//输出一个登陆页面
//out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset=\"utf-8\">");
out.println("<title>登陆</title>");
out.println("</head>");
out.println("<body>");
out.println("<center>");
//得到session对象
//1.通过HttpServletRequest对象的getSession()方法得到HttpSession接口对象
HttpSession session=req.getSession();
//输入session的基本信息
showSessionInfo(out,session);
//得到错误提示信息
Object obj=session.getAttribute("errortip");
if(obj!=null){
String errortip=(String)obj;
out.println("<font color=\"red\">"+errortip+"</font>");
}
out.println("<form action=\"cheack\" method=\"post\">");
out.println("用户名:<input name=\"username\" type=\"text\"><br>");
out.println("密码:<input name=\"password\" type=\"password\"><br>");
out.println("<input type=\"submit\" value=\"登陆\"/>");
out.println("</form>");
out.println("</center>");
out.println("</body>");
out.println("</html>");
out.close();
}
/**
* 输入session的基本信息
* @param out
* @param session
*/
private void showSessionInfo(PrintWriter out, HttpSession session) {
//得到session的基本信息
//得到sessionID
String sessionid=session.getId();
//创建时间日期格式化对象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
//得到session对象的创建时间[毫秒]
String createtime=sdf.format(new Date(session.getCreationTime()));
//得到session的最后访问时间[毫秒]
String lastAccesse=sdf.format(new Date(session.getLastAccessedTime()));
//得到session的最大不活动时间[秒]
int maxtime=session.getMaxInactiveInterval();
//session对象是否是一个新的session对象
boolean sessionnew=session.isNew();
out.println("<table border=\"1px\">");
out.println("<tr>");
out.println("<td>sessionID</td>");
out.println("<td>"+sessionid+"</td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td>session对象的创建时间</td>");
out.println("<td>"+createtime+"</td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td>session的最后访问时间[毫秒]</td>");
out.println("<td>"+lastAccesse+"</td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td>session的最大不活动时间[秒]</td>");
out.println("<td>"+maxtime+"</td>");
out.println("</tr>");
out.println("<tr>");
out.println("<td>是否是一个新的session对象</td>");
out.println("<td>"+sessionnew+"</td>");
out.println("</tr>");
out.println("</table>");
}
}
package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 创建验证用户名和密码的Servlet
* @author Administrator
*
*/
public class CheackServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求的字符编码
req.setCharacterEncoding("utf-8");
//设置响应的字符编码
resp.setCharacterEncoding("utf-8");
//得到用户名和密码
String username=req.getParameter("username");
String password=req.getParameter("password");
//判断用户名和密码
if(username.equals("zhangsan") && password.equals("123456")){
//跳转到成功页面
//封装用户名
req.setAttribute("username", username);
//请求转发
req.getRequestDispatcher("/success").forward(req, resp);
}else{
//封装错误提示信息跳转到登陆页面
//通过HttpSession对象封装数据
//setAttribute用于向创建的session对象中保存数据
req.getSession().setAttribute("errortip", "用户名密码不匹配");
resp.sendRedirect("login");
}
}
}
package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 创建登陆成功页面的Servet
* @author Administrator
*
*/
public class SuccessServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//从request中的得到username
Object obj=req.getAttribute("username");
String username="";
if(obj==null){
resp.sendRedirect("login");
}else{
username=(String)obj;
}
//设置请求的字符编码
req.setCharacterEncoding("utf-8");
//设置响应的字符编码
resp.setCharacterEncoding("utf-8");
//得到输出流对象
PrintWriter out=resp.getWriter();
//输出一个登陆页面
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset=\"utf-8\">");
out.println("<title>登陆</title>");
out.println("</head>");
out.println("<body>");
out.println("<center>");
out.println("<h1>"+username+",登陆成功!!!</h1>");
out.println("<a href=\"logout\">安全退出</a>");
out.println("</center>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 退出的Servlet
* @author Administrator
*
*/
public class LogOutServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求的字符编码
req.setCharacterEncoding("utf-8");
//设置响应的字符编码
resp.setCharacterEncoding("utf-8");
//销毁session对象
req.getSession().invalidate();
resp.sendRedirect("login");
}
}
3.Get与Post的区别?
Get | Post |
get通过地址栏传输 | post通过报文传输,也可以接收地址栏的数据 |
get参数有长度限制(受限于url长度) | post无限制,上传文件的时候一定是post |
GET产生一个TCP数据包 浏览器会把http header和data一并发送出去,服务器响应200(返回数据); | POST产生两个TCP数据包 浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。 |
安全性差 | 安全性好 |
数据查询时,建议用Get方式 | 数据添加、修改或删除时,建议用Post方式 |
GET在浏览器回退时是无害的 | 在浏览器回退时POST会再次提交请求 |
GET产生的URL地址可以被Bookmark | POST产生的URL地址不可以被Bookmark |
GET请求会被浏览器主动cache | POST不会被浏览器主动cache,除非手动设置。 |
GET请求只能进行url编码 | POST支持多种编码方式。 |
GET请求参数会被完整保留在浏览器历史记录里 | POST中的请求参数不会被保留在浏览器历史记录里。 |
参数的数据类型,GET只接受ASCII字符 | POST没有限制 |
GET参数通过URL传递 | POST放在Request body中 |
4.中文乱码的处理
网页----<meta charset="utf-8">
Eclipse---window-->preferences--->General---->workspace---->Text file encoding
Tomcat---默认的字符编码“iso8859-1”
服务器/conf目录/server.xml文件
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
1.页面提交到Servlet处理程序中的中文为乱码
Post提交方式 request.setCharacterEncoding(“utf-8”);
GET方式 String name = new String(name.getBytes(“iso8859-1”),“utf-8”);
2. Servlet处理程序向页面输出的中文为乱码
response.setCharacterEncoding("utf-8"); response.setHeader("Content-Type","text/html;charset=utf-8");