本栏博客目录

​Serlvet笔记一(Servlet基础)​​​ Servlet笔记二(请求和响应)
​Servlet笔记三(会话及其会话技术)​​​​Servlet笔记四(JSP技术)​​​​Servlet笔记五(EL表达式和JSTL)​​​​Servlet笔记六(Servlet 高级)​​​​Servlet笔记七(JDBC)​​​​Servlet笔记八(数据库连接池与DBUtils工具)​​​​Servlet笔记九(JSP 开发模型)​​​​Servlet笔记十(文件上传和下载)​


文章目录




在Web服务器运行阶段,每个Servlet都只会创建一个实例对象,而每次 Http 请求,Web 服务器都会调用所请求 Servlet 实例的 service(HttpServletRequest request, HttpServletResponse response)方法,重新创建一个request对象和一个response 对象。

HttpServletResponse对象

HttpServletResponse接口继承自 ServletResponse 接口,专门用来封装Http响应消息。HttpServletResponse接口定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。

发送状态码相关的方法

setStatus(int status)
该方法用于设置HTTP响应消息的状态码,并生成响应状态行。(如:200)

sendError(int sc)
该方法用于发送表示错误信息的状态码。(如:404)


设置响应消息头字段的方法

// 设置HTTP协议的响应头字段
void addHeader(String name, String value)
void setHeader(String name, String value)
// 设置包含整数值的响应头
void addIntHeader(String name, int value)
void setIntHeader(String name, int value)
// 设置响应消息的实体内容的大小,单位为字节
void setContentLength(int len)
// 设置Servlet输出内容的MIME类型(Content-Type响应头字段)
void setContentType(String value)
// 设置响应消息的本地化信息(Content-Language;Content-Type字符集编码部分)
void setLocale(Locale loc)
// 设置输出内容使用的字符编码(Content-Type),比前两个方法优先级高
void setCharacterEncoding(String charset)

发送响应消息体相关的方法

getOutputStream()方法

该方法所获取的字节输出流对象为ServletOutputStream类型,可以直接输出字节数组中的二进制数据。

getWriter()方法

该方法所获取的字符输出流对象为PrintWriter类型,可以直接输出字符文本内容。

String data = "sx";
OutputStream out = response.getOutputStream();
out.write(data.getBytes()); // 输出信息

实现网页定时刷新并跳转

// 2秒后刷新并跳转到百度页面
response.setHeader("Refresh", "2;URL=https://www.baidu.com");
// 每隔3秒定时刷新当前页面
response.setHeader("Refresh", "3");
// 输出当前时间
response.getWriter().println(new java.util.Date());

重定向

重定向是指Web服务器接收到客户端请求后,可能由于某些限制条件限制,不能访问当前请求URL所指向的Web资源,而是指定可一个新的资源路径,让客户端重新发送请求

HttpServletResponse的 sendRedirect() 方法可以实现重定向。

response.sendRedirect("/login.html");

HttpServletRequest对象

在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法。

获取请求行信息的相关方法

// 获取HTTP请求消息中的请求方式
String getMethod()
// 获取请求行中资源名称部分(URL的主机和端口之后、参数部分之前的部分)
String getRequestURI()
// 获取请求行中的参数部分(资源路径后面 问号(?) 以后的所有内容)
String getQueryString()
// 获取请求行中的协议名和版本 如:Http/1.1
String getProtocol()
// 获取请求URL中属于Web应用程序的路径(以 "/" 开头)
String getContextPath()
// 获取Servlet的名称或Servlet所映射的路径
String getServletPath()
// 获取请求客户端的IP地址
String getRemoteAddr()
// 获取请求客户端的完整的主机名
String getRemoteHost()
// 获取请求客户端网络链接的端口号
int getRemotePort()
// 获取Web服务器上接收当前请求网络连接的IP地址
String getLocalAddr()
// 获取Web服务器上接收当前网络连接IP所对应的主机名
String getLocalName()
// 获取Web服务器上接收当前网络连接的端口号
int getLocalPort()
// 获取当前请求所指向的主机名(HTTP请求消息重Host头字段所对应的主机名部分)
String getServerName()
// 获取当前请求所连接的服务器端口号(HTTP请求消息重Host头字段所对应的端口号部分)
int getServerPort()
// 获取请求的协议名(http、https、ftp)
String getScheme()
// 获取客户端发送请求时的完整URL,包括协议、服务器名、端口号、资源路径等(不包括后面的查询参数部分)
StringBuffer getRequestUrl()

