Servlet
Servlet是一个Java程序 是运行在服务器上 处理客户端请求并作出响应

Servlet声明周期

生命周期的各个阶段

Servlet构造方法
构造方法只有首次调用Servlet时,会被执行,后续请求不在执行
1 2 3 4 5
| public HelloServlet() { System.out.println("创建HelloServlet对象"); }
|
init()方法
init方法被设计成只调用一次
它在第一次创建Servelt时,被调用,在后续每次用户请求时,不再调用。因此,它是用于一次性初始化。
1 2 3 4 5 6 7
| @Override public void init(ServletConfig config) throws ServletException { System.out.println("开始初始化"); super.init(config); }
|
service方法
service()方法是执行实际任务的主要方法
Servlet容器(即Web服务器)调用service()方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
1 2 3 4 5 6 7
| @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("service方法执行"); super.service(req, resp); }
|
doGet()方法
get请求来自于一个URL的正常请求,或者来自于一个未指定Method的HTML表单,它由doGet()方法处理。
1 2 3 4 5 6 7
| @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet方法执行"); }
|
doPost()方法
post请求来自于一个特别指定了Method为POST的HTML表单,它由doPost()方法处理。
1 2 3 4
| @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }
|
destroy()方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
1 2 3 4 5 6 7
| @Override public void destroy() { System.out.println("destroy方法执行"); super.destroy(); }
|
@webservlet注解的作用
Servlet3.0提供了注解(annotation),我们可以不用在web.xml里面配置servlet,只需要加上@WebServlet注解就可以修改该servlet的属性了。web.xml可以配置的servlet属性,在@WebServlet中都可以配置。
1 2 3
| @WebServlet(name = "MyHelloServlet", urlPatterns = "/hello")
|
可以通过 @WebInitParam 来设置初始化参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @WebServlet( urlPatterns = "/hello", initParams = { @WebInitParam(name = "websiteName", value = "MyAwesomeSite"), @WebInitParam(name = "adminEmail", value = "admin@example.com") } ) public class HelloServlet extends HttpServlet {
@Override public void init() throws ServletException { ServletConfig config = getServletConfig(); String name = config.getInitParameter("websiteName"); String email = config.getInitParameter("adminEmail"); System.out.println("网站名称:" + name); System.out.println("管理员邮箱:" + email); }
protected void doGet(HttpServletRequest req, HttpServletResponse resp) { } }
|
@WebServlet 的属性列表

