01-Web技术-Servlet

第01章-WEB技术-Servlet

学习目标

  1. 掌握 servlet 实现原理
  2. 掌握 servlet 生命周期
  3. 掌握 servlet 监听器的使用

Servlet概论

Servlet 是什么?

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

使用 Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

Servlet 架构

下图显示了 Servlet 在 Web 应用程序中的位置。

img

Servlet 任务

Servlet 执行以下主要任务:

  • 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
  • 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
  • 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
  • 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
  • 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。

Servlet 包

Java Servlet 是运行在带有支持 Java Servlet 规范的解释器的 web 服务器上的 Java 类。

Servlet 可以使用 javax.servlet 和 javax.servlet.http 包创建,它是 Java 企业版的标准组成部分,Java 企业版是支持大型开发项目的 Java 类库的扩展版本。

Servlet与Tomcat版本

官方说明:http://tomcat.apache.org/whichversion.html

img

Servlet基础

创建动态web工程:

img img

说明:

dynamic web module指servlet的版本,servlet被包含在tomcat中。

  • dynamic web module 2.4 对应Tomcat 5.5
  • dynamic web module 2.5 对应Tomcat 6.0
  • dynamic web module 3.0 对应Tomcat 7.0
  • dynamic web module 3.1 对应Tomcat 7.0或者更高
  • dynamic web module 4 对应Tomcat 8.0或者更高

一直next直到如下:

img

创建好项目如下:

img

配置apache tomcat

img img img img img

设置tomcat

img img img

按ctr+s保存设置

创建JAVA文件

img img img

导入tomcat资源包

img img img img img

编程

编写代码

img

配置servlet

img

运行

img

img img

Servlet 生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。

  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

init()方法

init 方法被设计成只调用一次。

它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。

因此,它是用于一次性初始化。

Servlet 创建于用户第一次方位该Servlet的URL 时,但是也可以指定 Servlet 在服务器第一次启动时被加载。

每一个用户请求都会创建一个 Servlet 实例,并且产生一个新的线程。

init() 方法简单地创建或加载一些数据,这些数据将作用于 Servlet 的整个生命周期。

service()方法

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

destroy()方法

destroy() 方法只会在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

Servlet执行过程

  1. 同一个servlet是单例多线程的,只存在一个servlet对象,由多个线程异步执行该对象的方法。因此servlet的类属性是“线程不安全的”,对象属性是线程安全的,因为每个线程都会拷贝一份对象属性。
  2. Servelet容器维护了一个线程(等待执行代码的一组线程【Worker Thread】)池来处理各种请求。
  3. Servlet容器使用一个调度线程【Dispatcher Thread】来管理【Worker Thread】。
  4. 当tomcat启动时,按照在web.xml文件元素中配置的序号的顺序,容器会自动创建每个不同的Servlet对象,并执行。
  5. 当接受到第一个请求时,容器创建非Servlet的servlet对象,并执行。
  6. 执行过程按照Servlet生命周期执行
img

Servlet体系结构

img

ServletRequest接口

ServletRequest -> HttpServletRequest

相关方法

方 法 说 明
getAttributeNames() 返回当前请求的所有属性的名字集合
getAttribute(String name) 返回name指定的属性值
getCookies() 返回客户端发送的Cookie
getsession() 返回和客户端相关的session,如果没有给客户端分配session,则返回null
getsession(boolean create) 返回和客户端相关的session,如果没有给客户端分配session,则创建一个session并返回
getParameter(String name) 获取请求中的参数,该参数是由name指定的
getParameterValues(String name) 返回请求中的参数值,该参数值是由name指定的
getCharacterEncoding() 返回请求的字符编码方式
getContentLength() 返回请求体的有效长度
getInputStream() 获取请求的输入流中的数据
getMethod() 获取发送请求的方式,如get、post
getParameterNames() 获取请求中所有参数的名字
getProtocol() 获取请求所使用的协议名称
getReader() 获取请求体的数据流
getRemoteAddr() 获取客户端的IP地址
getRemoteHost() 获取客户端的名字
getServerName() 返回接受请求的服务器的名字
getServerPath() 获取请求的文件的路径

获得客户端信息

  • getRequestURL方法返回客户端发出请求时的完整URL
  • getRequestURI方法返回请求行中的资源名部分。
  • getQueryString 方法返回请求行中的参数部分。
  • getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以/开头。
  • getRemoteAddr方法返回发出请求的客户机的IP地址。
  • getRemoteHost方法返回发出请求的客户机的完整主机名。
  • getRemotePort方法返回客户机所使用的网络端口号。
  • getLocalAddr方法返回WEB服务器的IP地址。
  • getLocalName方法返回WEB服务器的主机名。
案例:获取客户端参数
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
package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServletTestRequest extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doGet</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	<span class="hljs-javadoc">/**
	 * 1.获得客户机信息
	 */</span>
	String requestUrl = req.getRequestURL().toString();<span class="hljs-comment">// 得到请求的URL地址</span>
	String requestUri = req.getRequestURI();<span class="hljs-comment">// 得到请求的资源</span>
	String queryString = req.getQueryString();<span class="hljs-comment">// 得到请求的URL地址中附带的参数</span>
	String remoteAddr = req.getRemoteAddr();<span class="hljs-comment">// 得到来访者的IP地址</span>
	String remoteHost = req.getRemoteHost();
	<span class="hljs-keyword">int</span> remotePort = req.getRemotePort();
	String remoteUser = req.getRemoteUser();
	String method = req.getMethod();<span class="hljs-comment">// 得到请求URL地址时使用的方法</span>
	String pathInfo = req.getPathInfo();
	String localAddr = req.getLocalAddr();<span class="hljs-comment">// 获取WEB服务器的IP地址</span>
	String localName = req.getLocalName();<span class="hljs-comment">// 获取WEB服务器的主机名</span>
	resp.setCharacterEncoding(<span class="hljs-string">"UTF-8"</span>);<span class="hljs-comment">// 设置将字符以"UTF-8"编码输出到客户端浏览器</span>
	<span class="hljs-comment">// 通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码</span>
	resp.setHeader(<span class="hljs-string">"content-type"</span>, <span class="hljs-string">"text/html;charset=UTF-8"</span>);
	PrintWriter out = resp.getWriter();
	out.write(<span class="hljs-string">"获取到的客户机信息如下:"</span>);
	out.write(<span class="hljs-string">"<hr/>"</span>);
	out.write(<span class="hljs-string">"请求的URL地址:"</span> + requestUrl);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"请求的资源:"</span> + requestUri);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"请求的URL地址中附带的参数:"</span> + queryString);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"来访者的IP地址:"</span> + remoteAddr);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"来访者的主机名:"</span> + remoteHost);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"使用的端口号:"</span> + remotePort);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"remoteUser:"</span> + remoteUser);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"请求使用的方法:"</span> + method);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"pathInfo:"</span> + pathInfo);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"localAddr:"</span> + localAddr);
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"localName:"</span> + localName);
}

}

