java-Servlet

Servlet

基本Servlet实现写法

原生Servlet

需要重写5个接口

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
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet implements Servlet {

@Override
public void init(ServletConfig config) throws ServletException {
// 初始化操作,可以在这里进行一些设置
}

@Override
public ServletConfig getServletConfig() {
return null;
}

@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");

PrintWriter out = res.getWriter();
String helloValue = req.getParameter("hello"); //实现hello参数的传入以及处理,但是无法分辨get,post请求

if (helloValue != null) {
if (helloValue.equals("1314")) {
out.println("<html><body>");
out.println("<h1>520</h1>");
out.println("</body></html>");
} else if (helloValue.equals("520")) {
out.println("<html><body>");
out.println("<h1>1314</h1>");
out.println("</body></html>");
} else {
out.println("<html><body>");
out.println("<h1>Other</h1>");
out.println("</body></html>");
}
} else {
out.println("<html><body>");
out.println("<h1>No Parameter</h1>");
out.println("</body></html>");
}
}

@Override
public String getServletInfo() {
return null;
}

@Override
public void destroy() {
// 清理资源等操作
}
}

GenericServlet写法

已经完成了一部分的Servlet,只需要重写service即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class GenericServlet extends javax.servlet.GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
servletResponse.setContentType("text/html");

PrintWriter out = servletResponse.getWriter();
out.println("<html><body>");
out.println("<h1>Hello from GenericServlet</h1>");
out.println("</body></html>");
}
}

传参

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
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class GenericServlet extends javax.servlet.GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 获取请求参数
String paramValue = servletRequest.getParameter("paramName");

servletResponse.setContentType("text/html");
PrintWriter out = servletResponse.getWriter();

out.println("<html><body>");

if (paramValue != null) {
out.println("<h1>Parameter value: " + paramValue + "</h1>");
// 在这里添加对参数的处理逻辑
} else {
out.println("<h1>No parameter value provided.</h1>");
}

out.println("</body></html>");
}
}

但是依旧无法分辨get和post请求,需要强制转化为HttpServlet

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
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; // 注意导入
import java.io.IOException;
import java.io.PrintWriter;

public class GenericServlet extends javax.servlet.GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 将 ServletRequest 强制转换为 HttpServletRequest
HttpServletRequest request = (HttpServletRequest) servletRequest;

// 获取请求方法
String method = request.getMethod();

if ("GET".equals(method)) {
// 处理 GET 请求
servletResponse.setContentType("text/html");

PrintWriter out = servletResponse.getWriter();
out.println("<html><body>");
out.println("<h1>Hello from GET request</h1>");
out.println("</body></html>");
} else if ("POST".equals(method)) {
// 处理 POST 请求
servletResponse.setContentType("text/html");

PrintWriter out = servletResponse.getWriter();
out.println("<html><body>");
out.println("<h1>Hello from POST request</h1>");
out.println("</body></html>");
} else {
// 其他类型的请求
servletResponse.setContentType("text/html");

PrintWriter out = servletResponse.getWriter();
out.println("<html><body>");
out.println("<h1>Unsupported request method</h1>");
out.println("</body></html>");
}
}
}

HttoServlet

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
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HttpServlet extends javax.servlet.http.HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取名为 "paramName" 的请求参数值
String paramName = req.getParameter("paramName");

if (paramName != null) {
// 根据参数值进行不同的处理
if ("hello".equals(paramName)) {
resp.getWriter().write("Hello, World!");
} else if ("bye".equals(paramName)) {
resp.getWriter().write("Goodbye!");
} else {
resp.getWriter().write("Unknown parameter value");
}
} else {
resp.getWriter().write("No parameter provided");
}
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 处理 POST 请求
String paramName = req.getParameter("paramName");

if (paramName != null) {
// 根据参数值进行不同的处理
if ("hello".equals(paramName)) {
resp.getWriter().write("Hello, World! (POST)");
} else if ("bye".equals(paramName)) {
resp.getWriter().write("Goodbye! (POST)");
} else {
resp.getWriter().write("Unknown parameter value (POST)");
}
} else {
resp.getWriter().write("No parameter provided (POST)");
}
}
}

路由设置

web.xml

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
<?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>
<servlet-name>MyServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>GenericServlet</servlet-name>
<servlet-class>GenericServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>GenericServlet</servlet-name>
<url-pattern>/GenericServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>HttpServlet</servlet-name>
<servlet-class>HttpServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>HttpServlet</servlet-name>
<url-pattern>/HttpServlet</url-pattern>
</servlet-mapping>


