第4章 Servlet基础
学习目标
- 掌握Servlet的基本概念、特点及其接口
- 熟悉使用IDEA工具开发Servlet
- 掌握Servlet的配置以及Servlet的生命周期
- 掌握ServletConfig和ServletContext接口的使用
- 掌握HttpServletRequest、HttpServletResponse对象的使用
目前开发动态Web应用中,比较较常见的技术有JSP和Servlet(Java)①、ASP(C#,.net)⑤、PHP(php)④、Nodejs(js)②、Python(python)③等技术。基于Java的动态Web开发技术,SUN公司提供了Servlet和JSP两种技术。
1. Servlet基础
1.1 Servlet概述
Servlet是什么 Web服务器端的小程序
Servlet(Server Applet)是运行在Web服务器端的Java应用小程序(使用Java语言编写)。Servlet对象主要封装了对HTTP请求/响应的处理,并且它的运行需要Servlet容器(如Tomcat)的支持。
Servlet容器
Servlet容器是提供了Servlet功能的服务器(如Tomcat)。Servlet容器将Servlet动态地加载到服务器上。使用HTTP请求和响应与客户端进行交互。
Servlet静态、动态结合的体系结构
Servlet的请求首先会被HTTP服务器(如Apache)接收,HTTP服务器只负责静态HTML页面的解析,对于Servlet的请求转交给Servlet容器,Servlet容器会根据web.xml文件中的映射关系,调用相应的Servlet,Servlet将处理的结果返回给Servlet容器,并通过HTTP服务器将响应传输给客户端。
Servlet纯容器解析的体系结构
无论静态HTML资源(html、css、js、images)的解析,还是动态请求(jsp、servlet)的解析都交给Servlet容器解析。静态资源Servlet容器直接返回浏览器客户端,动态资源Servlet容器会根据web.xml文件中的映射关系,调用相应的Servlet,Servlet将处理的结果返回给Servlet容器,并通过HTTP服务器将响应传输给客户端。
1.2 Servlet的特点
Servlet使用Java语言编写,它不仅具有Java 语言的优点,而且还对Web的相关应用进行了封装,同时Servlet容器还提供了对应用的相关扩展,无论是在功能、性能、安全等方面都十分优秀。
- 功能强大 Servlet既拥有Java提供的API,而且还可以调用Servlet封装的Servlet API编程接口,对HTTP请求/响应进行相应的处理,如处理提交数据、会话跟踪、读取和设置HTTP头信息等。
- 可移植性 Java语言是跨越平台性
- 性能高效 当Servlet对象第一次被请求时,Servlet 容器将Servlet对象实例化并驻存于内存中。此后的多次请求,Servlet不会再被实例化,仍然由第一次被实例化、驻留在内存中的Servlet对象处理其请求。每一个请求是一个线程,而不是一个进程。
- 安全性高 Servlet使用了Java的安全框架
- 可扩展 在业务逻辑处理中,可以通过封装、继承等特性扩展实际的业务需要。
1.3 Servlet接口(javax.servlet.Servlet接口)
SUN公司提供了一系列接口和类,其中最重要的是javax.servlet.Servlet接口。Servlet就是一种实现了Servlet接口的类,它由Web容器负责创建并调用,用于接收和响应用户的请求。
方法声明 | 功能描述 |
---|---|
void init(ServletConfig config) | Servlet实例化后,Servlet容器调用该方法完成初始化----出生,仅一次工作 |
ServletConfig getServletConfig() | 用于获取Servlet对象的配置信息,返回Servlet的ServletConfig对象 |
String getServletInfo() | 返回一个字符串,其中包含关于Servlet的信息,例如,作者、版本和版权等信息 |
void service(ServletRequest request,ServletResponse response) | 服务----伺候,多次 负责响应用户的请求,当容器接收到客户端访问Servlet对象的请求时,就会调用此方法。容器会构造一个表示客户端请求信息的ServletRequest对象和一个用于响应客户端的ServletResponse对象作为参数传递给service()方法。在service()方法中,可以通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息 |
void destroy() | 当服务器关闭或者Servlet对象被移除时,Servlet对象会被销毁----灭亡,仅一次,容器会调用此方法 |
在Servlet接口中的5个方法中,init()、service()和destroy()这三个方法可以表现Servlet的生命周期,它们会在某个特定的时刻被调用。
Servlet接口的实现类
SUN公司提供了两个默认的接口实现类:GenericServlet和HttpServlet。
- GenericServlet是一个抽象类,该类为Servlet接口提供了部分实现,它并没有实现HTTP请求处理。
- HttpServlet是GenericServlet的子类,它继承了GenericServlet的所有方法,并且为HTTP请求中的POST、GET等类型提供了具体的操作方法。
HttpServlet类的常用方法及功能
方法声明 | 功能描述 |
---|---|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) | 用于处理GET类型的Http请求的方法 |
protected void doPost(HttpServletRequest req, HttpServletResponse resp) | 用于处理POST类型的Http请求的方法 |
protected void doPut(HttpServletRequest req, HttpServletResponse resp) | 用于处理PUT类型的Http请求的方法 |
2. Servlet开发入门
2.1 实现第一个Servlet程序
(1) 启动IntelliJ IDEA开发工具,单击工具栏中的[文件] →[新建] →[项目] ,此时会弹出一个【新建项目】界面。选新建项目,①输入项目名称:如ch04_zxx,自动确定本次JavaWeb源代码存储位置,如E:\jxpJavaWeb,语言和构建系统选Java和IntelliJ;②选定JDK版本、③【创建】。
(2) 右击项目如[ch04_zxx]选【添加框架支持...】,弹出【添加框架支持】界面,选①JavaEE --> Web应用程序、版本4.0、创建Web.xml;②【确定】。
(3) IntelliJ IDEA工具,单击工具栏中的[文件] → [项目结构]弹出【项目结构】界面,选【模块】,①单击加号+;②库...;③Tomcat ;④添加所选项;⑤应用;⑥【确定】。
(4) IntelliJ IDEA工具,单击工具栏中的[文件] → [项目结构]弹出【项目结构】界面,选【工件】,①更换类型:归档;②重命名:ch04_zxx,输出目录自动更换为: out\artifacts\ch04_zxx,打包文件自动重命名为: ch04_zxx.war(用于部署);③应用;④【确定】,如图6、图7所示。
(5)在IDEA的菜单栏中单击[运行] →[编辑配置...], 会弹出一个[运行/调试配置]界面,①单击加号+,会弹出[添加新配置];②选择Tomcat服务器-->本地,如图8所示,弹出如图9所示界面,单击部署。
在【部署】界面,①单击加号+,选工件ch04_zxx,;②修改应用程序上下文:/ch04_zxx;③应用;④【确定】,如图10所示。
在【服务器】界面,①添加虚拟机选项:-Dfile.encoding=UTF-8;②修改JRE:③应用;④【确定】,如图11所示。
在IDEA的菜单栏中单击[运行] →[运行...], 会弹出如图12所示界面,单击部署。
\web\index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>ch04 Servlet基础</title>
</head>
<body>
<h1>ch04 Servlet基础(张晓轩)</h1>
<hr>
<a href="TestServlet01">1. 第一个Servlet(@WebServlet("/TestServlet01" 配置)</a><br>
<a href="jxp/第一个Servlet">1. 第一个Servlet(web.xml 配置)</a><br>
<a href="TestServlet02">2.1 Servlet生命周期(查看控制台输出)</a><br>
<a href="TestServlet03">3.1 获取@WebServlet(initParams={@WebInitParam(name="...", value="...")}设置值</a><br>
<a href="带参数的Servlet网址">3.1 获取web.xml中servlet设置的初始化参数值</a><br>
<a href="TestServlet04">3.2 (1) 读取Web.xml上下文配置参数</a><br>
<a href="TestServlet05">3.2 (2) 通过context.setAttribute进行servlet之间通讯 set</a><br>
<a href="TestServlet06">3.2 (2) 通过context.getAttribute进行servlet之间通讯 get</a><br>
<a href="TestServlet07">3.2 (3) 获取.properties文件中的属性值【context.getResourceAsStream()】</a><br>
<a href="TestServlet08">3.2 (3) 获取.properties文件中的属性值【context.getRealPath()】</a><br>
<a href="StatusServlet">4.1 发送状态码相关的方法(response.setStatus | sendError)</a><br>
<a href="HeaderServlet">4.2 发送响应头相关的方法 response.setCharacterEncoding | setContentType </a><br>
<a href="PrintServlet">4.3 发送响应消息体相关的方法(字符输出流)</a><br>
<a href="PrintServlet2">4.3 发送响应消息体相关的方法(字节输出流)</a><br>
<a href="PrintServlet3">4.3 发送响应消息体相关的方法(字节输出流--照片)</a><br>
<a href="LoginServlet">5.1 实现请求重定向--登录 response.sendRedirect("重定向url");</a><br>
<a href="ChineseServlet0">5.2 中文输出乱码问题 response.默认字符编码ISO8859-1;</a><br>
<a href="ChineseServlet1">5.2 中文输出乱码问题 response.setCharacterEncoding("utf-8");</a><br>
<a href="ChineseServlet">5.2 动手实践:解决中文输出乱码问题 response.setContentType("text/html;charset=utf-8");</a><br>
<a href="RequestLineServlet">6.1 获取请求行信息的相关方法 request.getScheme(); ...</a><br>
<a href="RequestHeadersServlet">6.2 获取请求头的相关方法 request.getHeaderNames(); </a><br>
<a href="请求转发">6.3 请求转发 request.getRequestDispatcher("/转发url").forward(request, response);</a><br>
<a href="form.html">6.4 获取请求参数 request.getParameter("input中name参数");</a><br>
<a href="Request传递数据">6.5 通过Request对象传递数据 request.setAttribute | getAttribute | removeAttribute </a><br>
<a href="Request传递数据2">6.5 通过Request对象传递数据2 request.setAttribute | getAttribute | removeAttribute </a><br>
<hr>
<p><a href="http://101.42.158.247/21javaweb.html">返回课程首页</a>
张晓轩<script>document.write(document.lastModified); </script>制作</p>
</body>
</html>
cn.zxx.servlet.TestServlet01.java
package cn.zxx.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/TestServlet01")
public class TestServlet01 extends HttpServlet {
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("第一个Servlet(张晓轩)。");
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
运行结果如下:
2.2 Servlet的配置
若想让Servlet正确地运行在服务器中并处理请求信息,必须进行适当的配置,关于Servlet的配置主要有两种方式,分别是通过Web应用的配置文件web.xml来完成配置和使用@WebServlet注解的方式完成。
(1) 使用web.xml配置Servlet
<servlet>元素的子元素
子元素 | 类型 | 说明 |
---|---|---|
<servlet-name> | String | 指定该Servlet的名称,随意命名,要求唯一 |
<servlet-class> | String | 指定该Servlet类的位置,包括包名与类名 |
<description> | String | 指定该Servlet的描述信息 |
<display-name> | String | 指定该Servlet的显示名 |
<servlet-mapping>元素的子元素
子元素 | 类型 | 说明 |
---|---|---|
<servlet-name> | String | 指定该Servlet的名称,要求与<servlet>相对应 |
<url-pattern> | String | 访问url,从/开始 |
<description> | String | 指定该Servlet的描述信息 |
<display-name> | String | 指定该Servlet的显示名 |
web.xml中servlet配置之一
<!-- 同一servlet类,可以定义成不同url访问地址,但同一url访问地址不可访问多个(>1)个servlet类-->
<servlet>
<servlet-name>第1个Servlet</servlet-name>
<servlet-class>cn.zxx.servlet.TestServlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>第1个Servlet</servlet-name>
<url-pattern>/jxp/第一个Servlet</url-pattern>
</servlet-mapping>
注意:同一servlet类,可以定义成不同url访问地址,但同一url访问地址不可访问多个(>1)个servlet类
(2) @WebServlet注解属性
属性声明 | 功能描述 |
---|---|
String name | 指定Servlet的name属性,等价于<servlet-name>。如果没有显式指定,则该Servlet的取值即为类的全限定名。 |
String[] value | 该属性等价于urlPatterns属性。urlPatterns和value属性不能同时使用。 |
String[] urlPatterns | 指定一组Servlet的URL匹配模式。等价于<url-pattern>标签。 |
int loadOnStartup | 指定Servlet的加载顺序,等价于<load-on-startup>标签。 |
WebInitParam[] | 指定一组Servlet初始化参数,等价于<init-param>标签。 |
boolean asyncSupported | 声明Servlet是否支持异步操作模式,等价于<async-supported> 标签。 |
String description | Servlet的描述信息,等价于<description>标签。 |
String displayName | Servlet的显示名,通常配合工具使用,等价于<display-name>标签。 |
2.3 Servlet的生命周期
在Servlet的整个生命周期内,它的init()方法只被调用一次--出生,在第1次调用该Servlet时创建实例初始化。
在Servlet的整个生命周期内,对于Servlet的每一次访问请求,Servlet容器都会调用一次Servlet的service()方法,并且创建新的ServletRequest和ServletResponse对象。执行多次--每请求1次执行1从
在Servlet的整个生命周期中,destroy()方法也只被调用一次--销毁,在web应用被移除出容器时或停止服务器时Servlet对象才会销毁。
cn.zxx.servlet.TestServlet02.java
package cn.zxx.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.*;
@WebServlet("/TestServlet02")
public class TestServlet02 extends GenericServlet {
public void init(ServletConfig config) throws ServletException {
System.out.println("你好,张晓轩。init method 初始化方法被调用----出生。只有1次出生");
}
public void service(ServletRequest request, ServletResponse response)
throws ServletException {
System.out.println("你好,张晓轩。service 服务方法被调用。可调用多次...");
}
public void destroy() {
System.out.println("你好,张晓轩。destroy method 销毁方法被调用----灭亡。只有1次销毁");
}
}
运行结果如下:
3. ServletConfig和ServletContext
3.1 ServletConfig接口
在Servlet运行期间,经常需要一些配置信息,例如,文件使用的编码等,这些信息都可以在@WebServlet注解的属性中配置。当Tomcat初始化一个Servlet时,会将该Servlet的配置信息封装到一个ServletConfig对象中,通过调用init(ServletConfig config)方法将ServletConfig对象传递给Servlet。
方法说明 | 功能描述 |
---|---|
String getInitParameter(String name) | 根据初始化参数名返回对应的初始化参数值 |
Enumeration getInitParameterNames() | 返回一个Enumeration对象,其中包含了所有的初始化参数名 |
ServletContext getServletContext() | 返回一个代表当前Web应用的ServletContext对象 |
String getServletName() | 返回Servlet的名字 |
cn.zxx.servlet.TestServlet03.java
package cn.zxx.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.WebInitParam;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
@WebServlet(urlPatterns = "/TestServlet03",
initParams = {@WebInitParam(name = "encoding", value = "UFT-8"),@WebInitParam(name = "使用单位", value = "信息工程学院")})
public class TestServlet03 extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 获得ServletConfig对象
ServletConfig config = this.getServletConfig();
// 获得参数名为encoding对应的参数值
String param = config.getInitParameter("encoding");
out.println("encoding=" + param);
param = config.getInitParameter("使用单位");
out.println("<br>使用单位=" + param);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
运行结果如下:
web.xml中servlet配置之二
<!-- servlet-name的名字随便命名,只要servlet和servlet-mapping相对应即可-->
<servlet>
<servlet-name>带参数的Servlet</servlet-name>
<servlet-class>cn.zxx.servlet.TestServlet03</servlet-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<param-name>使用单位</param-name>
<param-value>数字媒体技术教研室</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>带参数的Servlet</servlet-name>
<url-pattern>/带参数的Servlet网址</url-pattern>
</servlet-mapping>
运行结果如下:
3.2 ServletContext接口
(1)获取Web应用程序的初始化参数
方法说明 | 功能描述 |
---|---|
Enumeration |
返回一个Enumeration对象,该对象包含所有初始化参数名的Enumeration对象 |
web.xml中context-param片段
<context-param>
<param-name>学院名称</param-name>
<param-value>信息工程学院</param-value>
</context-param>
<context-param>
<param-name>地址</param-name>
<param-value>晋中市文华街125号</param-value>
</context-param>
cn.zxx.servlet.TestServlet04.java
package cn.zxx.servlet;
import javax.servlet.annotation.WebServlet;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
@WebServlet("/TestServlet04")
public class TestServlet04 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 得到ServletContext对象
ServletContext context = this.getServletContext();
// 得到包含所有初始化参数名的Enumeration对象
Enumeration<String> paramNames = context.getInitParameterNames();
out.println("所有参数名称和参数值如下:<br>");
// 遍历所有的初始化参数名,得到相应的参数值并打印
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = context.getInitParameter(name);
out.println(name + " : " + value);
out.println("<br>");
}
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
运行结果如下:
(2)实现多个Servlet对象共享数据
方法说明 | 功能描述 |
---|---|
Enumeration getAttributeNames() | 返回一个Enumeration对象,该对象包含了所有存放在ServletContext中的所有域属性名 |
Object getAttibute(String name) | 根据参数指定的属性名返回一个与之匹配的域属性值 |
void removeAttribute(String name) | 根据参数指定的域属性名,从ServletContext中删除匹配的域属性 |
void setAttribute(String name,Object obj) | 设置ServletContext的域属性,其中name是域属性名,obj是域属性值 |
cn.zxx.servlet.TestServlet05.java
package cn.zxx.servlet;
import javax.servlet.annotation.WebServlet;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
@WebServlet("/TestServlet05")
public class TestServlet05 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
ServletContext context = this.getServletContext();
// 通过setAttribute()方法设置属性值
context.setAttribute("data", "this servlet save data. 这是servlet保存数据--上下文属性值。");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
cn.zxx.servlet.TestServlet06.java
package cn.zxx.servlet;
import javax.servlet.annotation.WebServlet;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
@WebServlet("/TestServlet06")
public class TestServlet06 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
ServletContext context = this.getServletContext();
// 通过getAttribute()方法获取属性值
String data = (String) context.getAttribute("data");
out.println(data);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
运行结果如下:
(3) 读取Web应用下的资源文件
方法说明 | 功能描述 |
---|---|
Set getResourcePaths(String path) | 返回一个Set集合,集合中包含资源目录中子目录和文件的路径名称。参数path必须以正斜线(/)开始,指定匹配资源的部分路径 |
String getRealPath(String path) | 返回资源文件在服务器文件系统上的真实路径(文件的绝对路径)。参数path代表资源文件的虚拟路径,它应该以正斜线(/)开始,“/”表示当前Web应用的根目录,如果Servlet容器不能将虚拟路径转换为文件系统的真实路径,则返回null |
URL getResource(String path) | 返回映射到某个资源文件的URL对象。参数path必须以正斜线(/)开始,“/”表示当前Web应用的根目录 |
InputStream getResourceAsStream(String path) | 返回映射到某个资源文件的InputStream输入流对象。参数path传递规则和getResource()方法完全一致 |
src/jxp.properties
Company=zxxzhaojiang
Address=Taiyuan
公司=信息工程学院
地址=山西省晋中市榆次区文华街125号
cn.zxx.servlet.TestServlet07.java
package cn.zxx.servlet;
import javax.servlet.annotation.WebServlet;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import javax.servlet.*;
import javax.servlet.http.*;
@WebServlet("/TestServlet07")
public class TestServlet07 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
ServletContext context = this.getServletContext();
PrintWriter out = response.getWriter();
//获取相对路径中的输入流对象
InputStream in = context
.getResourceAsStream("/WEB-INF/classes/jxp.properties");
Properties pros = new Properties();
pros.load(in);
out.println("Company = " + pros.getProperty("Company") + "<br>");
out.println("Address = " + pros.getProperty("Address") + "<br>");
out.println("公司 = " + pros.getProperty("公司") + "<br>");
out.println("地址 = " + pros.getProperty("地址") + "<br>");
InputStream in2 = context
.getResourceAsStream("/WEB-INF/classes/jxp.properties");
Properties pros2 = new Properties();
InputStreamReader isr = new InputStreamReader(in2 , StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
pros.load(br);
out.println("Company = " + pros.getProperty("Company") + "<br>");
out.println("Address = " + pros.getProperty("Address") + "<br>");
out.println("公司 = " + pros.getProperty("公司") + "<br>");
out.println("地址 = " + pros.getProperty("地址") + "<br>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
运行结果如下:
cn.zxx.servlet.TestServlet08.java
package cn.zxx.servlet;
import javax.servlet.annotation.WebServlet;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import javax.servlet.*;
import javax.servlet.http.*;
@WebServlet("/TestServlet08")
public class TestServlet08 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
ServletContext context = this.getServletContext();
//获取文件绝对路径
String path = context
.getRealPath("/WEB-INF/classes/jxp.properties");
FileInputStream in = new FileInputStream(path);
Properties pros = new Properties();
pros.load(in);
out.println("Company=" + pros.getProperty("Company") + "<br>");
out.println("Address=" + pros.getProperty("Address") + "<br>");
out.println("公司 = " + pros.getProperty("公司") + "<br>");
out.println("地址 = " + pros.getProperty("地址") + "<br><hr>");
FileInputStream in2 = new FileInputStream(path);
InputStreamReader isr = new InputStreamReader(in2, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
// 一定一定要 load 设置编码后的字符流
Properties pros2 = new Properties();
pros2.load(br);
out.println("Company=" + pros2.getProperty("Company") + "<br>");
out.println("Address=" + pros2.getProperty("Address") + "<br>");
out.println("公司 = " + pros2.getProperty("公司") + "<br>");
out.println("地址 = " + pros2.getProperty("地址") + "<br>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
运行结果如下:
4. HttpServletResponse对象
4.1 发送状态码相关的方法
setStatus(int status)
sendError(int sc)
sendError(int code?String message)
package cn.zxx.response.StatusServlet.java
package cn.zxx.response;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/StatusServlet")
public class StatusServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
response.sendError(404,"文件去火星了!!!");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
doGet(request, response);
}
}
运行结果如下:
4.2 发送响应头相关的方法
HttpServletResponse接口设置HTTP响应头字段的方法--设置各种头字段
方法说明 | 功能描述 |
---|---|
void addHeader(String name, String value) | 这两个方法都是用来设置HTTP协议的响应头字段,其中,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。不同的是,addHeader()方法可以增加同名的响应头字段,而setHeader()方法则会覆盖同名的头字段 |
void setHeader(String name, String value) | |
void addIntHeader(String name,int value) | 这两个方法专门用于设置包含整数值的响应头。避免了调用addHeader()与setHeader()方法时,需要将int类型的设置值转换为String类型的麻烦 |
void setIntHeader(String name,int value) | |
void setContentLength(int len) | 该方法用于设置响应消息的实体内容的大小,单位为字节。对于HTTP协议来说,这个方法就是设置Content-Length响应头字段的值 |
HttpServletResponse接口设置HTTP响应头字段的方法----设置字符编码
方法说明 | 功能描述 |
---|---|
void setContentType(String type) | 该方法用于设置Servlet输出内容的MIME类型,对于HTTP协议来说,就是设置Content-Type响应头字段的值。例如,如果发送到客户端的内容是jpeg格式的图像数据,就需要将响应头字段的类型设置为“image/jpeg”。需要注意的是,如果响应的内容为文本,setContentType()方法的还可以设置字符编码,如:text/html;charset=UTF-8 |
void setLocale(Locale loc) | 该方法用于设置响应消息的本地化信息。对HTTP来说,就是设置Content-Language响应头字段和Content-Type头字段中的字符集编码部分。需要注意的是,如果HTTP消息没有设置Content-Type头字段,setLocale()方法设置的字符集编码不会出现在HTTP消息的响应头中,如果调用setCharacterEncoding()或setContentType()方法指定了响应内容的字符集编码,setLocale()方法将不再具有指定字符集编码的功能 |
void setCharacterEncoding(String charset) | 该方法用于设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码部分。如果没有设置Content-Type头字段,setCharacterEncoding方法设置的字符集编码不会出现在HTTP消息的响应头中。setCharacterEncoding()方法比setContentType()和setLocale()方法的优先权高,setCharacterEncoding()方法的设置结果将覆盖setContentType()和setLocale()方法所设置的字符码表 |
cn.zxx.response.HeaderServlet.java
package cn.zxx.response;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/HeaderServlet")
public class HeaderServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
response.setStatus(1000) ;
response.setCharacterEncoding("utf8");
response.setContentType("text/html");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
doGet(request, response);
}
}
运行结果如下:
4.3 发送响应消息体相关的方法
cn.zxx.response.PrintServlet.java
package cn.zxx.response;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/PrintServlet")
public class PrintServlet extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse resp)throws ServletException, IOException {
String data = "jxpzhaojiang 张晓轩!";
// 获取字符输出流对象
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("out = resp.getWriter();out.write(...) (张晓轩)<hr>");
out.write(data);
}
public void doPost(HttpServletRequest req,
HttpServletResponse resp)throws ServletException, IOException {
doGet(req, resp);
}
}
运行结果如下:
cn.zxx.response.PrintServlet2.java
package cn.zxx.response;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
@WebServlet("/PrintServlet2")
public class PrintServlet2 extends HttpServlet {
public void doGet(HttpServletRequest req,
HttpServletResponse resp)throws ServletException, IOException {
String data = "jxpzhaojiang 张晓轩!";
resp.setContentType("text/html;charset=UTF-8");
resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
OutputStream out = resp.getOutputStream();
out.write("out = resp.getOutputStream();out.write(...) 字节流 (张晓轩)<hr>".getBytes(StandardCharsets.UTF_8));
out.write(data.getBytes(StandardCharsets.UTF_8));
}
}
运行结果如下:
cn.zxx.response.PrintServlet3.java 先保存图片 dzj.jpg 到 web/dzj.jpg
package cn.zxx.response;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
@WebServlet("/PrintServlet3")
public class PrintServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
// 设置响应的格式
response.setContentType("image/jpg");
//字节输入流
ServletContext context = this.getServletContext();
InputStream in = Files.newInputStream(Paths.get(context.getRealPath("/dzj.jpg")));;
//字节输出流
ServletOutputStream out = response.getOutputStream();
// 存储读取到的数据
int read = 0;
while ((read = in.read())!= -1){
// 将读取到的数据输出
out.write(read);
}
// 关闭流
out.close();
in.close();
}
}
运行结果如下:
5. HttpServletResponse对象
5.1 实现请求重定向
sendRedirect()方法的工作原理
login.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<!--把表单内容提交到ch04工程下的LoginServlet-->
<form action="LoginServlet" method="post">
<label>用户名: <input type="text" name="username" ></label><br>
<label>密 码:<input type="password" name="password"></label><br>
<input type="submit" value="登录">
</form>
</body>
</html>
welcome.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
欢迎你,登录成功!
</body>
</html>
cn.zxx.response.LoginServlet.java
package cn.zxx.response;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// 用HttpServletRequest对象的getParameter()方法获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 假设用户名和密码分别为:jxp和123
if ("jxp".equals(username) &&"123".equals(password)) {
// 如果用户名和密码正确,重定向到 welcome.html
response.sendRedirect("welcome.html");
} else {
// 如果用户名和密码错误,重定向到login.html
response.sendRedirect("login.html");
}
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
doGet(request, response);
}
}
运行结果如下:
5.2 动手实践:解决中文输出乱码问题
package cn.zxx.response;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/ChineseServlet0")
public class ChineseServlet0 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("中国");
}
}
package cn.zxx.response;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/ChineseServlet1")
public class ChineseServlet1 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
response.setCharacterEncoding("utf8");
PrintWriter out = response.getWriter();
out.println("中国");
}
}
package cn.zxx.response;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/ChineseServlet")
public class ChineseServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
// 设置request的字符编码
request.setCharacterEncoding("utf-8");
//设置response的字符编码和浏览器解析的内容类型
response.setContentType("text/html;charset=utf-8");
String data = "中国";
PrintWriter out = response.getWriter();
out.println(data);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
doGet(request, response);
}
}
6. HttpServletRequest对象
6.1 获取请求行信息的相关方法
HttpServletRequest接口获取请求行的相关方法
方法声明 | 功能描述 |
---|---|
String getMethod( ) | 该方法用于获取HTTP请求消息中的请求方式(如GET、POST等) |
String getRequestURI( ) | 该方法用于获取请求行中资源名称部分,即位于URL的主机和端口之后、参数部分之前的数据 |
String getQueryString( ) | 该方法用于获取请求行中的参数部分,也就是资源路径后面问号(?)以后的所有内容 |
String getProtocol( ) | 该方法用于获取请求行中的协议名和版本,例如HTTP/1.0或HTTP/1.1 |
String getContextPath( ) | 该方法用于获取请求URL中属于Web应用程序的路径,这个路径以“/”开头,表示相对于整个Web站点的根目录,路径结尾不含“/”。如果请求URL属于Web站点的根目录,那么返回结果为空字符串("") |
String getServletPath( ) | 该方法用于获取Servlet的名称或Servlet所映射的路径 |
String getRemoteAddr( ) | 该方法用于获取请求客户端的IP地址,其格式类似于“192.168.0.3” |
String getRemoteHost( ) | 该方法用于获取请求客户端的完整主机名,其格式类似于“pc1.itcast.cn”。需要注意的是,如果无法解析出客户机的完整主机名,该方法将会返回客户端的IP地址 |
int getRemotePort() | 该方法用于获取请求客户端网络连接的端口号 |
String getLocalAddr() | 该方法用于获取Web服务器上接收当前请求网络连接的IP地址 |
String getLocalName() | 该方法用于获取Web服务器上接收当前网络连接IP所对应的主机名 |
int getLocalPort() | 该方法用于获取Web服务器上接收当前网络连接的端口号 |
String getServerName() | 该方法用于获取当前请求所指向的主机名,即HTTP请求消息中Host头字段所对应的主机名部分 |
int getServerPort() | 该方法用于获取当前请求所连接的服务器端口号,即如果HTTP请求消息中Host头字段所对应的端口号部分 |
String getScheme() | 该方法用于获取请求的协议名,例如http、https或ftp |
StringBuffer getRequestURL() | 该方法用于获取客户端发出请求时的完整URL,包括协议、服务器名、端口号、资源路径等信息,但不包括后面的查询参数部分。注意,getRequestURL()方法返回的结果是StringBuffer类型,而不是String类型,这样更便于对结果进行修改 |
package cn.zxx.request;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/RequestLineServlet")
public class RequestLineServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 获取请求行的相关信息
out.println("获取请求行的相关信息(张晓轩)<hr>");
out.println("请求方法 getMethod : " + request.getMethod() + "<br>");
out.println("请求URI getRequestURI : " + request.getRequestURI() + "<br>");
out.println("查询串 getQueryString:" + request.getQueryString() + "<br>");
out.println("请求协议 getProtocol : " + request.getProtocol() + "<br>");
out.println("上下文路径 getContextPath:" + request.getContextPath() + "<br>");
out.println("额外路径信息 getPathInfo : " + request.getPathInfo() + "<br>");
out.println("额外路径信息对应资源的真实路径 getPathTranslated : " + request.getPathTranslated() + "<br>");
out.println("Servlet所映射的路径 getServletPath:" + request.getServletPath() + "<br>");
out.println("客户端ip地址 getRemoteAddr : " + request.getRemoteAddr() + "<br>");
out.println("客户端主机名 getRemoteHost : " + request.getRemoteHost() + "<br>");
out.println("客户端端口 getRemotePort : " + request.getRemotePort() + "<br>");
out.println("Web服务器端本地ip地址(局域网--内网) getLocalAddr : " + request.getLocalAddr() + "<br>");
out.println("Web服务器端本地主机名(局域网--内网) getLocalName : " + request.getLocalName() + "<br>");
out.println("Web服务器端本地端口(局域网--内网) getLocalPort : " + request.getLocalPort() + "<br>");
out.println("Web服务器公网主机名(互联网--公网) getServerName : " + request.getServerName() + "<br>");
out.println("Web服务器公网端口(互联网--公网) getServerPort : " + request.getServerPort() + "<br>");
out.println("请求协议 getScheme : " + request.getScheme() + "<br>");
out.println("请求URL getRequestURL : " + request.getRequestURL() + "<br>");
}
//getPathInfo 返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
//getPathTranslated //返回URL中的额外路径信息所对应的资源的真实路径。
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
doGet(request, response);
}
}
运行结果如下:
6.2 获取请求头的相关方法
方法声明 | 功能描述 |
---|---|
String getHeader(String name) | 该方法用于获取一个指定头字段的值,如果请求消息中没有包含指定的头字段,getHeader()方法返回null;如果请求消息中包含有多个指定名称的头字段,getHeader()方法返回其中第一个头字段的值 |
Enumeration getHeaders(String name) | 该方法返回一个Enumeration集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段值组成。在多数情况下,一个头字段名在请求消息中只出现一次,但有时候可能会出现多次 |
Enumeration getHeaderNames() | 该方法用于获取一个包含所有请求头字段的Enumeration对象 |
int getIntHeader(String name) | 该方法用于获取指定名称的头字段,并且将其值转为int类型。需要注意的是,如果指定名称的头字段不存在,返回值为-1;如果获取到的头字段的值不能转为int类型,将发生NumberFormatException异常 |
long getDateHeader(String name) | 该方法用于获取指定头字段的值,并将其按GMT时间格式转换成一个代表日期/时间的长整数,这个长整数是自1970年1月1日0点0分0秒算起的以毫秒为单位的时间值 |
String getContentType() | 该方法用于获取Content-Type头字段的值,结果为String类型 |
int getContentLength() | 该方法用于获取Content-Length头字段的值,结果为int类型 |
String getCharacterEncoding() | 该方法用于返回请求消息的实体部分的字符集编码,通常是从Content-Type头字段中进行提取,结果为String类型 |
package cn.zxx.request;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/RequestHeadersServlet")
public class RequestHeadersServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 获取请求消息中所有头字段
out.println("获取请求消息中所有头字段(张晓轩)<hr>");
Enumeration<String> headerNames = request.getHeaderNames();
// 使用循环遍历所有请求头,并通过getHeader()方法获取一个指定名称的头字段
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
out.print(headerName + " : "
+ request.getHeader(headerName) + "<br />");
}
}
}
运行结果如下:
6.3 请求转发
package cn.zxx.request;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/请求转发")
public class RequestForwardServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setAttribute("用户名", "张晓轩");// 将数据存储到request对象中
RequestDispatcher dispatcher =
request.getRequestDispatcher("/ResultServlet");
dispatcher.forward(request, response);
}
}
package cn.zxx.request;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ResultServlet")
public class ResultServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String username = (String) request.getAttribute("用户名");
if (username != null) {
out.println("用户名:" + username + "<br>");
}
}
}
运行结果如下:
6.4 获取请求参数
方法声明 | 功能描述 |
---|---|
String getParameter(String name) | 该方法用于获取某个指定名称的参数值,如果请求消息中没有包含指定名称的参数,getParameter()方法返回null;如果指定名称的参数存在但没有设置值,则返回一个空串;如果请求消息中包含有多个该指定名称的参数,getParameter()方法返回第一个出现的参数值 |
String[] getParameterValues(String name) | 该方法用于返回一个String类型的数组,HTTP请求消息中可以有多个相同名称的参数(通常由一个包含有多个同名的字段元素的form表单生成),如果要获得HTTP请求消息中的同一个参数名所对应的所有参数值,那么就应该使用getParameterValues()方法 |
Enumeration getParameterNames() | 该方法用于返回一个包含请求消息中所有参数名的Enumeration对象,在此基础上,可以对请求消息中的所有参数进行遍历处理 |
Map getParameterMap() | 该方法用于将请求消息中的所有参数名和值装入进一个Map对象中返回 |
form.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>获取请求参数</title>
</head>
<body>
<h2>获取请求参数 request.getParameter("input中name参数");</h2>
<hr>
<form action="RequestParamsServlet" method="POST">
<label>用户名:<input type="text" name="用户名"></label><br>
<label>密 码:<input type="password" name="密码"></label>
<br />
<label>爱好:
<input type="checkbox" name="hobby" value="唱歌">唱歌
<input type="checkbox" name="hobby" value="跳舞">跳舞
<input type="checkbox" name="hobby" value="足球">足球</label><br>
<input type="submit" value="提交">
</form>
</body>
</html>
package cn.zxx.request;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/RequestParamsServlet")
public class RequestParamsServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String name = request.getParameter("用户名");
String password = request.getParameter("密码");
System.out.println("用户名:" + name);
System.out.println("密 码:" + password);
// 获取参数名为“hobby”的值 String数组
String[] hobbys = request.getParameterValues("hobby");
System.out.print("爱好:");
for (String hobby : hobbys) {
System.out.print(hobby + ", ");
}
// 输出到浏览器端
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("1. 接收到的参数 request.getParameter | request.getParameterValues<hr>");
out.println("用户名:" + name);
out.println("<br>密 码:" + password);
out.println("<br>爱好:");
for (String hobby : hobbys) {
out.print(hobby + ", ");
}
//3.获取所有的参数名
System.out.println("\n所有的参数名 Enumeration<String> names = request.getParameterNames(): ");
Enumeration<String> names = request.getParameterNames() ;
while (names.hasMoreElements()){
String name2 = names.nextElement();
if ("hobby".equals(name2))
System.out.println(name2+" = "+ Arrays.toString(request.getParameterValues(name2)));
else
System.out.println(name2+" = "+request.getParameter(name2));
};
Enumeration<String> names2 = request.getParameterNames() ;
out.println("<br><br>2. 所有的参数名 Enumeration<String> names = request.getParameterNames(): <hr>");
while (names2.hasMoreElements()){
String name2 = names2.nextElement();
if ("hobby".equals(name2))
out.println(name2+" = "+ Arrays.toString(request.getParameterValues(name2))+"<br>");
else
out.println(name2+" = "+request.getParameter(name2)+"<br>");
};
// 4.获取参数名和参数值组成的map集合
out.println("<br> 3. 获取参数名和参数值组成的map集合 Map<String, String[]> parameterMap = request.getParameterMap()<hr>");
Map<String, String[]> parameterMap = request.getParameterMap();
Set<Map.Entry<String,String[]>> entries = parameterMap.entrySet();
Set<String> keySet = parameterMap.keySet();
for (String key : keySet) {
out.print("关键字 " + key + " = ");
//out.print("key:"+it.next()); 这个地方不能怎么写,往下看就知道了
//因为不能一次判断取两次值,可能会抛出NoSuchElementExcetion异常
String[] value = parameterMap.get(key);
for (String str : value) {
if(value.length == 1)
out.print(str);
else
out.print(str + ", ");
}
out.print("<br>");
}
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
运行结果如下:
6.5 通过Request对象传递数据
package cn.zxx.request;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Request传递数据")
public class RequestDemoServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
request.setAttribute("用户名", "张晓轩");// 将数据存储到request对象中
RequestDispatcher dispatcher = request.getRequestDispatcher("/Request传递数据1");
dispatcher.forward(request, response);
}
}
package cn.zxx.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Request传递数据1")
public class RequestDemoServlet1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String uname = (String) request.getAttribute("用户名");
response.getWriter().write("Request传递数据1:用户名="+uname);
}
}
运行结果如下:
package cn.zxx.request;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Request传递数据2")
public class RequestDemoServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
request.setAttribute("用户名", "张晓轩");// 将数据存储到request对象中
RequestDispatcher dispatcher = request.getRequestDispatcher("/Request传递数据3");
dispatcher.forward(request, response);
}
}
package cn.zxx.request;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
@WebServlet("/Request传递数据3")
public class RequestDemoServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
System.out.println("RequestDemoServlet3.java 执行:\n ------------------------------------------");
System.out.println("request.removeAttribute(\"用户名\")之前: "+request.getAttribute("用户名"));
request.removeAttribute("用户名");
System.out.println("request.removeAttribute(\"用户名\")之后: "+request.getAttribute("用户名"));
RequestDispatcher dispatcher = request.getRequestDispatcher("/Request传递数据4");
dispatcher.forward(request, response);
}
}
package cn.zxx.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Request传递数据4")
public class RequestDemoServlet4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String uname = (String) request.getAttribute("用户名");
response.getWriter().write("Request传递数据4:用户名="+uname);
}
}
运行结果如下:
6.6 动手实践:解决请求参数的中文乱码问题
//设置request对象的编码方式
request.setCharacterEncoding("utf-8");
//设置resp对象的编码方式
resp.setContentType("text/html; charset=utf-8");