获得客户端请求头

  • getHeader(string name)方法:String
  • getHeaders(String name)方法:Enumeration
  • getHeaderNames()方法
案例:获取请求头
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
package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServletTestRequest2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doGet</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	resp.setCharacterEncoding(<span class="hljs-string">"UTF-8"</span>);<span class="hljs-comment">// 设置将字符以"UTF-8"编码输出到客户端浏览器</span>
	<span class="hljs-comment">// 通过设置响应头控制浏览器以UTF-8的编码显示数据</span>
	resp.setHeader(<span class="hljs-string">"content-type"</span>, <span class="hljs-string">"text/html;charset=UTF-8"</span>);
	PrintWriter out = resp.getWriter();
	Enumeration<String> reqHeadInfos = req.getHeaderNames();<span class="hljs-comment">// 获取所有的请求头</span>
	out.write(<span class="hljs-string">"获取到的客户端所有的请求头信息如下:"</span>);
	out.write(<span class="hljs-string">"<hr/>"</span>);
	<span class="hljs-keyword">while</span> (reqHeadInfos.hasMoreElements()) {
		String headName = (String) reqHeadInfos.nextElement();
		String headValue = req.getHeader(headName);<span class="hljs-comment">// 根据请求头的名字获取对应的请求头的值</span>
		out.write(headName + <span class="hljs-string">":"</span> + headValue);
		out.write(<span class="hljs-string">"<br/>"</span>);
	}
	out.write(<span class="hljs-string">"<br/>"</span>);
	out.write(<span class="hljs-string">"获取到的客户端Accept-Encoding请求头的值:"</span>);
	out.write(<span class="hljs-string">"<hr/>"</span>);
	String value = req.getHeader(<span class="hljs-string">"Accept-Encoding"</span>);<span class="hljs-comment">// 获取Accept-Encoding请求头对应的值</span>
	out.write(value);

	Enumeration<String> e = req.getHeaders(<span class="hljs-string">"Accept-Encoding"</span>);
	<span class="hljs-keyword">while</span> (e.hasMoreElements()) {
		String string = (String) e.nextElement();
		System.out.println(string);
	}
}

}

获得客户端请求参数

获取(客户端提交的数据)

  • getParameter(String)方法(常用)-获取单个字段
  • getParameterValues(String name)方法(常用)-获取多选字段
  • getParameterMap()方法(编写框架时常用)- 将所有字段全部封装成map
  • getParameterNames()方法(不常用)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

<html>
<span class="hljs-tag"><<span class="hljs-title">head</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">title</span>></span>Html的Form表单元素<span class="hljs-tag"></<span class="hljs-title">title</span>></span>
<span class="hljs-tag"></<span class="hljs-title">head</span>></span>

<span class="hljs-tag"><<span class="hljs-title">body</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">form</span> <span class="hljs-attribute">action</span>=<span class="hljs-value">"localhost:8080/servlet/star"</span> <span class="hljs-attribute">method</span>=<span class="hljs-value">"post"</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">label</span>></span>编号(文本框):<span class="hljs-tag"></<span class="hljs-title">label</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"userid"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"NO."</span> <span class="hljs-attribute">size</span>=<span class="hljs-value">"2"</span> <span class="hljs-attribute">maxlength</span>=<span class="hljs-value">"2"</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">br</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">label</span>></span>用户名(文本框):<span class="hljs-tag"></<span class="hljs-title">label</span>></span><span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"username"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"请输入用户名"</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">br</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">label</span>></span>密码(密码框):<span class="hljs-tag"></<span class="hljs-title">label</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"password"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"userpass"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"请输入密码"</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">br</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">label</span>></span>性别(单选框):<span class="hljs-tag"></<span class="hljs-title">label</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"radio"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"sex"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"男"</span> <span class="hljs-attribute">checked</span>></span>男
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"radio"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"sex"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"女"</span>></span>女<span class="hljs-tag"><<span class="hljs-title">br</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">label</span>></span>部门(下拉框):<span class="hljs-tag"></<span class="hljs-title">label</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"dept"</span>></span>
			<span class="hljs-tag"><<span class="hljs-title">option</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"技术部"</span>></span>技术部<span class="hljs-tag"></<span class="hljs-title">option</span>></span>
			<span class="hljs-tag"><<span class="hljs-title">option</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"销售部"</span> <span class="hljs-attribute">SELECTED</span>></span>销售部<span class="hljs-tag"></<span class="hljs-title">option</span>></span>
			<span class="hljs-tag"><<span class="hljs-title">option</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"财务部"</span>></span>财务部<span class="hljs-tag"></<span class="hljs-title">option</span>></span>
		<span class="hljs-tag"></<span class="hljs-title">select</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">br</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">label</span>></span>兴趣(复选框):<span class="hljs-tag"></<span class="hljs-title">label</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"checkbox"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"inst"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"唱歌"</span>></span>唱歌
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"checkbox"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"inst"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"游泳"</span>></span>游泳
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"checkbox"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"inst"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"跳舞"</span>></span>跳舞
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"checkbox"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"inst"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"编程"</span> <span class="hljs-attribute">checked</span>></span>编程
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"checkbox"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"inst"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"上网"</span>></span>上网
		<span class="hljs-tag"><<span class="hljs-title">br</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">label</span>></span>说明(文本域):<span class="hljs-tag"></<span class="hljs-title">label</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">textarea</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"note"</span> <span class="hljs-attribute">cols</span>=<span class="hljs-value">"34"</span> <span class="hljs-attribute">rows</span>=<span class="hljs-value">"5"</span>></span><span class="hljs-tag"></<span class="hljs-title">textarea</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">br</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"hidden"</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"hiddenField"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"hiddenvalue"</span> /></span>
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"submit"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"提交(提交按钮)"</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"reset"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"重置(重置按钮)"</span>></span>
	<span class="hljs-tag"></<span class="hljs-title">form</span>></span>
