三、Servlet
Servlet概述
- servlet= server+applet :运行在服务器端的java程序
- Servlet是一个接口,一个类要想通过浏览器被访问到,那么这个类就必须直接或间接的实现Servlet 接口
- 作用:接收请求,处理逻辑,响应结果
Servlet快速入门
- 案例需求:编写一个普通的java类,通过浏览器可以访问
- 步骤分析
- ① 创建web项目
- ② 编写普通java类,实现servlet接口
- ③ 在web.xml配置url-pattern(servlet 访问路径)
- ④ 部署web项目
- ⑤ 启动测试
代码编写
-
① 使用IDEA创建web项目
-
② 编写普通java类,实现servlet接口
- 编写抽象方法(service方法)
package com.lagou.servlet; import javax.servlet.*; import java.io.IOException; public class QuickServlet implements Servlet { /* * init: servlet对象创建时,调用此方法完成初始化操作 */ @Override public void init(ServletConfig servletConfig) throws ServletException { } /* getServletConfig:获取servletConfig配置对象 */ @Override public ServletConfig getServletConfig() { return null; } /* 对外提供服务的方法,tomcat会调用servlet里面的service方法执行具体的业务逻辑 servletRequest:请求对象:借助该对象来获取请求参数 servletResponse:响应对象:借助该对象来向浏览器响应一些数据 */ /* * service:用户访问servlet时,调用此方法完成业务逻辑的处理 */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("servlet入门成功了...."); } /* * 获取servlet的描述信息 */ @Override public String getServletInfo() { return null; } /* * destroy:当servlet对象销毁,会调用此方法完成销毁操作 */ @Override public void destroy() { } }
-
③ 配置web.xml
- 配置servlet网络访问路径
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置QuickSerlvet servlet-name : 当前配置的servlet起一个别名(名称) servlet-class: 编写的就是配置的servlet的全限定类名 1 --> <servlet> <servlet-name>QuickServlet</servlet-name> <servlet-class>com.lagou.servlet.QuickServlet</servlet-class> </servlet> <!-- servlet-mapping:给servlet设置一个映射地址 servlet-name:给指定名称的servlet来配置映射地址 url-pattern:具体该serlvet的映射地址(访问路径)*必须以/开头 --> <servlet-mapping> <servlet-name>QuickServlet</servlet-name> <url-pattern>/quickServlet</url-pattern> </servlet-mapping> </web-app>
-
④ 部署web项目
使用IDEA + Tomcat部署项目
servlet执行原理
-
原理图
Servlet生命周期
生命周期相关
思想介绍
-
生命周期:指的是 一个对象从生(创建)到死(销毁)的一个过程
// 1. servlet对象创建时,调用此方法 public void init(ServletConfig servletConfig); // 2. 用户访问servlet时,调用此方法 public void service(ServletRequest servletRequest, ServletResponse servletResponse); // 3. servlet对象销毁时,调用此方法 public void destroy()
代码演示
-
① LifeServlet
package com.lagou.life; import javax.servlet.*; import java.io.IOException; public class LifeServlet implements Servlet { /* * init: servlet对象创建时,调用此方法完成初始化操作 */ @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("LifeServlet的init方法执行了,该对象被创建完成了..."); } @Override public ServletConfig getServletConfig() { return null; } /* * service:用户访问servlet时,调用此方法完成业务逻辑的处理 */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("LifeServlet的service方法执行了,执行了具体的业务逻辑..."); } @Override public String getServletInfo() { return null; } /* * destroy:当servlet对象销毁,会调用此方法完成销毁操作 */ @Override public void destroy() { System.out.println("LifeServlet的destroy方法执行了,该对象被销毁了..."); } }
-
② 配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--LifeSerlvet--> <servlet> <servlet-name>LifeSerlvet</servlet-name> <servlet-class>com.lagou.life.LifeServlet</servlet-class> <!--配置上该标签,serlvet就会在启动服务器的时候去完成实例化,并进行初始化操作 标签内部需要写数值 正整数 1-3在tomcat的web.xml被使用了,所以建议从4开始使用 --> <load-on-startup>4</load-on-startup> </servlet> <servlet-mapping> <servlet-name>LifeSerlvet</servlet-name> <url-pattern>/LifeSerlvet</url-pattern> </servlet-mapping> </web-app>
相关解析
- 创建
- 1)默认情况下
- 用户第一次访问时,创建servlet,执行init方法
- 2)修改创建时机
- <load-on-startup></load-onstartup>
- 正数:4-N 【服务器启动时,创建】
- 补充:Tomcat的web.xml里有1,3 所以推荐4-n
- 负数(默认值):-1 【用户第一次访问时,创建】
- 如果是默认情况下的创建,则用户发送请求后才创建servlet实例化,当有多个servlet并且多用户访问不同servlet时,每个servlet都需要实例化,需要耗费长时间,体验不好,所以需要修改创建时机
- 1)默认情况下
- 运行(提供服务)
- 用户每次访问时,都执行service方法
- 销毁
- 服务器正常关闭时,销毁servlet,执行destroy方法
笔试题
- 问题:请描述下servlet的生命周期
- 答案:servlet是一个单实例多线程的,默认情况下,第一次请求来的时候,才会对该servlet进行实 例化,并执行初始化init方法,随后再执行service方法完成业务处理,当每一次请求发送过来,都会重新开启一个线程,来执行servlet中的service方法,当服务器关闭或者servlet被移除的时候,会执行 destory方法
Servlet体系结构
-
主要讲解其他方式创建Servlet服务
-
体系结构图
GenericServlet
-
GenericServlet是Servlet的实现类,其为抽象类,重写了大部分Servlet接口的方法,编写普通java类继承GenericServlet时,只需要重写service方法,使得代码更简洁
-
① 编写普通java类,继承GenericServlet抽象类
package com.lagou.servlet; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; public class ServletDemo1 extends GenericServlet { @Override public void init() throws ServletException { super.init(); System.out.println("ServletDemo1的初始化方法执行了.."); } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("ServletDemo1 extends GenericServlet..."); } @Override public void destroy() { super.destroy(); System.out.println("ServletDemo1的销毁方法执行了"); } }
-
② 配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--ServletDemo1--> <servlet> <servlet-name>ServletDemo1</servlet-name> <servlet-class>com.lagou.servlet.ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo1</servlet-name> <url-pattern>/servletDemo1</url-pattern> </servlet-mapping> </web-app>
HttpServlet
-
HttpServlet继承了GenericServlet,其是抽象类,用来处理HTTP协议中的交互,其可以根据不同的请求方法做出不同的处理;其内部又定义了不同请求的处理方法,普通java类继承HttpServlet只需要重写请求处理方法既可
-
HttpServlet为最常用的创建Servlet服务的方式
-
① 编写前端html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>用户登录</h3> <form action="http://localhost:8080/servlet_demo/servletDemo2" method="post"> <input type="submit" value="提交表单"> </form> <a href="/servlet_demo/mimeServlet?fileName=a.jpg">获取文件的mime类型</a> </body> </html>
-
② 编写普通java类,继承HttpServlet抽象类
package com.lagou.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ServletDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("ServletDemo2中的doGet方法执行了..."); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("ServletDemo2中的doPost方法执行了..."); } }
-
③ 配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--ServletDemo1--> <servlet> <servlet-name>ServletDemo2</servlet-name> <servlet-class>com.lagou.servlet.ServletDemo2</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo2</servlet-name> <url-pattern>/servletDemo2</url-pattern> </servlet-mapping> </web-app>
url-pattern的配置方式
-
单映射
Servlet映射多个url
-
多映射
url映射模式
-
配置 url地址取值可以是
- 精确匹配(掌握)
- /servletDemo3 localhost:8080/项目路径/servletDemo3
- 目录匹配
- /aa/*
- 后缀匹配
- .xxx 例如:*.do
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 只要浏览器符合目录匹配规则,都可以访问到这个servlet: /aa/abc /aa/asadfasdf --> <servlet> <servlet-name>ServletDemo4</servlet-name> <servlet-class>com.lagou.servlet.QuickServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo4</servlet-name> <url-pattern>/aa/*</url-pattern> </servlet-mapping> <!-- 只要浏览器符合后缀匹配规则,都可以访问到这个servlet aa.do bb.do xx.do --> <servlet> <servlet-name>ServletDemo5</servlet-name> <servlet-class>com.lagou.servlet.QuickServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletDemo5</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
- 精确匹配(掌握)
Request对象
request对象概述
-
用户通过浏览器访问服务器时,Tomcat将HTTP请求中所有的信息都封装在Request对象中
-
作用:开发人员可以通过request对象方法,来获取浏览器发送的所有信息
获取请求行信息
-
例如: GET /servlet_demo/requestDemo1 HTTP/1.1
-
相关API:
- 1.获取请求方式 GET【掌握】
- String getMethod()
- 2.获取项目虚拟路径(项目名)/servlet_demo【掌握】
- String getContextPath()
- 3.获取URL http://localhost:8080/servlet_demo/requestDemo1
- 统一资源定位符(确定某一个地址) 中华人民共和国
- StringBuffer getRequestURL()
- 4.获取协议和版本号 HTTP/1.1
- String getProtocol()
- 5.获取客户端ip
- String getRemoteAddr()
- 1.获取请求方式 GET【掌握】
-
代码演示
package com.lagou.request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RequestDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 演示request对象获取请求行信息 System.out.println("请求方式:" + request.getMethod()); System.out.println("虚拟路径:" + request.getContextPath()); System.out.println("URL:" + request.getRequestURL()); System.out.println("协议和版本:" + request.getProtocol()); System.out.println("客户端IP地址:"+ request.getRemoteAddr()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
获取请求头信息
-
例如: Host: 127.0.0.1:8080
-
相关API:
- 1.获取知道请求头名称对应的值,注:名称不区分大小写
- String getHeader(String name)
- 2.获取所有请求头的名称
- Enumeration<String> getHeaderNames()
- 注:是Iterator前身
- 1.获取知道请求头名称对应的值,注:名称不区分大小写
-
代码演示
package com.lagou.request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; public class RequestDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { // 获取请求头信息 // 获取指定的头信息 Host String host = request.getHeader("Host"); System.out.println(host); // 先获取到所有的请求头名称 Enumeration<String> headerNames = request.getHeaderNames(); //遍历 while (headerNames.hasMoreElements()){ // 请求头名称 String name = headerNames.nextElement(); // 根据名称获取值 String value = request.getHeader(name); System.out.println(name + ":" + value); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
获取请求体信息(请求参数)
-
不论get还是post请求方式,都可以使用下列方法来获取请求参数
-
参数
- username=jack&password=123&hobby=drink&hobby=perm
-
相关API
- 获取指定参数名的值 username=jack
- String getParameter(String name)
- 获取指定参数名的值数组 hobby=drink&hobby=perm
- String[] getParameterValues(String name)
- 获取所有参数名和对应值数组,参数名 name(key),值数组 value,封装map集合
- Map<String,String[]> getParameterMap()
- 中文乱码【重点】
- get:在tomcat8及以上版本,内部URL编码(UTF-8)
- post:编码解码不一致,造成乱码现象
- 客户端(浏览器)编码:UTF-8
- 服务器默认 解码:ISO-8859-1 拉丁文
- 指定解码:void setCharacterEncoding(String env)
- 注:其必须在方法内,且是行首
- 获取指定参数名的值 username=jack
-
代码演示
package com.lagou.request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.Map; public class RequestDemo3 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { // 设置解码为UTF-8 ,解决post中文乱码问题 request.setCharacterEncoding("UTF-8"); // 获取表单提交的请求参数 String username = request.getParameter("username"); System.out.println("用户名:" + username); // 获取爱好这样的多个value的数组类型 String[] hobbies = request.getParameterValues("hobby"); System.out.println( Arrays.toString(hobbies)); // 获取所有的请求参数的key和value // String:表单中的name属性值 String[]:请求参数的value值 Map<String, String[]> parameterMap = request.getParameterMap(); parameterMap.forEach((k,v)->{ System.out.println(k + "=" + Arrays.toString(v)); }); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { // 设置解码为UTF-8 ,解决post中文乱码问题 doGet(request, resp); //让doGet方法中业务逻辑执行 } }
请求转发
-
一种在服务器内部的资源跳转方式
-
相关API
方法 | 描述 |
---|---|
RequestDispatcher getRequestDispatcher(String path) | 通过reqeust对象,获得转发器对象 (path为要跳转到的路径) |
void forward(ServletRequest request, ServletResponse response) | 通过转发器对象,实现转发功能 |
-
请求转发特点
- 浏览器:发了一次请求
- 地址栏:没有发生改变
- 只能转发到服务器内部资源…
-
链式编程
- request.getRequestDispatcher("/bServlet").forward(reqeust,response)
-
代码演示
- AServlet
package com.lagou.request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class AServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { System.out.println("AServlet中功能上执行了"); // 请求转发到Bservelt String path: 写的就是要跳转的资源路径 // 1.获取到转发器对象 // RequestDispatcher requestDispatcher = request.getRequestDispatcher("https://www.baidu.com/"); // 2.借助转发器对象进行真正的请求转发 // requestDispatcher.forward(request,resp); // 链式编程 request.getRequestDispatcher("/bServlet").forward(request,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
- BServlet
package com.lagou.request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class BServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("BServlet中功能下执行了"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
域对象(共享数据)
-
域对象:一个有作用范围的对象,可以在范围内共享数据
-
request域:代表一次请求的范围,一般用于一次请求中转发的多个资源中共享数据
-
相关 API
方法 描述 void setAttribute(String name, Object o) 设置数据 Object getAttribute(String name) 获取数据 void removeAttribute(String name) 删除数据 -
生命周期
- 何时创建
- 用户发送请求时,创建request
- 何时销毁
- 服务器返回响应是,销毁request
- 作用范围
- 一次请求,包含多次转发
- 何时创建
-
代码演示
- AServlet
package com.lagou.request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class AServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { System.out.println("AServlet中功能上执行了"); request.setAttribute("haobao", "香辣鸡腿堡"); // 链式编程 request.getRequestDispatcher("/bServlet").forward(request,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
- BServlet
package com.lagou.request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class BServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 从request域中取出数据 String hanbao = (String) req.getAttribute("hanbao"); System.out.println(hanbao); System.out.println("BServlet中功能下执行了"); // 删除request域中数据 req.removeAttribute("hanbao"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
Response对象
概述
-
response对象表示web服务器给浏览器返回的响应信息
-
作用:开发人员可以使用response对象的方法,设置要返回给浏览器的响应信息
-
Response体系结构
ServletResponse 接口 | HttpServletResponse 接口 | org.apache.catalina.connector.ResponseFacade 实现类(由tomcat提供的)
设置Http响应消息
-
响应行
* 格式 协议/版本号 状态码 * 例如 HTTP/1.1 200 * API 1. 设置状态码 void setStatus(int sc) 200 302 304 404 500
-
响应头
* 格式 响应头名称:响应头的值 * 例如 Location:http://www.lagou.com * API 1. 设置指定头名称和对应的值 void setHeader(String name, String value)
-
响应体
* API(输出流对象) 1. 字符输出流 PrintWriter getWriter() 2. 字节输出流 ServletOutputStream getOutputStream() 注意:在同一个servlet中,二种类型的输出流不能同时存在,互斥
响应重定向
-
重定向理解图
-
需求:用户访问AServlet后,服务器告诉浏览器重定向到BServlet
-
步骤分析
* 方式一 // 1.设置状态码 response.setStatus(302); // 2.设置响应头 Location response.setHeader("Location","重定向网络地址"); * 方式二 // 1.response这哥们封装专门处理重定向的方法 response.sendRedirect("重定向网络地址");
-
重定向特点
- 地址栏会发生改变
- 重定向是二次请求
- 重定向是客户端(浏览器)行为,可以跳转到服务器外部资源…
- 不能使用request域共享数
-
请求转发与重定向的区别
1. 哪个对象 转发(request对象的方法) request.getRequestDispatcher("/bServlet").forward(request,response); 重定向(response对象的方法) response.sendRedirect("/day10_response/bServlet"); 2. 几次请求 转发 地址栏: 没有改变 浏览器: 发了一次请求 服务器: 只有一对请求和响应对象 发生的位置: 服务器 重定向 地址栏: 发生了改变 浏览器: 发了两次请求 服务器: 有两对请求和响应对象 发生的位置: 浏览器 3. 小结 写法 转发("/servlet资源路径") 服务器内部行为 重定向 ("/虚拟路径(项目名)/servlet资源路径") 浏览器外部行为 使用场景(重点掌握) 如果需要传递数据(request域),使用转发 如果不需要传递数据(request域),使用重定向
-
代码演示
- CServlet
package com.lagou.response; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("访问到了CSerlvet,接下来重定向到DServlet"); // 设置重定向 /* resp.setStatus(302); resp.setHeader("Location","dServlet");*/ // 设置重定向 方式二:常用 resp.sendRedirect("https://www.lagou.com/"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- DServlet
package com.lagou.response; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class DServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("DServlet执行了....."); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
响应中文
-
需求:向页面输出中文数据没有乱码
-
步骤分析
1. 通过response获取字符输出流 PrintWriter pw = response.getWriter(); 2. 通过字符输出输出文本 pw.write("中文....");
-
解决中文乱码
1. 指定服务器响应编码方式 response.setCharacterEncoding("GBK"); 2. 统一浏览器和服务器编码(常用) response.setContentType("text/html;charset=utf-8");
-
代码演示
package com.lagou.response; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class EncodeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置编码时,一定要写在首行 //resp.setCharacterEncoding("GBK"); // 统一浏览器和服务器编码 resp.setContentType("text/html;charset=utf-8"); // 向页面输出中文 PrintWriter writer = resp.getWriter(); writer.write("中文.."); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
ServletContext对象
概述
-
web容器(tomcat)在启动时,它会为每个web项目承建一个对应的ServletContext对象
-
ServletContext对象 代表:当前web项目
主要作用
- 其是域对象(用于共享数据)
- 获取资源在服务器的真实地址
- 获取全局的配置参数
- 获取文件MIME类型
获取ServletContext对象
-
1. 通过request对象获得 ServletContext sc = request.getServletContext(); 2. 继承HttpServlet后,可以直接调用 ServletContext sc = this.getServletContext();
域对象(共享数据)
-
在当前项目范围内,共享数据(多个servlet都可以获取)
-
相关方法
1. 存储数据 void setAttribute(String name,Object value) 2. 获取数据 Object getAttribute(String name) 3. 删除数据 void removeAttribute(String name)
-
生命周期
1. 何时创建? 项目加载时,创建 2. 何时销毁? 项目卸载时,销毁 3. 作用范围? 与项目共存亡(多个servlet都可以操作它)
-
代码演示
- OneServlet
package com.lagou.servletContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class OneServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 向servletContext域对象中存入数据 // ServletContext servletContext1 = this.getServletContext(); ServletContext servletContext = req.getServletContext(); servletContext.setAttribute("user","jack"); System.out.println("OneServlet中存入了数据...."); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- TwoServlet
package com.lagou.servletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TwoServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 从servletContext域中取出数据 String user = (String) req.getServletContext().getAttribute("user"); System.out.println("TwoServlet中取出的数据为" + user); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
获取资源在服务器的真实地址
-
可以实现web项目的移植性…动态获取文件真实路径
-
文件的真实路径并不是文件在项目中所放的位置,而是项目启动后,被放在一个加载目录中
-
相关API
-
String getRealPath(String path)
-
代码演示
package com.lagou.servletContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RealpathServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取lagou.jpg文件的真实路径 ServletContext servletContext = req.getServletContext(); String realPath = servletContext.getRealPath("/img/lagou.jpg"); System.out.println(realPath); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
获取全局的配置参数
-
读取web.xml配置文件中标签信息,实现参数和代码的解耦(多个servlet都可以获取)
-
相关API
- String getInitParameter(String name)
-
代码演示
- web.xml配置全局参数
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--全局配置参数:所有的servlet都可以读取...--> <context-param> <param-name>encode</param-name> <param-value>UTF-8</param-value> </context-param> </web-app>
- OneServlet
package com.lagou.servletContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class OneServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = req.getServletContext(); // servletContext获取到全局配置参数 String encode = servletContext.getInitParameter("encode"); System.out.println("获取到的全局配置参数-"+ encode); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
获取文件MIME类型
-
在互联网通信过程中定义的一种文件数据类型格式
-
格式: 大类型/小类型 例如: text/html image/jpeg
-
相关API
- Sting getMimeType(String filename)
-
代码演示
package com.lagou.servletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class MimeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取指定文件的mime类型 // servlet_demo/mimeServlet?fileName=a.jpg // 获取请求参数 String fileName = req.getParameter("fileName"); // 获取文件的mime类型 String mimeType = req.getServletContext().getMimeType(fileName); resp.getWriter().write(fileName + "----" + mimeType); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
案例:统计网站的访问次数
-
需求:一般个人博客的首页,都会显示你是第几位访问此网站…
-
思路图
-
代码演示
- web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--CountServlet--> <servlet> <servlet-name>CountServlet</servlet-name> <servlet-class>com.lagou.servletContext.CountServlet</servlet-class> <load-on-startup>4</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CountServlet</servlet-name> <url-pattern>/countServlet</url-pattern> </servlet-mapping> </web-app>
- CountServlet
package com.lagou.servletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CountServlet extends HttpServlet { @Override public void init() throws ServletException { // 向servletContext域中存入变量count,并且初始值为0 this.getServletContext().setAttribute("count",0); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 设置响应编码 resp.setContentType("text/html;charset=utf-8"); //2. 向页面响应信息 resp.getWriter().write("<h1>拉勾博客</h1>"); //3.进行servletContext域中的取值 取 加 存 0 // 取 Integer count = (Integer) this.getServletContext().getAttribute("count"); // 加 count++; resp.getWriter().write("<dev>你是,第"+ count + "位访问此网站的人</dev>"); // 存 this.getServletContext().setAttribute("count",count); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
注:本内容为个人拉勾教育大数据训练营课程笔记