获取请求消息头的相关方法

// 获取一个指定头字段的值
String getHeader(String name)
// 返回请求消息中出现的某个指定名称的所有头字段值的集合
Enumeration getHeaders(String name)
// 获取一个包含所有请求头字段的Enumeration对象
Enumeration getHeaderNames()
// 获取指定名称的头字段,并将其值转为int类型
int getIntHeader(String name)
// 获取指定头字段的值,并按GMT格式转换成代表 日期/时间 的长整数
long getDateHeader(String name)
// 获取Content-Type头字段的值
String getContentType()
// 获取Content-Length头字段的值
int getContentLength()
// 返回请求消息的实体部分的字符集编码(从Content-Type头字段中进行提取)
String getCharacterEncoding()

获取请求参数

获取 表单 中的请求参数

// 获取某个指定名称的参数值
String getParameter(String name)
// 获取Http请求消息中的同一个参数名对应的所有参数值
String[] getParamterValues(String name)
// 返回一个包含请求中所有参数名的Enumeration对象
Enumeration getParameterNames()
// 将请求消息中的所有参数名和值装进一个Map对象中返回
Map getParameterMap()

解决请求参数的中文乱码问题

在HttpServletRequest接口中提供了一个setCharacterEncoding()方法,该方法用于设置request对象的解码方式

request.setCharacterEncoding("utf-8");

上述方法只对POST请求有效

而对于get请求,需要在适当位置添加如下一行代码:

name = new String(name.getBytes("iso8859-1"), "utf-8");

通过Request对象传递数据

Request 对象不仅可以获取一系列数据,还可以通过属性传递数据。

  • setAttribute() 方法

用于将一个对象与一个名称关联后存储进ServletRequest对象中

void setAttribute(String name, Object o)
  • getAttribute() 方法

该方法用于从ServletRequest对象中返回指定名称的属性对象

Object getAttribute(String name)
  • removeAttribute() 方法

该方法用于从ServletRequest对象中删除指定名称的属性

void removeAttribute(String name)
  • getAttributeNames() 方法

该方法用于返回一个包含 ServletRequest 对象中所有属性名的Enumeration对象

Enumeration getAttributeNames()

RequestDispatcher

当一个Web资源收到客户端的请求后,如果希望服务器通知另外一个资源去处理请求,这时,除了使用 sendRedirect() 方法实现请求重定向外,还可以通过RequestDispatcher接口的实例对象来实现 。

获取RequestDispatcher对象的方法

返回封装了某个路径所指定资源的 RequestDispatcher 对象,其中,参数 path 必须以 “/” 开头,用于表示当前Web应用的根目录,并且WEB-INF 目录中的内容对 RequestDispatcher 对象也是可见的,因此,传递给getRequestDispatcher(String path) 方法的资源可以是 WEB-INF 目录中的文件。

RequestDispatcher getRequestDispatcher(String path)

RequestDispatcher接口的方法

请求转发与请求包含

// 用于将请求从一个 Servlet 传递给另外的一个 Web 资源(将请求传递给其他资源进行响应)
forward(ServletRequest request, ServletResponse response)
// 该方法用于将其他的资源作为当前响应内容包含进来
include(ServletRequest request, ServletResponse response)

应用实例

request 对象方法应用

​请求体​

@WebServlet(name = "method", value = "/req")
public class RequestGetMethodServlet extends HttpServlet {

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");

PrintWriter out = resp.getWriter();

out.println("getMethod :" + req.getMethod() +"<br />");
out.println("getRequestURI :" + req.getRequestURI() +"<br />");
out.println("getServerName :" + req.getServerName() +"<br />");
out.println("getServletPath :" + req.getServletPath() +"<br />");

}
}