<span class="hljs-tag"></<span class="hljs-title">body</span>></span>

</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
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
69
70
71
72
73
package com.servlet;

import java.io.IOException;
import java.text.MessageFormat;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServletTestRequest3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doGet</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	<span class="hljs-comment">// 客户端是以UTF-8编码提交表单数据的,所以需要设置服务器端以UTF-8的编码进行接收,否则对于中文数据就会产生乱码</span>
	req.setCharacterEncoding(<span class="hljs-string">"UTF-8"</span>);
	<span class="hljs-javadoc">/**
	 * 编&nbsp;&nbsp;号(文本框):
	 * <input type="text" name="userid" value="NO." size="2" maxlength="2">
	 */</span>
	String userid = req.getParameter(<span class="hljs-string">"userid"</span>);<span class="hljs-comment">// 获取填写的编号,userid是文本框的名字,<input</span>
												<span class="hljs-comment">// type="text"</span>
												<span class="hljs-comment">// name="userid"></span>
	<span class="hljs-javadoc">/**
	 * 用户名(文本框):<input type="text" name="username" value="请输入用户名">
	 */</span>
	String username = req.getParameter(<span class="hljs-string">"username"</span>);<span class="hljs-comment">// 获取填写的用户名</span>
	<span class="hljs-javadoc">/**
	 * 密&nbsp;&nbsp;码(密码框):<input type="password" name="userpass" value=
	 * "请输入密码">
	 */</span>
	String userpass = req.getParameter(<span class="hljs-string">"userpass"</span>);<span class="hljs-comment">// 获取填写的密码</span>
	String sex = req.getParameter(<span class="hljs-string">"sex"</span>);<span class="hljs-comment">// 获取选中的性别</span>
	String dept = req.getParameter(<span class="hljs-string">"dept"</span>);<span class="hljs-comment">// 获取选中的部门</span>
	<span class="hljs-comment">// 获取选中的兴趣,因为可以选中多个值,所以获取到的值是一个字符串数组,因此需要使用getParameterValues方法来获取</span>
	String[] insts = req.getParameterValues(<span class="hljs-string">"inst"</span>);
	String note = req.getParameter(<span class="hljs-string">"note"</span>);<span class="hljs-comment">// 获取填写的说明信息</span>
	String hiddenField = req.getParameter(<span class="hljs-string">"hiddenField"</span>);<span class="hljs-comment">// 获取隐藏域的内容</span>

	String instStr = <span class="hljs-string">""</span>;
	<span class="hljs-javadoc">/**
	 * 获取数组数据的技巧,可以避免insts数组为null时引发的空指针异常错误!
	 */</span>
	<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; insts != <span class="hljs-keyword">null</span> && i < insts.length; i++) {
		<span class="hljs-keyword">if</span> (i == insts.length - <span class="hljs-number">1</span>) {
			instStr += insts[i];
		} <span class="hljs-keyword">else</span> {
			instStr += insts[i] + <span class="hljs-string">","</span>;
		}
	}

	String htmlStr = <span class="hljs-string">"<table>"</span> 
        	+ <span class="hljs-string">"<tr><td>填写的编号:</td><td>{0}</td></tr>"</span>
        	+ <span class="hljs-string">"<tr><td>填写的用户名:</td><td>{1}</td></tr>"</span>
			+ <span class="hljs-string">"<tr><td>填写的密码:</td><td>{2}</td></tr>"</span>
        	+ <span class="hljs-string">"<tr><td>选中的性别:</td><td>{3}</td></tr>"</span>
			+ <span class="hljs-string">"<tr><td>选中的部门:</td><td>{4}</td></tr>"</span>
        	+ <span class="hljs-string">"<tr><td>选中的兴趣:</td><td>{5}</td></tr>"</span>
			+ <span class="hljs-string">"<tr><td>填写的说明:</td><td>{6}</td></tr>"</span>
        	+ <span class="hljs-string">"<tr><td>隐藏域的内容:</td><td>{7}</td></tr>"</span>
        	+ <span class="hljs-string">"</table>"</span>;
	htmlStr = MessageFormat.format(htmlStr, userid, username, userpass, sex, dept, instStr, note, hiddenField);

	resp.setCharacterEncoding(<span class="hljs-string">"UTF-8"</span>);<span class="hljs-comment">// 设置服务器端以UTF-8编码输出数据到客户端</span>
	resp.setContentType(<span class="hljs-string">"text/html;charset=UTF-8"</span>);<span class="hljs-comment">// 设置客户端浏览器以UTF-8编码解析数据</span>
	resp.getWriter().write(htmlStr);<span class="hljs-comment">// 输出htmlStr里面的内容到客户端浏览器显示</span>
}

}

Request请求转发

请求转发:指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。

请求转发的应用场景:MVC设计模式

案例:转发
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
package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

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 MyServletTestRequest4 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doGet</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	RequestDispatcher reqDispatcher =<span class="hljs-keyword">this</span>.getServletContext().getRequestDispatcher(<span class="hljs-string">"/test.jsp"</span>);
	reqDispatcher.forward(req, resp);

}

}

文件上传

使用 multipart/form-data 表单处理文件上传 。文件的上传是以流的形式提交给服务器的

案例:文件上传

页面

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

<html>
<head>
	<meta charset="UTF-8">
	<title>图片上传title>
head>
<body>
	<form id="imageForm" enctype="multipart/form-data" method="post">
		<input id="fileUploader" name="fileUploader" type="file" multiple/>
	form>
