带你吃透Servlet核心编程下篇(完整图文教程)
本文被 系统学习JavaWeb 收录点击订阅专栏
文章目录
- 1 Http协议
- 1.1 什么是 HTTP 协议
- 1.2 GET请求与POST请求
- 1.3 响应的HTTP协议格式
- 1.4 MIME数据类型
- 2 HttpServletRequest类
- 2.1 HttpServletRequest说明及常用方法
- 2.2 HttpServletRequest类演示
- 2.3 获取请求表单中的参数值(POST请求)
- 2.4 解决post请求中的中文乱码问题
- 3 请求转发
- 4 HttpServletResponse类
- 4.1 两个输出流
- 4.2 如何回传客户端数据
- 5 请求重定向
- 5.1 什么是请求重定向
- 5.2 请求重定向演示
- 写在最后
1 Http协议
1.1 什么是 HTTP 协议
协议是双方或者多方约定好需要遵守的规则。所谓HTTP协议就是指,在客户端和服务端通信时,发送的数据,需要遵守的规则。HTTP协议中的数据称为报文。
客户端给服务器发送数据叫请求,而服务器给客户端回传数据叫响应。
请求分为GET请求和POST请求。
1.2 GET请求与POST请求
GET请求的组成如下:
- 请求行
(1)请求的方式 GET
(2)请求的资源路径 [+?+请求参数]
(3)请求的协议版本号 HTTP/1.1 - 请求头
key:value 组成,不同的键值对,表示不同的含义。
GET请求HTTP协议内容示例:
常用请求头的说明:
- Accept: 告诉服务器,客户端可以接收的数据类型;
- Accept-Language: 告诉服务器客户端而言接收的语言类型;
- User-Agent: 浏览器的信息;
- Accept-Encoding: 告诉服务器,客户端可以接收的数据编码(压缩)格式;
- Host: 表示请求的服务器ip和端口号;
- Connection: 告诉服务器请求连接如何处理
Keep-Alive:服务器马上回传数据,不要马上关闭,保持一小会儿的连接
Closed: 马上关闭
POST请求的组成如下:
- 请求行
(1)请求的方式 GET
(2)请求的资源路径 [+?+请求参数]
(3)请求的协议版本号 HTTP/1.1 - 请求头
key:value 组成,不同的请求头,表示不同的含义。 - 请求体:发送给服务器的数据
辨析哪些是GET请求,哪些是POST请求
常用的GET请求:
- form标签 method=get
- a 标签
- link标签引入css
- Script标签引入js文件
- img标签引入图片
- iframe引入html页面
- 在浏览器地址栏输入地址后敲回车
常用的POST请求:
- form标签 method=post
1.3 响应的HTTP协议格式
响应的HTTP协议格式组成如下:
- 响应行
(1)响应的协议和版本号
(2)响应状态码
(3)响应状态码描述符 - 响应头
key:value 组成,不同的响应头,表示不同的含义。 - 响应体:回传给客户端的数据、
示例图如下:
常用的响应码:
响应码 | 说明 |
---|---|
200 | 表示请求成功 |
302 | 表示请求重定向 |
404 | 表示请求服务器已经收到,但是需要访问的数据不存在 |
500 | 表示服务器已经收到请求,但是服务器内部错误 |
1.4 MIME数据类型
MIME是HTTP协议中的数据类型。全称是"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务,MIME类型的格式是"大类型/小类型",并与某一种文件的扩展名相对应。
常见的MIME类型:
2 HttpServletRequest类
2.1 HttpServletRequest说明及常用方法
每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(doGet、doPost)中供我们使用。我们可以通过HttpServletRequest对象获取到所有请求的信息。
HttpServletRequest类常用方法
方法 | 说明 |
---|---|
getRequestURL() | 获取请求的资源路径 |
getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
getRemoteHost() | 获取客户端的ip地址 |
getHeader() | 获取请求头 |
getParameter() | 获取请求的参数 |
getParamterValues() | 获取请求的参数(多个值使用) |
getMethod() | 获取请求的方式POST或GET |
setAttribute(key,value) | 设置域数据 |
getAttribute(key) | 获取域数据 |
getRequestDispatcher() | 获取请求转发对象 |
2.2 HttpServletRequest类演示
xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>RequestAPIServelet</servlet-name>
<servlet-class>com.example.servlet_test.RequestAPIServelet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestAPIServelet</servlet-name>
<url-pattern>/requestAPIServlet</url-pattern>
</servlet-mapping>
</web-app>
RequestAPIServelet.java
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 兴趣使然黄小黄
* @version 1.0
*/
public class RequestAPIServelet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取请求的资源路径
System.out.println("URL = " + req.getRequestURI());
//2. 获取绝对路径(返回值是StringBuffer)
System.out.println("URL = " + req.getRequestURL());
//3. 获取客户端的ip地址
/*
* 在IDEA中,使用LocalHost访问时,得到的客户端的ip地址时127.0.0.1
* IPV6表现形式则为0:0:0:0:0:0:0:1
*/
System.out.println("ip = " + req.getRemoteHost());
//4. 获取请求头
System.out.println("请求头User-Agent = " + req.getHeader("User-Agent"));
//5. 获取请求方式
System.out.println("请求方式 = " + req.getMethod());
}
}
2.3 获取请求表单中的参数值(POST请求)
下面演示如何获取表单的信息,以Post请求方式为例
xml配置文件信息:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>ServletRequest</servlet-name>
<servlet-class>com.example.servlet_test.ServletRequest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletRequest</servlet-name>
<url-pattern>/servletRequest</url-pattern>
</servlet-mapping>
</web-app>
html页面信息如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/Servlet_Test/servletRequest" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="python">Python
<input type="checkbox" name="hobby" value="C++">C++
<input type="submit">
</form>
</body>
</html>
获取请求参数的方法都写在了ServletRequest类中
ServletRequest.java:
package com.example.servlet_test;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
/**
* @author 兴趣使然黄小黄
* @version 1.0
* 读取表单数据
*/
public class ServletRequest extends HttpServlet {
@Override
protected void doPost(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));
}
}
2.4 解决post请求中的中文乱码问题
还是刚刚的例子,表单中的内容如下图(用户名用中文):
提交后,控制台获取的参数信息如下;
用户名中文出现了乱码!如何解决?
只需要在获取参数前设置编码格式为utf-8即可
req.setCharacterEncoding(“UTF-8”):设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题。
3 请求转发
何为请求转发?
请求转发是指当服务器接收到请求后,从一个资源跳转到另一个资源的操作。
请求转发的特点如下:
- 浏览器地址不会变化
- 仅仅是一次请求
- 可以共享Request域的数据
- 可以转发到 WEB-INF 目录(一般情况无法访问,可以通过请求转发访问)
- 不可以访问到工程以外的资源
示例代码如下:(xml配置文件略,可以自己参考类名去配置)
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 = " + username);
//给材料盖章,传递到servlet2查看
req.setAttribute("key1", "柜台1的章");
//问路:servlet2怎么走
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
//走向Servlet2
requestDispatcher.forward(req, resp);
}
}
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求参数
String username = req.getParameter("username");
System.out.println("servlet2中 username = " + username);
//查看柜台1是否有章
Object key1 = req.getAttribute("key1");
System.out.println("柜台1是否有章 " + key1);
//处理自己的业务
System.out.println("柜台二处理中");
}
}
4 HttpServletResponse类
HttpServletResponse类与HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序使用。HttpServletRequest表示所有请求过来的信息,而HttpServletResponse表示所有相应的信息。
如果我们希望设置返回给客户端的信息,则可以通过HttpServletResponse对象来进行设置。
4.1 两个输出流
流 | 名 | 使用场景 |
---|---|---|
字节流 | getOutputStream() | 常用于下载(传递二进制数据) |
字符流 | getWriter() | 常用于回传字符串 |
两个流只能同时使用一个
4.2 如何回传客户端数据
往客户端回传字符串数据
案例代码如下:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author 兴趣使然黄小黄
* @version 1.0
*/
public class ResponseIO extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("response's content!!!");
}
}
同样,该案例中也存在响应的中文乱码问题
与post请求的中文乱码问题不同的是,不能仅仅设置服务端的编码格式,还需要将浏览器默认解析的编码格式统一!
代码如下:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author 兴趣使然黄小黄
* @version 1.0
*/
public class ResponseIO extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置服务器的字符集
resp.setCharacterEncoding("UTF-8");
//通过响应头,设置浏览器的字符集
resp.setHeader("Content-Type", "text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("这是一段中文!");
}
}
也可以在获取流对象前,通过一个方法同时设置服务端和客户端的编码集:
resp.setContentType("text/html;charset=UTF-8");
5 请求重定向
5.1 什么是请求重定向
请求重定向是指客户端给服务端发请求,然后服务器给客户端提供了一个新的地址去访问。可以简单理解为:呼叫转移~
需要注意请求重定向与请求转发的区别!
请求重定向的特点如下:
- 不共享Request域的数据
- 两次请求
- 浏览器地址栏会发生变化
- 不能访问到WEB-INF目录下的资源
- 可以访问到工程外的资源
5.2 请求重定向演示
Response1.java
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 兴趣使然黄小黄
* @version 1.0
* 演示请求重定向
*/
public class Response1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("----------Response1---------");
//设置状态码302 表示重定向
resp.setStatus(302);
resp.setHeader("Location", "http://localhost:8080/Servlet_Test/response2");
}
}
Response2.java
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 兴趣使然黄小黄
* @version 1.0
* 演示请求重定向
*/
public class Response2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("----------Response2---------");
resp.getWriter().write("response2");
}
}
补充
请求重定向也有一种简便的实现方式:
resp.sendRedirect("http://xxxx/xxx/xxx...");
写在最后
本文部分内容参考:尚硅谷JavaWeb课程。好了,本文内容到这里就告一段落了,欢迎大家订阅专栏,加入JavaWeb学习!点击订阅
如果你有任何问题,欢迎私信,感谢您的支持!