JavaWeb学习笔记

学习时间:2021年9月8日至

1 XML

1.1 概述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="osg.AndroidExample"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"></uses-sdk>
<uses-feature android:glEsVersion="0x00020000"/> <!-- OpenGL min requierements (2.0) -->
<uses-permission android:name="android.permission.INTERNET"/>

<application android:label="@string/app_name" android:icon="@drawable/osg">
<activity android:name=".osgViewer"
android:label="@string/app_name" android:screenOrientation="landscape"> <!-- Force screen to landscape -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
</manifest>

XML数据格式最主要的功能就是数据传输

主要用途

  • 程序之间的数据传输通讯
  • 配置文件:config.xml
  • 存储数据,充当小型数据库:data.xml
  • 规范数据格式,使得数据具有结构性,易读易处理

1.2 什么是xml

  • xml(Extensible Markup Language)指的是,可扩展性标记语言

  • xml被发明的目的是传输和存储数据,而不是展示数据。

  • xml的标签必须自定义,但是在写标签时一定要有含义。
  • xml是W3C(万维网联盟)推荐的数据传输格式。
1
2
3
4
5
<!-- 必须要有一个根标签 -->
<root>
<user>曾弘毅</user>
<msg>你好,世界</msg>
</root>

xml和html的不同

  1. html的标签不能自定义,xml的标签必须自定义
  2. html语法要求不严格,xml则非常严格
  3. xml用来传输和存储数据,html 用来展示数据

1.3 xml基本语法

1.3.1 语法规则

  1. xml文档必须有根节点。根节点就是其他所有节点的父节点
  2. xml的头声明可有可无,但是建议写:包括版本号和文件编码格式
1
<?xml version="1.0" encoding="utf-8" ?>
  1. xml标签必须成对,标签名大小写敏感,标签不允许交叉编写
  2. 注释形式:
1
<!-- 这是注释 -->
  1. 特殊字符要使用实体名称进行转义
1
2
<msg>if a &lt; b</msg>
<!-- &lt;是<的实体名称 -->

1.3.2 属性规则

1
2
3
4
5
6
7
8
9
<root>
<man>
<name>张三</name>
<age>18</age>
</man>
<man>
<name age="20">李四</name>
</man>
</root>
  • 一个标签可以有多个属性,属性的值必须使用引号
  • xml中属性不太重要,解析属性时,属性会带来额外的解析代码

1.4 xml解析

1.4.1 解析技术介绍

早期的解析技术

早期 JDK 为我们提供了两种 xml 解析技术 DOM 和 Sax (已经过时)。dom 解析技术是 W3C 组织制定的,而所有的编程语言都对这个解析技术使用了自己语言的特点进行实现。 Java 对 dom 技术解析标记也做了实现。 sun 公司在 JDK5 版本对 dom 解析技术进行升级:SAX( Simple API for XML ) SAX 解析,它跟 W3C 制定的解析不太一样。它是以类似事件机制通过回调告诉用户当前正在解析的内容。 它是一行一行的读取 xml 文件进行解析的。不会创建大量的 dom 对象。 所以它在解析 xml 的时候,在内存的使用上。和性能上。都优于 Dom 解析。

第三方解析技术

  • jdom 在 dom 基础上进行了封装 、
  • dom4j 又对 jdom 进行了封装。
  • pull 主要用在 Android 手机开发,是在跟 sax 非常类似都是事件机制解析 xml 文件。

1.4.2 使用dom4j读取xml文档

编程步骤

第一步: 先加载 xml 文件创建 Document 对象

第二步:通过 Document 对象拿到根元素对象

第三步:通过根元素.elelemts(标签名); 可以返回一个集合,这个集合里放着。所有你指定的标签名的元素对象

第四步:找到你想要修改、删除的子元素,进行相应在的操作

第五步,保存到硬盘上

待读取的xml文档

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8" ?>
<books>
<book sn="SN123456">
<name>罗翔说刑法</name>
<price>9.8</price>
<author>张三</author>
</book>
<book sn="SN123457">
<name>老人与海</name>
<price>1.1</price>
<author>海明威</author>
</book>
</books>

获取Document对象

  1. 创建Book类