body>
<script>
	window.onload = function(){
        document.getElementById('fileUploader').onchange = function(){ 
            var file = document.getElementById('fileUploader').files[0];
        <span class="hljs-keyword">var</span>	formData = <span class="hljs-keyword">new</span> FormData(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'imageForm'</span>));
        <span class="hljs-comment">//formData.append("imageFile",file);</span>

        <span class="hljs-keyword">var</span> httpRequest = <span class="hljs-keyword">new</span> XMLHttpRequest();
        httpRequest.onreadystatechange = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{
            <span class="hljs-keyword">if</span>(httpRequest.readyState == <span class="hljs-number">4</span> && httpRequest.status == <span class="hljs-number">200</span>){
                alert(<span class="hljs-string">"结果: "</span>+httpRequest.responseText);
            }
        };
        httpRequest.open(<span class="hljs-string">"post"</span>,<span class="hljs-string">"http://localhost:8080/aos-maintain/imageProcess"</span>,<span class="hljs-literal">true</span>);
        <span class="hljs-comment">//httpRequest.setRequestHeader("Content-type","multipart/form-data");</span>
        httpRequest.send(formData);
    }
};

</script>

servlet

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.test.servlet;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@MultipartConfig
@WebServlet("/imageProcess")
public class ImageProcessPrimitiveServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doPost</span><span class="hljs-params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	System.out.println(<span class="hljs-string">"request.getContentType(): "</span> + request.getContentType());
	<span class="hljs-keyword">if</span>(!request.getContentType().split(<span class="hljs-string">";"</span>)[<span class="hljs-number">0</span>].equals(<span class="hljs-string">"multipart/form-data"</span>))
		<span class="hljs-keyword">return</span>;
	Collection<Part> parts = request.getParts();
	System.out.println(parts);
	<span class="hljs-keyword">for</span>(Part part:parts){
		System.out.println(part);
		FileProcess(part);
	}
	
	response.getWriter().print(<span class="hljs-string">"end"</span>);
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">FileProcess</span><span class="hljs-params">(Part part)</span> <span class="hljs-keyword">throws</span> IOException </span>{
	System.out.println(<span class="hljs-string">"part.getName(): "</span> + part.getName());
	<span class="hljs-keyword">if</span>(part.getName().equals(<span class="hljs-string">"fileUploader"</span>)){
		String cd = part.getHeader(<span class="hljs-string">"Content-Disposition"</span>);
		String[] cds = cd.split(<span class="hljs-string">";"</span>);
		String filename = cds[<span class="hljs-number">2</span>]
            .substring(cds[<span class="hljs-number">2</span>].indexOf(<span class="hljs-string">"="</span>)+<span class="hljs-number">1</span>)
            .substring(cds[<span class="hljs-number">2</span>].lastIndexOf(<span class="hljs-string">"//"</span>)+<span class="hljs-number">1</span>)
            .replace(<span class="hljs-string">"\""</span>, <span class="hljs-string">""</span>);
		String ext = filename.substring(filename.lastIndexOf(<span class="hljs-string">"."</span>)+<span class="hljs-number">1</span>);
		
		System.out.println(<span class="hljs-string">"filename:"</span> + filename);
		System.out.println(<span class="hljs-string">"ext:"</span> + ext);
		
		InputStream is = part.getInputStream();
		<span class="hljs-keyword">if</span>(Arrays.binarySearch(ImageIO.getReaderFormatNames(),ext) >= <span class="hljs-number">0</span>)
			imageProcess(filename, ext, is);
		<span class="hljs-keyword">else</span>{
			commonFileProcess(filename, is);
		}
	}
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">commonFileProcess</span><span class="hljs-params">(String filename, InputStream is)</span> </span>{
	FileOutputStream fos = <span class="hljs-keyword">null</span>;
	<span class="hljs-keyword">try</span>{
		fos=<span class="hljs-keyword">new</span> FileOutputStream(<span class="hljs-keyword">new</span> File(getClass().getResource(<span class="hljs-string">"/"</span>).getPath()+filename));
		<span class="hljs-keyword">int</span> b = <span class="hljs-number">0</span>;
		<span class="hljs-keyword">while</span>((b = is.read())!=-<span class="hljs-number">1</span>){
			fos.write(b);
		}
	}<span class="hljs-keyword">catch</span>(Exception e){
		e.printStackTrace();
	}<span class="hljs-keyword">finally</span>{
		<span class="hljs-keyword">try</span>{
			fos.close();
		}<span class="hljs-keyword">catch</span>(Exception e){
			e.printStackTrace();
		}
	}
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">imageProcess</span><span class="hljs-params">(String filename, String ext, InputStream is)</span> <span class="hljs-keyword">throws</span> IOException </span>{
	Iterator<ImageReader> irs = ImageIO.getImageReadersByFormatName(ext);
	ImageReader ir = irs.hasNext()?irs.next():<span class="hljs-keyword">null</span>;
	<span class="hljs-keyword">if</span>(ir == <span class="hljs-keyword">null</span>) 
		<span class="hljs-keyword">return</span>;
	ir.setInput(ImageIO.createImageInputStream(is));<span class="hljs-comment">//必须转换为ImageInputStream,否则异常</span>
	
	ImageReadParam rp = ir.getDefaultReadParam();
	Rectangle rect = <span class="hljs-keyword">new</span> Rectangle(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">200</span>,<span class="hljs-number">200</span>);
	rp.setSourceRegion(rect);
	
	<span class="hljs-keyword">int</span> imageNum = ir.getNumImages(<span class="hljs-keyword">true</span>);<span class="hljs-comment">//allowSearch必须为true,否则有些图片格式imageNum为-1。</span>
	
	System.out.println(<span class="hljs-string">"imageNum:"</span> + imageNum);
	
	<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> imageIndex = <span class="hljs-number">0</span>;imageIndex < imageNum;imageIndex++){
		BufferedImage bi = ir.read(imageIndex,rp);
		ImageIO.write(bi, ext, <span class="hljs-keyword">new</span> File(getClass().getResource(<span class="hljs-string">"/"</span>).getPath()+filename));
	}
}

}