servlet的url-pattern匹配规则
url-pattern 是设置映射关系的 它支持三模式
精准模式
1 2 3 4
| <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello-servlet</url-pattern> </servlet-mapping>
|
路径匹配
以/ 或者 /*结尾是匹配路径
1 2 3 4
| <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello-servlet/*</url-pattern> </servlet-mapping>
|
后缀匹配
1 2 3 4
| <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping>
|
传入参数获取参数
将参数存储在web.xml的init-param中,可以给程序提供更多的灵活性。可以在init启动的时候getInitParameter(“参数名”)获取值
1 2 3 4 5 6 7 8 9 10 11 12
| <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>org.example.demo1.HelloServlet</servlet-class> <init-param> <param-name>name</param-name> <param-value>moonsec</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello-servlet</url-pattern> </servlet-mapping>
|
1 2 3 4
| public void init() { message = "Hello World!"; System.out.println(getInitParameter("name")); }
|
也可以在doGet方法里使用req.getParameter来获取参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.name=req.getParameter("name"); this.age=req.getParameter("age"); System.out.println("doGet方法,每次请求调用"); resp.setContentType("text/html; charset=UTF-8"); PrintWriter out=resp.getWriter(); out.println("<html><body>"); out.println("<h1>"+message+"</h1>"); out.println(name); out.println(":"); out.println(age); out.println("</html></body>");
}
|
Servlet 请求和响应
Request
Request即HttpRequest,可以获取客户端相关的信息、获取请求头以及获取请求参数等。
获取客户端相关的信息
常使用的API有如下
1 2 3 4 5 6 7 8 9 10 11
| getRequestURL
getRequestURI
getQueryString
getRemoteAddr
getMethod
getContextPath
|
获取请求参数
1 2 3 4 5 6 7
| getParameter(String name)
getParameterValues(String name)
getParameterMap()
getParameterNames()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| @WebServlet("/request") public class RequestServlet extends HttpServlet {
@Override public void init() throws ServletException { super.init(); }
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.service(req, resp); }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html; charset=UTF-8"); System.out.println("获取客户端数据"); System.out.println("获取请求url:"+req.getRequestURL()); System.out.println("获取请求参数:"+req.getQueryString()); System.out.println("获取请求方法:"+req.getMethod()); System.out.println("获取请求ip:"+req.getRemoteAddr()); System.out.println("获取虚拟目录:"+req.getContextPath()); System.out.println("获取servlet名称:"+req.getServletPath()); System.out.println("获取参数数据"); System.out.println("获取Get请求参数:"+req.getQueryString()); String username=req.getParameter("username"); Integer age=Integer.parseInt(req.getParameter("age")); System.out.println(String.format("username is %s and age is %d ", username, age)); resp.getWriter().println(String.format("username is %s and age is %d ", username, age)); if (req.getQueryString()!= null){ resp.getWriter().write("只能写文本"); }
for (String hobby : req.getParameterValues("hobby")) { System.out.println(hobby); }
Map<String, String[]> parameterMap = req.getParameterMap(); for(String key:parameterMap.keySet()){ for (String s: parameterMap.get(key)){ System.out.println(s); }
}
Enumeration<String> parameterNames = req.getParameterNames(); while (parameterNames.hasMoreElements()){ String name =(String) parameterNames.nextElement(); String value = req.getParameter(name); System.out.println("请求参数:" + name + " 请求值:" + value); } }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req,resp); }
@Override public void destroy() { super.destroy(); } }
|
response
响应返回信息
1 2 3 4 5 6 7 8 9
| response.getWriter() resp.getWriter().println(); resp.getWriter().write(); resp.setContentType("text/html; charset=UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.sendRedirect("xxx.html"); resp.setStatus(301); resp.setHeader("Location", "fail.html");
|
请求转发和跳转
请求转发,是使用RequestDispatcher资源调度,将请求从当前资源交给下一个资源处理,下一个资源可以是servlet,也可以是JSP。转发的过程中,只有一次请求和一次响应,并且地址不变。
客户端跳转 sendRedirect ,直接跳转,不会转发请求
服务器转发 getRequestDispatcher ,会转发请求
HttpSession session = req.getSession(); 创建seesion对象
HttpServletRequest 接口中的 getSession() 方法用于获取与当前请求关联的会话对象,如果不存在会话,则创建一个新的会话。
LoginServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package com.example.servlet2;
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 java.io.IOException; import java.util.Map;
@WebServlet("/login") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html; charset=UTF-8"); Map<String, String[]> parameterMap = req.getParameterMap(); HttpSession session = req.getSession(); String username = req.getParameter("username"); if(parameterMap.containsKey("username") && parameterMap.containsKey("password")){ if(req.getParameter("username").equals("admin")&&req.getParameter("password").equals("123456")){ session.setAttribute("user",username);
resp.sendRedirect("main"); }else { resp.getWriter().println("账号或密码错误"); } }else { resp.getWriter().println("账号或密码不能为空"); }
}
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req,resp); } }
|
MainServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.example.servlet2;
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 java.io.IOException; import java.io.PrintWriter;
@WebServlet("/main") public class MainServlet extends HttpServlet { public MainServlet(){
}
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); String user = (String) session.getAttribute("user"); if (user != null){ resp.setContentType("text/html; charset=UTF-8"); PrintWriter out = resp.getWriter(); out.println("<h1>hello world</h1><br>"); out.println("欢迎:"+ user); out.println("<p>There is main</p>"); }else { resp.sendRedirect("login.jsp"); } } }
|
filter过滤器
Filter过滤器是Servlet2.3中所提供的一个过滤请求与响应的对象。
Filter过滤器既可以对客户端向服务器端发送的请求进行过滤,也可以对服务器端向客户端产生的响应进行过滤处理

filter 的生命周期
Filter 的生命周期由 Web 容器管理,包含以下三个阶段:
- 初始化阶段:
- 调用
init(FilterConfig filterConfig) 方法
- 在 Web 应用启动时执行一次
- 过滤阶段:
- 每次请求匹配 Filter 的 URL 模式时,调用
doFilter(ServletRequest, ServletResponse, FilterChain) 方法
- 销毁阶段:
- 调用
destroy() 方法
- 在 Web 应用关闭时执行一次
1 2 3 4 5 6 7 8 9 10 11
| [Web 应用启动] ↓ init() 被调用(1次) ↓ [每次请求匹配 Filter URL] ↓ doFilter() 被调用(多次) ↓ [Web 应用关闭] ↓ destroy() 被调用(1次)
|
FilterChain(过滤器链)

demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package filter;
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/admin") public class Filter1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("Filter1 init"); Filter.super.init(filterConfig); }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter1 req"); filterChain.doFilter(servletRequest,servletResponse); System.out.println("Filter1 resp");
}
@Override public void destroy() { System.out.println("Filter1 destory"); Filter.super.destroy(); } }
|
设置字符
1 2 3 4 5 6 7 8 9
| @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding("utf-8"); res.setCharacterEncoding("utf-8"); res.setContentType("text/html;charset=UTF-8"); String name = req.getParameter("name"); res.getWriter().println(name); chain.doFilter(req,res); }
|
filter登录验证
LoginServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package Servlet;
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 java.io.IOException; import java.util.Map;
@WebServlet("/login") public class LoginServlet extends HttpServlet { public LoginServlet(){}
@Override public void init() throws ServletException { super.init(); }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); HttpSession session = req.getSession(); Map<String, String[]> parameterMap = req.getParameterMap(); if (parameterMap.containsKey("username")&¶meterMap.containsKey("password")){ String username = req.getParameter("username"); if (req.getParameter("username").equals("admin")&&req.getParameter("password").equals("123456")){ session.setAttribute("user",username); resp.sendRedirect("main"); }else { resp.getWriter().println("账号或密码错误,请重新输入"); } }else { resp.getWriter().println("账号或密码校验错误,请重新输入"); } }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req,resp); }
@Override public void destroy() { super.destroy(); } }
|
MainServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package Servlet;
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 java.io.IOException; import java.io.PrintWriter;
@WebServlet("/main") public class MainServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); HttpSession session = req.getSession(); String user =(String) session.getAttribute("user");
out.println("欢迎 【"+user+"】 访问");
}
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req,resp); } }
|
MainFilter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package Filter;
import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;
@WebFilter("/*") public class MainFilter extends HttpFilter {
@Override protected void doFilter(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException { String url = req.getRequestURI().toString();
if (!url.endsWith("jsp")){ HttpSession session = req.getSession(); String user = (String) session.getAttribute("user"); System.out.println(user);
if (user == null && !url.endsWith("login")){ resp.sendRedirect("login.jsp"); return; } }
chain.doFilter(req, resp); } }
|
ServletContext
ServletContext全局唯一,它是属于整个Web应用程序的,我们可以通过getServletContext()来获取到此对象。
设置ServletContext
1
| req.getServletContext().setAttribute("username","admin");
|
获取ServletContext
1 2
| System.out.println(req.getServletContext().getAttribute("username"));
|