1
2
3
4
5
public class Book {
private String sn;
private String name;
private BigDecimal price;
}
  1. 获取Document对象
1
2
3
4
5
6
7
8
9
10
11
12
/**
* dom4j获取Document对象
*/
@Test
public void test1() throws DocumentException {
// 要创建一个document对象,我们需要创建一个SAXReader对象
SAXReader saxReader = new SAXReader();
// 这个对象用于读取xml,然后返回一个document对象
Document document = saxReader.read("src/main/resources/book.xml");
// 打印该对象
System.out.println(document);
}

遍历 标签 获取所有标签中的内容

  1. 通过创建 SAXReader 对象。来读取 xml 文件,获取 Document 对象
  2. 通过 Document 对象。拿到 XML 的根元素对象
  3. 通过根元素对象。获取所有的 book 标签对象
  4. 遍历每个 book 标签对象。然后获取到 book 标签对象内的每一个元素,再通过 getText() 方法拿到起始标签和结 束标签之间的文本内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 读取xml中的内容
*/
@Test
public void test2() throws DocumentException {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("src/main/resources/book.xml");
// 获取根元素对象
Element root = document.getRootElement();
System.out.println(root.asXML());// asXML()将当前元素转化为String对象
// 通过根元素对象,获取所有的book标签对象
List<Element> books = root.elements("book");
// 遍历每个book标签对象,然后获得每个book标签对象的每一个元素
for(Element book : books){
Element name = book.element("name");
Element price = book.element("price");
Element author = book.element("author");
// 通过 getText() 方法拿到起始标签和结束标签之间的文本内容
System.out.println("书名" + name.getText() + " , 价格:" + price.getText() + ", 作者:" + author.getText());
}
}

image-20210911105647311

2 Tomcat

2.1 概述

javaweb的概念

JavaWeb 是指,所有通过 Java 语言编写可以通过浏览器访问的程序的总称,叫 JavaWeb。

JavaWeb 是基于请求和响应来开发的

请求和响应

  • 请求是指客户端给服务器发送数据,叫请求 Request。

  • 响应是指服务器给客户端回传数据,叫响应 Response。

web资源的分类

web 资源按实现的技术和呈现的效果的不同,又分为静态资源和动态资源两种。

  • 静态资源: html、css、js、txt、mp4 视频 , jpg 图片
  • 动态资源: jsp 页面、Servlet 程序

常用的web服务器

  1. Tomcat:由 Apache 组织提供的一种 Web 服务器,提供对 jsp 和 Servlet 的支持。它是一种轻量级的 javaWeb 容器(服务 器),也是当前应用最广的 JavaWeb 服务器(免费)。
  2. Jboss:是一个遵从 JavaEE 规范的、开放源代码的、纯 Java 的 EJB 服务器,它支持所有的 JavaEE 规范(免费)。
  3. GlassFish: 由 Oracle 公司开发的一款 JavaWeb 服务器,是一款强健的商业服务器,达到产品级质量(应用很少)。
  4. Resin:是 CAUCHO 公司的产品,是一个非常流行的服务器,对 servlet 和 JSP 提供了良好的支持, 性能也比较优良,resin 自身采用 JAVA 语言开发(收费,应用比较多)。
  5. WebLogic:是 Oracle 公司的产品,是目前应用最广泛的 Web 服务器,支持 JavaEE 规范, 而且不断的完善以适应新的开发要求,适合大型项目(收费,用的不多,适合大公司)。

2.2 Tomcat使用

tomcat目录介绍

image-20210912145515541

  • bin:可执行程序
  • conf:配置文件
  • lib:jar包
  • logs:存放服务器运行时输出的日志
  • temp:存放产生的临时数据
  • webapps:存放部署的Web工程,该目录下的每一个目录都是一个web工程项目
  • work:tomcat工作时的目录,用来存放tomcat运行时jsp翻译为servlet的源码,和session钝化的目录

启动tomcat

  1. 方法一:找到bin下的startup.bat文件,双击打开:

image-20210912150804106

测试:localhost:8080

image-20210912150838506

  1. 方法二:采用命令行启动,cd到bin目录下,输入命令