ServletResponse接口

ServletResponse -> HttpServletResponse

相关方法

方 法 说 明
addCookie(Cookie cookie) 将指定的Cookie加入到当前的响应中
addHeader(String name,String value) 将指定的名字和值加入到响应的头信息中
containsHeader(String name) 返回一个布尔值,判断响应的头部是否被设置
encodeURL(String url) 编码指定的URL
sendError(int sc) 使用指定状态码发送一个错误到客户端
sendRedirect(String location) 发送一个临时的响应到客户端
setDateHeader(String name,long date) 将给出的名字和日期设置响应的头部
setHeader(String name,String value) 将给出的名字和值设置响应的头部
setStatus(int sc) 给当前响应设置状态码
setContentType(String ContentType) 设置响应的MIME类型

常用的方法和操作说明:

常用的方法

  • addCookie(Cookie cookie) 向客户端写入Cookie
  • addHeader(String name, String value) 写入给定的响应头
  • encodeURL(String url) 默认cookie中包含Session ID,如果客户端不支持 Cookie,就在参数 url 中加入 Session ID 信息,可以解决用户禁用cookie的问题。
  • setStatus(200) 设置响应的状态码。
  • sendError(404, "您要查找的资源不存在"):当发送错误状态码时,Tomcat会跳转到固定的错误页面去,但可以显示错误信息。
  • setCharaceterEncoding(String arg);设置字符集编码
  • setContentType("text/html;charset=utf-8"):等同与调用response.setHeader("content-type", "text/html;charset=utf-8")

getOutputStream和getWriter方法的区别

  • getOutputStreamgetWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStreamPrintwriter对象。
  • getOutputStreamgetWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。

这两个方法写入的数据会作为响应消息的正文,与响应状态行和各响应头组合后输出到客户端。

Serlvetservice方法结束后,web容器将检查getWritergetOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,web容器将调用close方法关闭该输出流对象。

Response重定向

  • 重定向指的是一个web资源收到客户端请求后,web服务器通知客户端去访问另外一个web资源,这称之为请求重定向。
  • 实现方式是调用response.sendRedirect()方法。实现的原理就是给客户端返回了302状态码和location头。

Response 跨域

跨域是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

所谓的同源是指,域名、协议、端口均为相同。如果其中一项不同则为跨域

同源策略限制了一下行为:

  • 无法读取非同源的CookieLocalStorageIndexDB
  • 无法获取非同源的 DOMJS 对象
  • 无法发送 Ajax 请求

解决跨域的方法:设置允许跨域访问

1
2
3
4
5
response.setHeader("Access-Control-Allow-Origin", "*");  // 允许的域名,逗号分割
response.setHeader("Access-Control-Allow-Methods", "*");    // 允许的请求方法,逗号分割
response.setHeader("Access-Control-Max-Age", "3600");    // 允许跨域的超时时间,单位秒
response.setHeader("Access-Control-Allow-Headers", "*");  // 允许的请求头参数,逗号分割
response.setHeader("Access-Control-Allow-Credentials", "true");  // 是否将响应头信息暴露给页面,如:cookies

案例:文件下载

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
package com.servlet;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**

  • 文件下载
    */
    public class MyServletTestResponse extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    downloadFileByOutputStream(response);// 下载文件,通过OutputStream流
    }

    /**

    • 下载文件,通过OutputStream流

    * @param response
    * @throws FileNotFoundException
    * @throws IOException
    */
    private void downloadFileByOutputStream(HttpServletResponse response) throws FileNotFoundException, IOException {
    // 1.获取要下载的文件的绝对路径
    String realPath = this.getServletContext().getRealPath("/download/demo.jpg");
    // 2.获取要下载的文件名
    String fileName = realPath.substring(realPath.lastIndexOf("\") + 1);
    // 3.设置content-disposition响应头控制浏览器以下载的形式打开文件
    response.setHeader("content-disposition", "attachment;filename=" + fileName);
    // 4.获取要下载的文件输入流
    InputStream in = new FileInputStream(realPath);
    int len = 0;
    // 5.创建数据缓冲区
    byte[] buffer = new byte[1024];
    // 6.通过response对象获取OutputStream流
    OutputStream out = response.getOutputStream();
    // 7.将FileInputStream流写入到buffer缓冲区
    while ((len = in.read(buffer)) > 0) {
    // 8.使用OutputStream将缓冲区的数据输出到客户端浏览器
    out.write(buffer, 0, len);
    }
    in.close();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
    }
    }

SerlvetConfig对象

SerlvetConfig对象:代表的是当前Servlet初始化配置项的信息。

利用ServletConfig对象主要是为了得到Context对象。(Context对象可以帮助我们与用户进行交互)

  • 获得指定初始化参数的值:
  • String getInitParameter(String name); 【需要在web.xml文件中进行配置】
  • 获得所有初始化参数的名称:
  • Enumeration getInitParameterNames();【需要在web.xml文件中进行配置】
  • 获得ServletContext对象:
  • ServletContext getServletContext();
  • 获得当前Servlet的名称:
  • String getServletName();

Servlet 的配置文件中,可以用一个或多个标签为servlet配置一些初始化参数。

servlet配置了初始化参数之后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servletinit方法时,将ServletConfig对象传递给Servlet。进而,程序员通过Servlet对象得到当前servlet的初始化参数信息。

获取ServletConfig中初始化信息步骤:

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

<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_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>Servletdisplay-name>
  <welcome-file-list>
    <welcome-file>index.htmlwelcome-file>
    <welcome-file>index.htmwelcome-file>
    <welcome-file>index.jspwelcome-file>
    <welcome-file>default.htmlwelcome-file>
    <welcome-file>default.htmwelcome-file>
    <welcome-file>default.jspwelcome-file>
  welcome-file-list>

<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.servlet.MyServlet</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/star</url-pattern>
</servlet-mapping>
</web-app>

案例

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
package com.servlet;

import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class MyServletTestConfig extends HttpServlet {
private ServletConfig config = null;

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">(ServletConfig config)</span> <span class="hljs-keyword">throws</span> ServletException </span>{
	<span class="hljs-keyword">this</span>.config = config;
	<span class="hljs-comment">// 获取初始化参数</span>
	String value1 = <span class="hljs-keyword">this</span>.config.getInitParameter(<span class="hljs-string">"charset"</span>);
	<span class="hljs-comment">// 获得配置文档中<inti-param>标签下name对应的value</span>
	String value2 = <span class="hljs-keyword">this</span>.config.getInitParameter(<span class="hljs-string">"name"</span>);
	<span class="hljs-comment">// 获取所有初始化参数</span>
	Enumeration e = <span class="hljs-keyword">this</span>.config.getInitParameterNames();
	<span class="hljs-keyword">while</span> (e.hasMoreElements()) {
		String name = (String) e.nextElement();
		String value = <span class="hljs-keyword">this</span>.config.getInitParameter(name);
		System.out.println(name + <span class="hljs-string">"="</span> + value);
	}
}

}