</web-app>
1
2
3
4
5
6
7
8
9
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
  1. <servlet-name>用于<servlet-class>以及<url-pattern>之间的绑定,<servlet-class>是包中的类名的绝对路径,<url-pattern>是用于请求的url路径,可以使用通配符进行处理
  2. <load-on-startup>1</load-on-startup>标签用于是否进行预先加载,以及预加载的顺序,越小越早
  3. <url-pattern>存在匹配的规则
1
2
3
4
精确匹配  	/具体的名称  	只有路径是具体的名称的时候才会触发Serv1et
后缰匹配 *.xxx 只要是以×××结尾的就匹配触发Serv1et
通配符匹配 /* 匹配所有请求,包含服务器的所有资源
通配符匹配 / 匹配所有请求,包含服务器的所有资源,不包括.jsp

注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/hello")

public class Webser extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("64646");
}
}

这样就不需要在web.xml中进行定义了,适用于Servlet3.0以上

属性名 类型 标签 描述 是否必需
name String <servlet-name> 指定 Servlet 的 name 属性。 如果没有显式指定,则取值为该 Servlet 的完全限定名,即包名+类名。
value String[ ] <url-pattern> 该属性等价于 urlPatterns 属性,两者不能同时指定。 如果同时指定,通常是忽略 value 的取值。
urlPatterns String[ ] <url-pattern> 指定一组 Servlet 的 URL 匹配模式。
loadOnStartup int <load-on-startup> 指定 Servlet 的加载顺序。
initParams WebInitParam[ ] <init-param> 指定一组 Servlet 初始化参数。
asyncSupported boolean <async-supported> 声明 Servlet 是否支持异步操作模式。
description String <description> 指定该 Servlet 的描述信息。
displayName String <display-name> 指定该 Servlet 的显示名。

多路由映射

1
2
3
4
5
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
<url-pattern>/myServlet3</url-pattern>
</servlet-mapping>
1
@WebServlet(urlPatterns = { "/myServlet", "/myServlet4" })

ServletConfig

获取初始对象

通过 ServletConfig 对象即可获得当前 Servlet 的初始化参数信息。

获得方式:

  1. 使用带参的 init() 方法获取

    1
    2
    3
    4
    5
    @Override
    public void init(ServletConfig config) throws ServletException {
    //从带参init方法中,提取ServletConfig对象
    this.servletConfig = config;
    }
  2. GenericServlet 提供的 getServletConfig() 方法获得

    1
    this.getServletConfig()

ServletConfig 接口

javax.servlet 包提供了一个 ServletConfig 接口,该接口中提供了以下方法。

返回值类型 方法 功能描述
String getInitParameter(String name) 根据初始化参数名 name,返回对应的初始化参数值。
Enumeration<String> getInitParameterNames() 返回 Servlet 所有的初始化参数名的枚举集合,如果该 Servlet 没有初始化参数,则返回一个空的集合。
ServletContext getServletContext() 返回一个代表当前 Web 应用的 ServletContext 对象。
String getServletName() 返回 Servlet 的名字,即 web.xml 中 元素的值。
  1. 初始化参数xml

    1
    2
    3
    4
    <init-param>
    <param-name>URL</param-name>
    <param-value>https://gudiffany.github.io/</param-value>
    </init-param>

    需要在servlet标签中使用

  2. 初始化参数WebServlet

1
initParams = {@WebInitParam(name = "name", value = "diffany"),@WebInitParam(name = "URL", value="https://gudiffany.github.io/")}
  1. 获得初始化参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PrintWriter writer = response.getWriter();//输出流
// 获取ServletConfig对象
ServletConfig config = getServletConfig();

// 获取servletName
String servletName = config.getServletName();

// 返回 servlet 的初始化参数的名称的集合
Enumeration<String> initParameterNames = config.getInitParameterNames();

// 遍历集合获取初始化参数名称
while (initParameterNames.hasMoreElements()) {
// 获取初始化参数名称
String initParamName = initParameterNames.nextElement();
// 获取相应的初始参数的值
String initParamValue = config.getInitParameter(initParamName);
// 向页面输出
writer.write(initParamName + " : " + initParamValue + "<br/>");
}

ServletContext

获得

ServletContext是Servlet共用的,通过这个对象实现不同路由之间的通信

获得 ServletContext 对象有以下 4 种方式:

  1. 通过 GenericServlet 提供的 getServletContext() 方法
1
2
//通过 GenericServlet的getServletContext方法获取ServletContext对象
ServletContext servletContext = this.getServletContext();
  1. 通过 ServletConfig 提供的 getServletContext() 方法
1
2
//通过 ServletConfig的 getServletContext方法获取ServletContext对象
ServletContext servletContext = this.getServletConfig().getServletContext();
  1. 通过 HttpSession 提供的 getServletContext() 方法
1
2
//通过 HttpSession的 getServletContext方法获取ServletContext对象
ServletContext servletContext = req.getSession().getServletContext();
  1. 通过 HttpServletRequest 提供的 getServletContext() 方法
1
2
//通过 HttpServletRequest的 getServletContext方法获取ServletContext对象
ServletContext servletContext = req.getServletContext();

应用

  1. 初始化参数
1
2
3
4
<context-param>
<param-name>url</param-name>
<param-value>www.biancheng.net</param-value>
</context-param>
  1. 获得初始化参数
1
2
3
4
5
6
7
8
9
10
11
12
13
PrintWriter writer = response.getWriter();
// 调用httpServlet父类GenericServlet的getServletContext方法获取ServletContext对象
ServletContext context = super.getServletContext();
// 返回 context 上下文初始化参数的名称
Enumeration<String> initParameterNames = context.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
// 获取初始化参数名称
String initParamName = initParameterNames.nextElement();
// 获取相应的初始参数的值
String initParamValue = context.getInitParameter(initParamName);
// 向页面输出
writer.write(initParamName + " : " + initParamValue + "<br/>");
}
  1. 数据通讯
返回值类型 方法 描述
void setAttribute(String name, Object object) 把一个 Java 对象与一个属性名绑定,并将它作为一个属性存放到 ServletContext 中。 参数 name 为属性名,参数 object 为属性值。
void removeAttribute(String name) 从 ServletContext 中移除属性名为 name 的属性。
Object getAttribute(String name) 根据指定的属性名 name,返回 ServletContext 中对应的属性值。

example

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
@WebServlet("/CountServlet")
public class CountServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
// 获取ServletContext对象
ServletContext context = getServletContext();
// 初始化时,向ServletContext中设置count属性,初始值为0
context.setAttribute("count", 0);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 调用httpServlet父类GenericServlet的getServletContext方法获取ServletContext对象
ServletContext context = super.getServletContext();
// 获取count的值,自增
Integer count = (Integer) context.getAttribute("count");
// 存入到域对象中
context.setAttribute("count", ++count);
// 向页面输出内容
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h3>编程帮 www.biancheng.net 欢迎您</h3>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@WebServlet("/ShowServlet")
public class ShowServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取ServletContext中存放的count属性(即页面的访问次数)
Integer count = (Integer) getServletContext().getAttribute("count");
// 向页面输出
response.setContentType("text/html;charset=UTF-8");
// 若CountServlet已被访问
if (count != null) {
response.getWriter().write("<h3>该网站一共被访问了" + count + "次</h3>");
} else {
// 若CountServlet未被访问,提示先访问CountServlet
response.getWriter().write("<h3>请先访问 CountServlet</h3>");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

HttpServletRequest

返回值类型 方法声明 描述
String getMethod() 该方法用于获取 HTTP 请求方式(如 GET、POST 等)。
String getRequestURI() 该方法用于获取请求行中的资源名称部分,即位于 URL 的主机和端口之后,参数部分之前的部分。
String getQueryString() 该方法用于获取请求行中的参数部分,也就是 URL 中“?”以后的所有内容。
String getContextPath() 返回当前 Servlet 所在的应用的名字(上下文)。对于默认(ROOT)上下文中的 Servlet,此方法返回空字符串""。
String getServletPath() 该方法用于获取 Servlet 所映射的路径。
String getRemoteAddr() 该方法用于获取客户端的 IP 地址。
String getRemoteHost() 该方法用于获取客户端的完整主机名,如果无法解析出客户机的完整主机名,则该方法将会返回客户端的 IP 地址。
1
2
3
4
5
6
7
8
writer.println("请求方式:" + request.getMethod() + "<br/>" +
"客户端的 IP 地址:" + request.getRemoteAddr() + "<br/>" +
"应用名字(上下文):" + request.getContextPath() + "<br/>" +
"URI:" + request.getRequestURI() + "<br/>" +
"请求字符串:" + request.getQueryString() + "<br/>" +
"Servlet所映射的路径:" + request.getServletPath() + "<br/>" +
"客户端的完整主机名:" + request.getRemoteHost() + "<br/>"
);
返回值类型 方法声明 描述
String getHeader(String name) 该方法用于获取一个指定头字段的值。 如果请求消息中包含多个指定名称的头字段,则该方法返回其中第一个头字段的值。
Enumeration getHeaders(String name) 该方法返回指定头字段的所有值的枚举集合, 在多数情况下,一个头字段名在请求消息中只出现一次,但有时可能会出现多次。
Enumeration getHeaderNames() 该方法返回请求头中所有头字段的枚举集合。
String getContentType() 该方法用于获取 Content-Type 头字段的值。
int getContentLength() 该方法用于获取 Content-Length 头字段的值 。
String getCharacterEncoding() 该方法用于返回请求消息的字符集编码 。
返回值类型 方法声明 功能描述
String getParameter(String name) 返回指定参数名的参数值。
String [ ] getParameterValues (String name) 以字符串数组的形式返回指定参数名的所有参数值(HTTP 请求中可以有多个相同参数名的参数)。
Enumeration getParameterNames() 以枚举集合的形式返回请求中所有参数名。
Map getParameterMap() 用于将请求中的所有参数名和参数值装入一个 Map 对象中返回。

HttpServletResponse

返回值类型 方法 描述
void setStatus(int status) 用于设置 HTTP 响应消息的状态码,并生成响应状态行。
void sendError(int sc) 用于发送表示错误信息的状态码。
返回值类型 方法 描述
void addHeader(String name,String value) 用于增加响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值。
void setHeader (String name,String value) 用于设置响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值。
void addIntHeader(String name,int value) 用于增加值为 int 类型的响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值,类型为 int。
void setIntHeader(String name, int value) 用于设置值为 int 类型的响应头字段,其中,参数 name 用于指定响应头字段的名称,参数 value 用于指定响应头字段的值,类型为 int。
void setContentType(String type) 用于设置 Servlet 输出内容的 MIME 类型以及编码格式。
void setCharacterEncoding(String charset) 用于设置输出内容使用的字符编码。
返回值类型 方法 描述
ServletOutputStream getOutputStream() 用于获取字节输出流对象。
PrintWriter getWriter() 用于获取字符输出流对象。

请求转发

对于客户端的请求,可能需要多个web服务进行处理,这个时候就需要请求转发

1
2
request.setAttribute("welcome", "welcome");
request.getRequestDispatcher("/Servlet").forward(request, response);

只要对request设置,然后getRequestDispatcher转发到路由上就行了

Session与Cookie

方法 描述 所属接口
void addCookie(Cookie cookie) 用于在响应头中增加一个相应的 Set-Cookie 头字段。 javax.servlet.http.HttpServletResponse
Cookie[] getCookies() 用于获取客户端提交的 Cookie。 javax.servlet.http.HttpServletRequest
返回值类型 方法 描述
int getMaxAge() 用于获取指定 Cookie 的最大有效时间,以秒为单位。 默认情况下取值为 -1,表示该 Cookie 保留到浏览器关闭为止。
String getName() 用于获取 Cookie 的名称。
String getPath() 用于获取 Cookie 的有效路径。
boolean getSecure() 如果浏览器只通过安全协议发送 Cookie,则返回 true;如果浏览器可以使用任何协议发送 Cookie,则返回 false。
String getValue() 用于获取 Cookie 的值。
int getVersion() 用于获取 Cookie 遵守的协议版本。
void setMaxAge(int expiry) 用于设置 Cookie 的最大有效时间,以秒为单位。 取值为正值时,表示 Cookie 在经过指定时间后过期。取值为负值时,表示 Cookie 不会被持久存储,在 Web 浏览器退出时删除。取值为 0 时,表示删除该 Cookie。
void setPath(String uri) 用于指定 Cookie 的路径。
void setSecure(boolean flag) 用于设置浏览器是否只能使用安全协议(如 HTTPS 或 SSL)发送 Cookie。
void setValue(String newValue) 用于设置 Cookie 的值。
返回值类型 方法 描述
long getCreationTime() 返回创建 Session 的时间。
String getId() 返回获取 Seesion 的唯一的 ID。
long getLastAccessedTime() 返回客户端上一次发送与此 Session 关联的请求的时间。
int getMaxInactiveInterval() 返回在无任何操作的情况下,Session 失效的时间,以秒为单位。
ServletContext getServletContext() 返回 Session 所属的 ServletContext 对象。
void invalidate() 使 Session 失效。
void setMaxInactiveInterval(int interval) 指定在无任何操作的情况下,Session 失效的时间,以秒为单位。负数表示 Session 永远不会失效。
返回值类型 方法 描述
void setAttribute(String name, Object o) 把一个 Java 对象与一个属性名绑定,并将它作为一个属性存放到 Session 对象中。 参数 name 为属性名,参数 object 为属性值。
Object getAttribute(String name) 根据指定的属性名 name,返回 Session 对象中对应的属性值。
void removeAttribute(String name) 从 Session 对象中移除属性名为 name 的属性。
Enumeration getAttributeNames() 用于返回 Session 对象中的所有属性名的枚举集合。

Filter

1
2
3
4
5
6
7
8
9
10
11
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/login</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>

<filter-mapping>
<filter-name>myFilter</filter-name>
<servlet-name>ServletDemo</servlet-name>
</filter-mapping>
1
2
3
4
5
6
7
@WebFilter(
dispatcherTypes = {
DispatcherType.REQUEST,
DispatcherType.FORWARD,
},
urlPatterns = {"/login"},
servletNames = {"ServletDemo"})
属性名 类型 描述
filterName String 指定过滤器的 name 属性,等价于 <filter-name>
urlPatterns String[] 指定过滤器的 URL 匹配模式。等价于 <url-pattern> 标签。
value String[] 该属性等价于 urlPatterns 属性,但是两者不能同时使用。
servletNames String[] 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中 filterName 属性的取值,或者 web.xml 中 <servlet-name> 的取值。
dispatcherTypes DispatcherType 指定过滤器拦截的资源被 Servlet 容器调用的方式。具体取值包括: ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。
initParams WebInitParam[] 指定一组过滤器初始化参数,等价于 <init-param> 标签。
asyncSupported boolean 声明过滤器是否支持异步操作模式,等价于 <async-supported> 标签。
description String 指定过滤器的描述信息,等价于 <description> 标签。
displayName String 指定过滤器的显示名,等价于 <display-name> 标签。

Filter 链中 Filter 的执行顺序

通过 web.xml 配置的 Filter 过滤器,执行顺序由 <filter-mapping> 标签的配置顺序决定。<filter-mapping> 靠前,则 Filter 先执行,靠后则后执行。通过修改 <filter-mapping> 的顺序便可以修改 Filter 的执行顺序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--过滤器链中FirstChainFilter配置 -->
<filter>
<filter-name>FirstChainFilter</filter-name>
<filter-class>FirstChainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FirstChainFilter</filter-name>
<url-pattern>/login</url-pattern>
</filter-mapping>
<!--过滤器链中SecondChainFilter配置 -->
<filter>
<filter-name>SecondChainFilter</filter-name>
<filter-class>SecondChainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecondChainFilter</filter-name>
<url-pattern>/login</url-pattern>
</filter-mapping>

黑名单

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
public class BlackListFilter implements Filter {
private FilterConfig fConfig;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=UTF-8");
Boolean successde = true;
//获取前台登录的账号信息
String name = request.getParameter("username");
//获取过滤器中的初始化参数
Enumeration<String> blackListNames = fConfig.getInitParameterNames();
//判断前台登录账号是否为空
if (name == null || "".equals(name)) {
response.getWriter().write("用户名不能为空");
} else {
//登录账号不为空,循环遍历黑名单
while (blackListNames.hasMoreElements()) {
//若登录账号是黑名单账号则不允许登录
if (fConfig.getInitParameter(blackListNames.nextElement()).equals(name)) {
successde = false;
break;
}
}
if (successde) {
chain.doFilter(request, response);
} else {
response.getWriter().write("sucess");
}
}
}
public void init(FilterConfig fConfig) throws ServletException {
this.fConfig = fConfig;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
<filter>
<filter-name>BlackListFilter</filter-name>
<filter-class>BlackListFilter</filter-class>
<init-param>
<param-name>blackList</param-name>
<param-value>user</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>BlackListFilter</filter-name>
<url-pattern>/login</url-pattern>
</filter-mapping>