1
catalina run

image-20210912151135972

停止tomcat

  • 双击bin目录下的shutdown.bat
  • 在命令行窗口中按ctrl+C关闭

修改tomcat默认端口号

  • 默认端口号为8080

  • 修改conf/server.xml中Connector标签的port属性

1
2
3
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

2.3 web工程部署在Tomcat

  1. 方法1:直接将工程目录放置在webapps下
  2. 方法2:在conf/Catalina/localhost下创建一个xml配置文件abc.xml:
1
2
<!-- Context 表示一个工程上下文 path 表示工程的访问路径:/abc docBase 表示你的工程目录在哪里 --> 
<Context path="/abc" docBase="E:\book" />

访问路径:http://ip:port/abc/ 就表示访问 E:\book 目录

手托 html 页面到浏览器和在浏览器中输入 http://ip:端口号/工程名/访问的区别

协议不同,一个是file协议,一个是http协议

image-20210912152841086

image-20210912152948269

ROOT工程访问

  • 当我们在浏览器地址栏中输入访问地址如下: http://ip:port/ 没有工程名的时候,默认访问的是webapps下的ROOT工程,即tomcat默认主页

image-20210912153234071

  • 当我们在浏览器地址栏中输入的访问地址如下: http://ip:port/工程名/ ,而没有资源名,默认访问 index.html 页面

2.4 idea整合Tomcat

整合tomcat

image-20210912153448918

image-20210912153545488

在idea中创建web动态工程

image-20210912153839950

web工程目录介绍

image-20210912154228041

  • WEB-INF:是一个受服务器保护的目录,浏览器无法直接访问到该目录的内容
  • web.xml:它是整个动态web工程的配置部署描述文件,可以在这里配置很多web工程的组件,比如Servlet程序,Filter过滤器,Listener监听器,Session超时等等

idea在tomcat部署web工程

  1. 建议修改 web 工程对应的 Tomcat 运行实例名称:

image-20210912155736375

image-20210912155959681

3 Servlet

3.1 Servlet技术

3.1.1 什么是Servlet

  1. Servlet 是 JavaEE 规范之一。规范就是接口 。

  2. Servlet 就 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器

  3. Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。

3.1.2 手动实现Servlet程序

  1. 编写一个类去实现 Servlet 接口

  2. 实现 service 方法,处理请求,并响应数据

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
public class HelloServlet implements Servlet {

@Override
public void init(ServletConfig servletConfig) throws ServletException {

}

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

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("HelloServlet 被访问了");
}

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

@Override
public void destroy() {

}
}
  1. 到 web.xml 中去配置 servlet 程序的访问地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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标签给tomcat配置servlet程序 -->
<servlet>
<!-- 给servlet程序起别名,一般是类名 -->
<servlet-name>HelloServlet</servlet-name>
<!-- servlet-class是servlet程序的全类名 -->
<servlet-class>com.hongyi.servlet_demo.HelloServlet</servlet-class>
</servlet>

<!-- servlet-mapping标签给servlet程序配置访问地址 -->
<servlet-mapping>
<!-- 告诉tomcat,我当前配置的地址给那个servlet程序使用 -->
<servlet-name>HelloServlet</servlet-name>
<!-- 配置访问地址 -->
<!-- / 在tomcat解析的时候,表示地址为http://ip:port/工程路径 -->
<!-- /hello 表示地址为http://ip:port/工程路径/hello -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>

image-20210915113256758

注意:tomcat10之后servlet依赖包名不是javax.servlet,而是jakarta.servlet,maven依赖如下:

1
2
3
4
5
6
7
8
9
10
11
12
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency

url地址到Servlet程序的访问

image-20210915114256579

3.1.3 servlet生命周期

  1. 执行 Servlet 构造器方法

  2. 执行 init 初始化方法 :第一、二步,是在第一次访问的时候,创建 Servlet 程序会调用。

  3. 执行 service 方法:第三步,每次访问都会调用

  4. 执行 destroy 销毁方法 :第四步,在 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
public class HelloServlet implements Servlet {

public HelloServlet() {
System.out.println("1 构造方法被调用");
}

@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init方法被调用");
}

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

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3 HelloServlet 被访问了");
}

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

