【JavaEE之Servlet】
2020.10.16 coin
一:Servlet的实现
Servlet的实现
1. 新建包,并新建普通Class类
2. 继承 HttpServlet 类 (实现Servlet规范)
3. 重新 HttpServlet 类中的 service() 方法 (service 方法在servlet类被访问时,自动调用。作用:接收请求,响应结果)
4. 在 Servlet 上添加注解 @WebServlet, 设置 Servlet 类的访问路径 (资源的对外访问路径:浏览器通过访问该路径,从而访问到 Servlet类)
注:
1. servive方法是由服务器自动调用 (当 Servlet 类被访问时)
2. 设置 Servlet 类的访问路径时,需要添加 "/" !!!(不加"/",会报错) java.lang.IllegalArgumentException: Invalid <url-pattern> [ser01] in servlet mapping
3. 在同一个项目下,Servlet类的对外访问路径值唯一 (不能重复)
4. 访问 Servlet 时,路径格式如下: http://localhost:端口/项目路径/资源路径?参数名=参数值** 项目路径:站点名,项目对外访问路径,在Tomcat中设置 (Deployment属性中设置 Application context)
资源路径:servlet 对外访问路径,通过 @WebServlet 注解设置
@WebServlet("/ser01")
// @WebServlet(name = "Servlet01", value = "/ser01")
// @WebServlet(name = "Servlet01", urlPatterns = "/ser01")
// @WebServlet(value = {"/ser01","/ser02"})
// @WebServlet(urlPatterns = {"/ser01","/ser02"})
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Hello Servlet!");
// 响应数据 resp.getWriter().write("Hello"); }}
@WebServlet("/ser02")
public class Servlet02 extends HttpServlet {
/**
* 接收GET请求
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 调用POST方法,代码写在doPost方法中 doPost(req,resp); }
/**
* 接收POST请求
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
1.1 Servlet的生命周期
* 1. 初始化
* init()
* 系统方法,服务器自动调用,只会执行一次。
* 当一次访问Servlet时触发。
* 2. 就绪/调用
* service()
* 系统方法,服务器自动调用,可以调用多次。
* 当有请求访问servlet时,servcie就会被调用
* 3. 销毁
* destory()
* 系统方法,服务器自动调用,只会执行一次。
* 当服务器关闭时触发。
@WebServlet("/ser03")
public class Servlet03 extends HttpServlet {
/**
* init()
* 系统方法,服务器自动调用,只会执行一次。
* 当一次访问Servlet时触发。
* @throws ServletException
*/
@Override
public void init() throws ServletException {
System.out.println("init...");
}
/**
* service()
* 系统方法,服务器自动调用,可以调用多次。
* 当有请求访问servlet时,servcie就会被调用
* @param req
* @param resp
* @throws ServletException * @throws IOException
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service...");
}
/**
* destory()
* 系统方法,服务器自动调用,只会执行一次。
* 当服务器关闭时触发。
*/
@Override
public void destroy() {
System.out.println("destroy..."); }
}
1.2 获取请求
/**
* 获取请求
* 常用请求方法
* 获取请求参数
*/
@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
/*
常用请求方式
http://localhost:8080/s02/ser01?uname=zs&upwd=123
*/
// 获取客户端请求的完整URL (从http开始,到?前面结束)
String url = request.getRequestURL().toString(); System.out.println("获取客户端请求的完整URL:" + url);
// 获取客户端请求的部分URL (从站点名开始,到?前面结束)
String uri = request.getRequestURI(); System.out.println("获取客户端请求的部分URL:" + uri);
// 获取请求行中的参数部分
String queryString = request.getQueryString(); System.out.println("获取请求行中的参数部分:" + queryString);
// 获取客户端的请求方式
String method = request.getMethod();
System.out.println("获取客户端的请求方式:" + method);
// 获取HTTP版本号
String protocol = request.getProtocol(); System.out.println("获取HTTP版本号:" + protocol);
// 获取webapp名字 (站点名)
String webapp = request.getContextPath();
System.out.println("获取webapp名字:" + webapp);
/**
* 获取请求参数
* 1. 通过参数名获取参数值,返回字符串
* request.getParameter("参数名")
* 参数名:
* 1. 表单元素的name属性值
* 2. ajax的data属性的值的键
* 3. 超链接参数的键
* 2. 通过参数名获取所有的参数值,返回数组
*/
// 获取用户名
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
System.out.println("姓名:" + uname + ",密码:" + upwd);
// 通过参数名获取所有的参数值,返回数组
String[] hobbys = request.getParameterValues("hobby");
System.out.println(hobbys.length); }
}
1.3 请求乱码问题
/**
* 请求乱码问题
* 乱码原因:
* request有默认的编码格式,默认编码是IOS-8859-1,这种编码格式不支持中文。
* 乱码情况:
* Tomcat7及以下版本:GET请求与POST请求都会乱码
* Tomcat8及以上版本:GET请求不会乱码,POST请求会乱码
* 解决方法:
* 解决POST请求乱码
* 方式一:设置请求的编码格式 (只针对POST请求)
* request.setCharacterEncoding("UTF-8");
* 方式二:通过new String()
* new String(request.getParameter(name).getBytes("ISO-8859-1"), "UTF-8");
*/
@WebServlet("/ser02")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 在参数获取前,设置编码
// req.setCharacterEncoding("UTF-8");
System.out.println(req.getParameter("name"));
// 单独处理乱码参数
System.out.println(new String(req.getParameter("name").getBytes("ISO-8859-1"), "UTF-8"));
}
}
1.4 请求转发问题
/**
* 请求转发
* 服务端的一种跳转方式
* 格式:
* req.getRequestDispatcher("路径").forward(req,resp);
* 特点:
* 1. 地址栏不发生改变
* 2. 服务端行为
* 3. 请求转发只有一次请求
* 4. request对象可以共享
*/
@WebServlet("/ser03")
public class Servlet03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet03...");
// 请求的用户名和密码
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
System.out.println("姓名:" + name + ",密码:" + pwd);
// 请求转发跳转到首页
req.getRequestDispatcher("index.jsp").forward(req,resp);
}
}
1.5 request作用域
/**
* request作用域
* 只在一次请求中有效,只在请求转发中有效
* 设置作用域
* request.setAttribute("参数名",参数值);
* 获取作用域
* request.getAttribute("参数名");
* 移除作用域
* request.removeAttribute("参数名");
*/
@WebServlet("/ser04")
public class Servlet04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet04...");
String uname = "zhangsan";
String upwd = "admin";
List<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
// 设置到request作用域中
req.setAttribute("userName", uname);
req.setAttribute("userPwd", upwd);
req.setAttribute("list", list);
// 请求转发跳转到首页
req.getRequestDispatcher("index.jsp").forward(req,resp);
}
}
1.6 响应数据
/**
* 响应数据
* 字符输出流
* getWriter() 向客户输出字符
* 字节输出流
* getOutputStream() 可以向客户端输出任意内容
*
* 注:两个方法不能同时使用
* java.lang.IllegalStateException: getWriter() has already been called for this response
*
*/
@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置响应类型
resp.setHeader("content-type","text/html"); /**
* 字符流
*/
PrintWriter writer = resp.getWriter();
// writer.write("Hello 01");
writer.write("<h2>Hello 01</h2>");
writer.close();
}
}
@WebServlet("/ser02")
public class Servlet02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置响应类型
resp.setHeader("content-type","text/html");
/**
* 字节流
*/
ServletOutputStream out = resp.getOutputStream();
out.write("<h2>Hello 02</h2>".getBytes());
out.close();
}
}
1.7 响应数据乱码
/**
* 响应数据乱码
* 乱码原因:
* 在响应中,如果我们响应的内容中含有中文,则有可能出现乱码。
* 这是因为服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
* 乱码情况:
* 1. getWriter()字符输出流
* 响应中文必定出乱码。由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。
* 2. getOutputStream()字节输出流
* 可能会出现乱码。响应中文时,由于本身就是传输的字节, 所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。
*
* 乱码原因:
* 客户端与服务端的编码不一致,或编码不支持中文。
*
* 解决方案:
* 1. 设置客户端与服务端的编码格式一致
* 2. 设置客户端与服务端的编码格式都支持中文
*
*
* 设置客户端的编码格式
* response.setHeader("content-type", "text/html;charset=UFT-8");
* 设置服务端的编码格式
* response.setChacaterEncoding("UTF-8");
* 或
* 同时设置客户端与服务端的编码
* response.setContentType("text/html;charset=UTF-8");
*
*
*/
@WebServlet("/ser03")
public class Servlet03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置服务端的编码格式
// resp.setCharacterEncoding("UTF-8");
// 设置客户端的编码格式
// resp .setHeader("content-type","text/html;charset=UTF-8");
// 同时设置客户端与服务端的编码格式
resp.setContentType("text/html;charset=UTF-8");
/**
* 字符流
*/
PrintWriter writer = resp.getWriter();
// writer.write("Hello 01");
writer.write("<h2>你好 01</h2>");
writer.close();
}
}
//--------------------------------------------------
@WebServlet("/ser04")
public class Servlet04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置服务端的编码格式
// resp.setCharacterEncoding("UTF-8");
// 设置客户端的编码格式
// resp .setHeader("content-type","text/html;charset=UTF-8");
// 同时设置客户端与服务端的编码格式
resp.setContentType("text/html;charset=UTF-8");
/**
* 字节流
*/
ServletOutputStream out = resp.getOutputStream();
out.write("<h2>你好 02</h2>".getBytes("UTF-8"));
out.close();
}
}
1.8 重定向
/**
* 重定向
* 服务端指导,客户端行为的跳转方式
*
* 特点:
* 1. 地址栏会发生改变
* 2. 客户端跳转
* 3. 有两次请求
* 4. request对象不共享
*
*
*/
@WebServlet("/ser05")
public class Servlet05 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet05...");
// 接收参数
System.out.println("姓名:" + req.getParameter("name"));
// 设置request作用域
req.setAttribute("admin","admin");
// 重定向跳转到首页
resp.sendRedirect("index.jsp");
}
}
//-------------------------------------------
/**
* 请求转发与重定向
* 1. 请求转发的地址栏不发生改变,重定向的地址栏会改变
* 2. 请求转发是服务端跳转,重定向是客户端跳转
* 3. 请求转发只有一次请求,重定向有两次请求
* 4. 请求转发的request作用域可以共享,重定向的request作用域不能共享
* 5. 请求转发的地址只能跳转到当前项目的资源,重定向可以跳转到任意资源
*
*/
@WebServlet("/ser06")
public class Servlet06 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet06...");
// 设置request作用域
req.setAttribute("admin","admin");
// 请求转发
// req.getRequestDispatcher("index.jsp").forward(req,resp);
// 重定向
// resp.sendRedirect("index.jsp");
// 跳转到百度
// req.getRequestDispatcher("http://www.baidu.com").forward(req,resp);
resp.sendRedirect("http://www.baidu.com");
}
}
二:Cookie
2.1 Cookie
/**
* Cookie
* 是浏览器提供的一种技术
*
* Cookie对象的创建与发送
*/
@WebServlet("/cook01")
public class Cookie01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 得到Cookie对象
Cookie cookie = new Cookie("uname","admin");
// 响应cookie对象
resp.addCookie(cookie);
Cookie cookie02 = new Cookie("uname02","zhangsan");
resp.addCookie(cookie02);
}
}
2.2 Cookie获取
/**
* Cookie的获取
* 获取所有的cookie对象,返回cookie数组
* Cookie[] cookies = request.getCookies();
*/
@WebServlet("/cook02")
public class Cookie02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取所有的cookie对象,返回cookie数组
Cookie[] cookies = req.getCookies();
// 判断cookie是否存在 ,遍历获取值
if (cookies != null && cookies.length >0) {
for(Cookie cookie : cookies) {
System.out.println("名称:" + cookie.getName() + ",值:" + cookie.getValue());
// 获取指定cookie对象
if ("uname".equals(cookie.getName())) {
System.out.println("指定值为:" + cookie.getValue());
}
}
}
}
}
2.3 Cookie的到期时间
/**
* Cookie的到期时间
* maxAge
* 设置cookie对象失效的时间,单位秒
*
* 正整数:
* 表示cookie会存活指定秒数
* 负整数:(默认-1,浏览器关闭失效)
* 表示cookie只在浏览器中存活,浏览器关闭则失效
* 零:
* 表示即刻删除,删除cookie对象
*/
@WebServlet("/cook03")
public class Cookie03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取cookie对象
Cookie cookie = new Cookie("uname03","lisi");
// 设置失效时间
cookie.setMaxAge(-1); // 负整数,浏览器关闭失效,默认
resp.addCookie(cookie);
// 获取cookie对象
Cookie cookie02 = new Cookie("uname04","wangwu");
// 设置失效时间
cookie02.setMaxAge(20); // 正整数,存活指定秒数
resp.addCookie(cookie02);
// 获取cookie对象
Cookie cookie03 = new Cookie("uname05","zhaoliu");
// 设置失效时间
cookie03.setMaxAge(0); // 0,表示删除
resp.addCookie(cookie03);
// 如果cookie对象存在,删除cookie
Cookie cook = new Cookie("uname",null);
cook.setMaxAge(0);
resp.addCookie(cook);
}
}