ServletContext对象

Web容器在启动时会为每个web应用创建一个ServletContext对象,而这个ServletContext对象就代表当前这个web应用。

因为一个ServletContext对象代表一个web应用,所以该web应用中所有的Servlet和其他资源都共享一个ServletContext对象,

可以通过ServletContext对象进行Servlet对象之间的通讯。而ServletContext对象也称之为Context域对象。

获取ServletContext对象的两种方式

1
2
3
4
5
6
7
8
//两种获取ServletContext对象的方法:
ServletContext context = this.getServletConfig().getServletContext();
ServletContext context2 = this.getServletContext();

//System.out.println(context1 == context2); //ture

context.setAttribute("lover", "LRR");
context.getAttribute("lover");

获取和设置参数

ServletContext类中还有getInitParameter(String name)方法或者getInitParameterNames()方法。

这两个方法获取的是web应用所配置的参数(毕竟ServletContext代表web应用),就像ServletConfig中类似的方法获取的是某个Servlet中的标签配置的参数。

而对于配置web应用的参数是在web.xml文件中使用标签,正如在该文件中为Servlet配置参数而使用标签一样。

这种配置标签的好处在于属于全局性的配置,而每个Servlet的配置参数仅局限于在Servlet的范围内。

举个例子,对于整个web应用配置数据库连接,这样在web应用中的每个Servlet都可以使用,而无需再在每个Servlet中都单独设置一次,提高了效率。

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
38
39

<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_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>Servletdisplay-name>
  <welcome-file-list>
    <welcome-file>index.htmlwelcome-file>
    <welcome-file>index.htmwelcome-file>
    <welcome-file>index.jspwelcome-file>
    <welcome-file>default.htmlwelcome-file>
    <welcome-file>default.htmwelcome-file>
    <welcome-file>default.jspwelcome-file>
  welcome-file-list>

<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>

<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.servlet.MyServlet</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/star</url-pattern>
</servlet-mapping>
</web-app>

案例

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
package com.servlet;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServletTestContext extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doGet</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	<span class="hljs-comment">// 两种获取ServletContext对象的方法:</span>
	ServletContext context = <span class="hljs-keyword">this</span>.getServletConfig().getServletContext();
	ServletContext context2 = <span class="hljs-keyword">this</span>.getServletContext();

	<span class="hljs-comment">// System.out.println(context1 == context2); //ture</span>

	String username = context.getInitParameter(<span class="hljs-string">"username"</span>);
	String password = context.getInitParameter(<span class="hljs-string">"password"</span>);

	System.out.println(username + <span class="hljs-string">":"</span> + password);
}

}

获取MIME类型数据

ServletContext类中的getMimeType(String file)方法用于返回该文件的MIME类型。用于确定返回类型resp.setContentType(type)

案例

1
2
3
4
5
6
7
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String filename = "1.html";
        ServletContext context = this.getServletContext();
        System.out.println(context.getMimeType(filename));
        resp.setContentType(context.getMimeType(filename));
}

ServletContext转发

ServletContext对象中还有这么两个方法:getNameDispatcher(String name)(不常用)和getRequestDispatcher(String path),返回的是RequestDispatcher对象。

可以实现将一个Servlet中的数据交个另一个Servlet来处理,或者Servlet将某个实时数据交给JSP来显示,虽然我们在浏览器中访问的是最开始的Servlet,但是进行转发后看到的其他web资源,而浏览器的地址栏不会改变。

注:在请求对象request对象中也有这么一个getRequestDispatcher(String path)方法,功能与ServletContext对象的这个方法一样,也可以实现转发,因此用哪个对象都行,没有区别。

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<servlet>
    <servlet-name>mainservlet-name>
    <servlet-class>com.star.servlet.MainServletservlet-class>
servlet>

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


<servlet>
<servlet-name>demo01</servlet-name>
<servlet-class>com.star.servlet.MyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>demo01</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>

文件1

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
//统一对外访问的入口
//welcome?path=copy
public class MainServlet extends HttpServlet {
<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doGet</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	<span class="hljs-comment">// 将数据存至web应用的配置中</span>
	<span class="hljs-keyword">this</span>.getServletContext().setAttribute(<span class="hljs-string">"data"</span>, <span class="hljs-string">"自定义转发的数据"</span>);
	<span class="hljs-comment">// 当访问welcome,调到copy来执行</span>
	String path = req.getParameter(<span class="hljs-string">"path"</span>);
	<span class="hljs-keyword">if</span> (path == <span class="hljs-keyword">null</span>) {
		<span class="hljs-keyword">return</span>;
	}
	<span class="hljs-keyword">switch</span> (path) {
	<span class="hljs-keyword">case</span> <span class="hljs-string">"copy"</span>:
		<span class="hljs-comment">// 跳转到MyServlet2去执行</span>
		RequestDispatcher rd = <span class="hljs-keyword">this</span>.getServletContext().getRequestDispatcher(<span class="hljs-string">"/copy"</span>);
		rd.forward(req, resp);
		<span class="hljs-keyword">break</span>;
	<span class="hljs-keyword">default</span>:
		resp.setContentType(<span class="hljs-string">"text/html"</span>);
		resp.setCharacterEncoding(<span class="hljs-string">"UTF-8"</span>);
		resp.getWriter().write(<span class="hljs-string">"参数不合法"</span>);
		<span class="hljs-keyword">break</span>;
	}
}

}