@Override
public void destroy() {
System.out.println("4 destroy方法被调用");
}
}

image-20210915114810030

3.1.4 GET 和 POST 请求的分发处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3 HelloServlet 被访问了");
// 类型转换
HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
// 获取请求方式
String method = httpServletRequest.getMethod();
if ("GET".equals(method)){
doGet();
}else if("POST".equals(method)){
doPost();
}
}

private void doPost() {
System.out.println("接收到POST请求");
}

private void doGet() {
System.out.println("接收到GET请求");
}

3.1.5 通过继承HttpServlet实现Servlet程序

一般在实际项目开发中,都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。

  1. 编写一个类去继承 HttpServlet 类

  2. 根据业务需要重写 doGet 或 doPost 方法

  3. 到 web.xml 中的配置 Servlet 程序的访问地址

1
2
3
4
5
6
7
8
9
10
11
12
13
public class HelloServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
System.out.println("HelloServlet2的doGet方法");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("HelloServlet2的doPost方法");
}
}

3.1.6 使用idea创建servlet程序

image-20210916144520580

image-20210916144652354

自动生成的servlet代码:

1
2
3
4
5
6
7
8
9
10
11
public class HelloServlet3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

3.1.7 servlet类的继承体系

image-20210916151445030

3.2 ServletConfig类

  • ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。

  • Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。

  • Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象

ServletConfig 类的三大作用

  1. 可以获取 Servlet 程序的别名 servlet-name 的值

  2. 获取初始化参数 init-param

  3. 获取 ServletContext 对象

1
2
3
4
5
6
7
8
9
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// 1. 可以获取 Servlet 程序的别名 servlet-name 的值
System.out.println("该servlet程序的别名是:" + servletConfig.getServletName());
// 2. 获取初始化参数 init-param
System.out.println("初始化参数url的值是:" + servletConfig.getInitParameter("url"));
// 3. 获取 ServletContext 对象
System.out.println(servletConfig.getServletContext());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- servlet标签给tomcat配置servlet程序 -->
<servlet>
<!-- 给servlet程序起别名,一般是类名 -->
<servlet-name>HelloServlet</servlet-name>
<!-- servlet-class是servlet程序的全类名 -->
<servlet-class>com.hongyi.servlet_demo.HelloServlet</servlet-class>
<!-- init-param是初始化参数 -->
<init-param>
<!-- 参数名 -->
<param-name>url</param-name>
<!-- 参数值 -->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>

3.3 ServletContext类

3.3.1 什么是ServletContext

  1. ServletContext 是一个接口,它表示 Servlet 上下文对象

  2. 一个 web 工程,只有一个 ServletContext 对象实例

  3. ServletContext 对象是一个域对象。

  4. ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。

什么是域对象?

域对象,是可以像 Map 一样存取数据的对象,叫域对象。

这里的域指的是存取数据的操作范围,而范围则是整个 web 工程。

存数据 取数据 删除数据
Map put get remove
域对象 setAttribute getAttribute removeAttribute

3.3.2 ServletContext 类的四个作用

  1. 获取 web.xml 中配置的上下文参数 context-param

  2. 获取当前的工程路径,格式: /工程路径

  3. 获取工程部署后在服务器硬盘上的绝对路径

  4. 像 Map 一样存取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ContextServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 web.xml 中配置的上下文参数 context-param
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
String password = context.getInitParameter("password");
System.out.println(username + password);
// 2. 获取当前的工程路径,格式: /工程路径
System.out.println(context.getContextPath()); // /servlet_demo
// 3. 获取工程部署后在服务器硬盘上的绝对路径
// 斜杠/ 映射到idea代码的web目录
System.out.println("工程部署的路径是:" + context.getRealPath("/"));
System.out.println("工程下css目录的绝对路径是:" + context.getRealPath("/css"));
}
}
1
2
3
4
5
6
7
8
9
<!-- context-param是上下文参数(它属于整个web工程) -->
<context-param>
<param-name>username</param-name>
<param-value>hongyi</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>

image-20210916155320045