​show​​​Servlet笔记二(请求和响应)_response

​请求头​

@WebServlet(value = "/he")
public class RequestHeaderServlet extends HttpServlet {

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");

PrintWriter out = resp.getWriter();

Enumeration<String> names = req.getHeaderNames();

while(names.hasMoreElements()){

out.println(req.getHeader(names.nextElement()) + "<br />");
}

}
}

​show​

Servlet笔记二(请求和响应)_response_02

referer字段

@WebServlet(value = "/download")
public class DownloadManagerServlet extends HttpServlet {

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");

PrintWriter out = resp.getWriter();

String referer = req.getHeader("referer");

String sitePath = "http://" + req.getServerName();

if(referer != null && referer.startsWith(sitePath)){
out.println("正常访问,可以下载数据");
}else{
RequestDispatcher rd = req.getRequestDispatcher("/regist.html");
rd.forward(req, resp);
}

}
}

​index.html​​中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/download">下载音乐</a>
</body>
</html>

​regist.html​

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>请登录后再访问页面</div>
</body>
</html>

​show​

Servlet笔记二(请求和响应)_request_03

点击下载音乐后

Servlet笔记二(请求和响应)_http_04

直接访问此路径

Servlet笔记二(请求和响应)_request_05

获取请求参数

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");

PrintWriter out = resp.getWriter();

String name = req.getParameter("username");
String pass = req.getParameter("userpass");

String[] hobby = req.getParameterValues("hobby");
out.println("用户名:" + name + " 登录密码:" + pass+"<br/>");
System.out.println("用户名:" + name + " 登录密码:" + pass+"<br/>");
out.println("爱好:<br/>");
for (int i = 0; i < hobby.length; i++) {
out.println(hobby[i]);
}
}
}

​login.html​

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<div style="width: 400px; height: 300px; background-color: #cad; margin: auto'">
<form action="/login" method="get">
<table>
<tr><td><label>登录名称:</label><input type="text" name="username"></td></tr>
<tr><td><label>登录密码:</label><input type="password" name="userpass"></td></tr>
<tr><td><label>爱好</label></td></tr>
<td>
<input type="checkbox" name="hobby" value="read"> 读书
<input type="checkbox" name="hobby" value="music"> 音乐
</td>
<tr><td><input type="submit" value="提交"></td></tr>
</table>
</form>
</div>
</body>
</html>

​show​

Servlet笔记二(请求和响应)_java_06

Servlet笔记二(请求和响应)_http_07

RequestDispatcher应用

​forward​

@WebServlet("/forward")
public class ForWardServlet extends HttpServlet {

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");
req.setAttribute("name", "LanZhou");
RequestDispatcher dispatcher = req.getRequestDispatcher("/result");
dispatcher.forward(req, resp);
}
}
@WebServlet("/result")
public class ResultServlet extends HttpServlet {

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");

PrintWriter out = resp.getWriter();
String name = (String)req.getAttribute("name");

if(name!=null){
out.println("name=" + name);
}
}
}

​show​​​​访问 "/forward"​Servlet笔记二(请求和响应)_servlet_08
​访问 "/result"​

Servlet笔记二(请求和响应)_response_09

原因:在 “/forward” 对应的servlet中向request对象添加了name 属性字段,而直接访问 “/result” 并没有添加 name 属性字段。

​include​

@WebServlet("/included")
public class IncludedServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
out.println("兰州交通大学" + "<br/>");
out.println("URI=" + req.getRequestURI() + "<br/>");
out.println("Query=" + req.getQueryString()+"<br/>");
out.println("pl=" + req.getParameter("pl")+"<br/>");
}
}
@WebServlet("/including")
public class IncludingServlet extends HttpServlet {

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();

RequestDispatcher rd = req.getRequestDispatcher("/included?pl=abc");
out.println("before including" + "<br/>");
rd.include(req,resp);
out.println("after including" + "<br/>");
}
}

​show​

​访问 "/including?name=hpp"​

Servlet笔记二(请求和响应)_response_10