复制一份新的Servlet

1
2
3
4
5
6
7
8
9
10
public class MyServlet extends HttpServlet{
<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doGet</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	resp.setContentType(<span class="hljs-string">"text/html"</span>);
	resp.setCharacterEncoding(<span class="hljs-string">"UTF-8"</span>);
	resp.getWriter().write(<span class="hljs-string">"欢迎访问/copy"</span>);
}

}

ServletContextListener 接口

在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。

当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理ServletContextEvent 事件的两个方法。

1
2
3
4
5
6
7
8
9
/**
 * 当Servlet 容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,
 * 并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化。
 */
contextInitialized(ServletContextEvent sce) 
/**
 * 当Servlet 容器终止Web 应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet 和Filter 过滤器。
*/
contextDestroyed(ServletContextEvent sce)

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
38
39
40
41
42
43

<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_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>Servletdisplay-name>
  <welcome-file-list>
    <welcome-file>index.htmlwelcome-file>
    <welcome-file>index.htmwelcome-file>
    <welcome-file>index.jspwelcome-file>
    <welcome-file>default.htmlwelcome-file>
    <welcome-file>default.htmwelcome-file>
    <welcome-file>default.jspwelcome-file>
  welcome-file-list>

<listener>
<listener-class>com.servlet.ServletContextLTest</listener-class>
</listener>

<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>

<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.servlet.MyServlet</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/star</url-pattern>
</servlet-mapping>
</web-app>

案例

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
package com.servlet;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletTestContextListener implements ServletContextListener {
// 实现其中的销毁函数
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("this is last destroyeed");
}

<span class="hljs-comment">// 实现其中的初始化函数,当有事件发生时即触发</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">contextInitialized</span><span class="hljs-params">(ServletContextEvent sce)</span> </span>{

	ServletContext sct = sce.getServletContext();

	Map<Integer, String> depts = <span class="hljs-keyword">new</span> HashMap<Integer, String>();

	depts.put(<span class="hljs-number">1</span>, <span class="hljs-string">"张三"</span>);
	depts.put(<span class="hljs-number">2</span>, <span class="hljs-string">"132456"</span>);

	<span class="hljs-comment">// 将所取到的值存放到一个属性键值对中</span>
	sct.setAttribute(<span class="hljs-string">"dept"</span>, depts);

}

}

Servlet Filter 过滤器

Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。

可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet

Servlet 过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。调用 Servlet 前调用所有附加的 Servlet 过滤器。

Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:

  • 在客户端的请求访问后端资源之前,拦截这些请求。
  • 在服务器的响应发送回客户端之前,处理这些响应。

根据规范建议的各种类型的过滤器:

  • 身份验证过滤器(Authentication Filters)。
  • 数据压缩过滤器(Data compression Filters)。
  • 加密过滤器(Encryption Filters)。
  • 触发资源访问事件过滤器。
  • 图像转换过滤器(Image Conversion Filters)。
  • 日志记录和审核过滤器(Logging and Auditing Filters)。
  • MIME-TYPE 链过滤器(MIME-TYPE Chain Filters)。
  • 标记化过滤器(Tokenizing Filters)。
  • XSL/T 过滤器(XSL/T Filters),转换 XML 内容。

过滤器根据web.xml文件中先后顺序执行

Servlet 过滤器方法

过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三个方法:

  • public void doFilter (ServletRequest, ServletResponse, FilterChain)
  • 该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器。
  • public void init(FilterConfig filterConfig)
  • web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
  • public void destroy()
  • Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

案例:统计IP

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
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
69

<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>Servletdisplay-name>
	<welcome-file-list>
		<welcome-file>index.htmlwelcome-file>
		<welcome-file>index.htmwelcome-file>
		<welcome-file>index.jspwelcome-file>
		<welcome-file>default.htmlwelcome-file>
		<welcome-file>default.htmwelcome-file>
		<welcome-file>default.jspwelcome-file>
	welcome-file-list>
<span class="hljs-tag"><<span class="hljs-title">listener</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">listener-class</span>></span>com.servlet.MyServletTestContextListener<span class="hljs-tag"></<span class="hljs-title">listener-class</span>></span>
<span class="hljs-tag"></<span class="hljs-title">listener</span>></span>

<span class="hljs-tag"><<span class="hljs-title">context-param</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">param-name</span>></span>username<span class="hljs-tag"></<span class="hljs-title">param-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">param-value</span>></span>root<span class="hljs-tag"></<span class="hljs-title">param-value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">context-param</span>></span>
<span class="hljs-tag"><<span class="hljs-title">context-param</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">param-name</span>></span>password<span class="hljs-tag"></<span class="hljs-title">param-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">param-value</span>></span>root<span class="hljs-tag"></<span class="hljs-title">param-value</span>></span>
<span class="hljs-tag"></<span class="hljs-title">context-param</span>></span>

<span class="hljs-tag"><<span class="hljs-title">filter</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">filter-name</span>></span>dataFilter<span class="hljs-tag"></<span class="hljs-title">filter-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">filter-class</span>></span>com.servlet.MyServletTestFilter<span class="hljs-tag"></<span class="hljs-title">filter-class</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">init-param</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">param-name</span>></span>test<span class="hljs-tag"></<span class="hljs-title">param-name</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">param-value</span>></span>测试数据<span class="hljs-tag"></<span class="hljs-title">param-value</span>></span>
	<span class="hljs-tag"></<span class="hljs-title">init-param</span>></span>
<span class="hljs-tag"></<span class="hljs-title">filter</span>></span>