1
2
3
4
// 4. 像 Map 一样存取数据
ServletContext context1 = getServletContext();
context1.setAttribute("k1", "v1");
System.out.println(context1.getAttribute("k1"));

3.4 Http协议

什么是协议?

协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。

所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。 HTTP 协议中的数据又叫报文。

3.4.1 请求的 HTTP 协议格式

GET请求

  1. 请求行:

(1)请求的方式:GET

(2)请求的资源路径[+?+请求参数] 后面的是可选参数

(3)请求的协议的版本号:HTTP/1.1

  1. 请求头:

key:value 组成 不同的键值对,表示不同的含义

image-20210919141228036

POST请求

  1. 请求行:

(1)请求的方式:POST

(2)请求的资源路径[+?+请求参数] 后面的是可选参数

(3)请求的协议的版本号:HTTP/1.1

  1. 请求头:

key:value 组成 不同的键值对,表示不同的含义

空行

  1. 请求体:发送给服务器的数据

image-20210919141732677

哪些是GET请求,哪些是POST请求

  • GET 请求有哪些:
  1. form 标签 method=get

  2. a 标签

  3. link 标签引入 css

  4. Script 标签引入 js 文件

  5. img 标签引入图片

  6. iframe 引入 html 页面

  7. 在浏览器地址栏中输入地址后敲回车

  • POST 请求有哪些:
  1. form 标签 method=post

3.4.2 响应的 HTTP 协议格式

  1. 响应行:

(1)响应的协议和版本号

(2)响应状态码

(3)响应状态描述符

  1. 响应头:kv键值对

空行

  1. 响应体:回传给客户端的数据

image-20210919142200965

常见的响应码

  • 200 :表示请求成功

  • 302 :表示请求重定向

  • 404 :表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)

  • 500 :表示服务器已经收到请求,但是服务器内部错误(代码错误)

3.5 HttpServletRequest类

每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到Request 对象中。然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。

3.5.1 常用方法

  1. getRequestURI() :获取请求的资源路径

  2. getRequestURL() :获取请求的统一资源定位符(绝对路径)

  3. getRemoteHost() 获取客户端的 ip 地址
  4. getHeader() 获取请求头
  5. getParameter() 获取请求的参数
  6. getParameterValues() 获取请求的参数(多个值的时候使用)
  7. getMethod() 获取请求的方式 GET 或 POST
  8. setAttribute(key, value); 设置域数据
  9. getAttribute(key); 获取域数据
  10. getRequestDispatcher() 获取请求转发对象
1
2
3
4
5
6
7
8
9
10
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("URI:" + req.getRequestURI());
System.out.println("URL:" + req.getRequestURL());
System.out.println("客户端IP地址:" + req.getRemoteUser());
System.out.println("请求头user-agent:" + req.getHeader("User-Agent"));
System.out.println("请求方式:" + req.getMethod());
}
}

image-20210919143757656

获取请求参数:

1
2
3
4
5
6
7
8
9
10
11
12
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby"); // 数组形式
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.asList(hobby));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/parameterServlet" method="get">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">Javascript<br/>
<input type="submit">
</form>
</body>
</html>

执行结果:

image-20210919144903197

image-20210919144845836

3.5.2 请求转发

请求转发是指,服务器收到请求后,从一个资源跳转到另一个资源的操作叫请求转发。

image-20210919150228023

  • servlet1代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println("在Servlet1中查看的参数" + username);

// 添加域数据
req.setAttribute("key", "servlet1");

// 请求转发至Servlet2
/**
* 请求转发必须以 / 开头
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
requestDispatcher.forward(req, resp);
}
}
  • servlet2代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println("在Servlet1中查看的参数" + username);

// 查看servlet1是否有数据
Object key = req.getAttribute("key");
System.out.println("servlet1的key:" + key);

// 处理自己的业务
System.out.println("servlet2处理自己的业务...");
}
}
  • 请求地址
1
http://localhost:8080/servlet1?username=zym
  • 执行结果

image-20210919151332578

特点

  1. 浏览器地址栏没有变化
  2. 他们是一次请求
  3. 他们共享Request域中的数据
  4. 可以转发到WEB-INF目录下
  5. 不可以访问工程以外的资源

3.5.3 base标签的作用