<span class="hljs-tag"><<span class="hljs-title">filter-mapping</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">filter-name</span>></span>dataFilter<span class="hljs-tag"></<span class="hljs-title">filter-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">url-pattern</span>></span>/*<span class="hljs-tag"></<span class="hljs-title">url-pattern</span>></span>
	<span class="hljs-comment"><!-- /*是对所有的文件进行拦截 --></span>
<span class="hljs-tag"></<span class="hljs-title">filter-mapping</span>></span>

<span class="hljs-tag"><<span class="hljs-title">servlet</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">servlet-name</span>></span>MyServlet<span class="hljs-tag"></<span class="hljs-title">servlet-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">servlet-class</span>></span>com.servlet.MyServlet<span class="hljs-tag"></<span class="hljs-title">servlet-class</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">init-param</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">param-name</span>></span>charset<span class="hljs-tag"></<span class="hljs-title">param-name</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">param-value</span>></span>UTF-8<span class="hljs-tag"></<span class="hljs-title">param-value</span>></span>
	<span class="hljs-tag"></<span class="hljs-title">init-param</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">init-param</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">param-name</span>></span>name<span class="hljs-tag"></<span class="hljs-title">param-name</span>></span>
		<span class="hljs-tag"><<span class="hljs-title">param-value</span>></span>张三<span class="hljs-tag"></<span class="hljs-title">param-value</span>></span>
	<span class="hljs-tag"></<span class="hljs-title">init-param</span>></span>
<span class="hljs-tag"></<span class="hljs-title">servlet</span>></span>
<span class="hljs-tag"><<span class="hljs-title">servlet-mapping</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">servlet-name</span>></span>MyServlet<span class="hljs-tag"></<span class="hljs-title">servlet-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">url-pattern</span>></span>/star<span class="hljs-tag"></<span class="hljs-title">url-pattern</span>></span>
<span class="hljs-tag"></<span class="hljs-title">servlet-mapping</span>></span>

<span class="hljs-tag"><<span class="hljs-title">servlet</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">servlet-name</span>></span>MyTestFilter<span class="hljs-tag"></<span class="hljs-title">servlet-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">servlet-class</span>></span>com.servlet.MyServletTestFilterServlet<span class="hljs-tag"></<span class="hljs-title">servlet-class</span>></span>
<span class="hljs-tag"></<span class="hljs-title">servlet</span>></span>
<span class="hljs-tag"><<span class="hljs-title">servlet-mapping</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">servlet-name</span>></span>MyTestFilter<span class="hljs-tag"></<span class="hljs-title">servlet-name</span>></span>
	<span class="hljs-tag"><<span class="hljs-title">url-pattern</span>></span>/testfilter<span class="hljs-tag"></<span class="hljs-title">url-pattern</span>></span>
<span class="hljs-tag"></<span class="hljs-title">servlet-mapping</span>></span>

</web-app>

过滤器过滤 IP

DataFilter.java

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
package com.servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyServletTestFilter implements Filter {

<span class="hljs-keyword">private</span> FilterConfig filterConfig;

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">(FilterConfig filterConfig)</span> <span class="hljs-keyword">throws</span> ServletException </span>{
	<span class="hljs-comment">// 初始化参数,ipCount用来存放ip及访问次数</span>
	ServletContext application = filterConfig.getServletContext();
	Map<String, Integer> ipCount = <span class="hljs-keyword">new</span> HashMap<String, Integer>();
	application.setAttribute(<span class="hljs-string">"ipCount"</span>, ipCount);
	<span class="hljs-keyword">this</span>.filterConfig = filterConfig;
}

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">destroy</span><span class="hljs-params">()</span> </span>{

}

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doFilter</span><span class="hljs-params">(ServletRequest request, ServletResponse response, FilterChain chain)</span>
		<span class="hljs-keyword">throws</span> IOException, ServletException </span>{
	ServletContext application = filterConfig.getServletContext();
	Map<String, Integer> ipCount = (HashMap<String, Integer>) application.getAttribute(<span class="hljs-string">"ipCount"</span>);
	String ip = request.getRemoteAddr();
	Integer count = ipCount.get(ip);
	<span class="hljs-keyword">if</span> (count != <span class="hljs-keyword">null</span>) {
		<span class="hljs-comment">// Map中存在该ip</span>
		count = count + <span class="hljs-number">1</span>;
	} <span class="hljs-keyword">else</span> {
		count = <span class="hljs-number">1</span>;
	}
	ipCount.put(ip, count);
	System.out.println(ipCount.size());
	application.setAttribute(<span class="hljs-string">"ipCount"</span>, ipCount);
	chain.doFilter(request, response);
}

}

以表格形式返回数据

MyServletTestFilterServlet.java

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
package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServletTestFilterServlet extends HttpServlet {

<span class="hljs-annotation">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">service</span><span class="hljs-params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="hljs-keyword">throws</span> ServletException, IOException </span>{
	<span class="hljs-comment">// 设置响应类型</span>
	resp.setContentType(<span class="hljs-string">"text/html"</span>);
	resp.setCharacterEncoding(<span class="hljs-string">"utf-8"</span>);
	
	ServletContext application = req.getServletContext();
	Map<String, Integer> ipCount = (Map<String, Integer>) application.getAttribute(<span class="hljs-string">"ipCount"</span>);

	<span class="hljs-comment">// 实际的逻辑是在这里</span>
	PrintWriter out = resp.getWriter();
	out.println(<span class="hljs-string">"<h1>分IP统计网站浏览次数</h1>"</span>);
	out.print(<span class="hljs-string">"<table>"</span>);
	Iterator<Entry<String, Integer>> iterator = ipCount.entrySet().iterator();
	<span class="hljs-keyword">while</span> (iterator.hasNext()) {
		out.print(<span class="hljs-string">"<tr>"</span>);
		out.print(<span class="hljs-string">"<td>"</span>);
		out.print(iterator.next().getKey());
		out.print(<span class="hljs-string">"</td>"</span>);
		out.print(<span class="hljs-string">"<td>"</span>);
		out.print(iterator.next().getValue());
		out.print(<span class="hljs-string">"</td>"</span>);
		out.print(<span class="hljs-string">"</tr>"</span>);
	}
	out.print(<span class="hljs-string">"</table>"</span>);
}

}

结果

img

作业

实现登录功能

实现注册功能

    </article>
posted @ 2021-11-20 16:48  柠檬色的橘猫  阅读(44)  评论(0)    收藏  举报