文章目录
1. HTTP协议概述
-
概念:Hyper Text Transfer Protocol 超文本传输协议。HTML:Hyper Text Markup Language 超文本标签语言。它是一个应用层协议,运行在TCP协议之上。TCP是一个传输层协议。
-
作用:HTTP协议就是用来传输HTML的,我们的网页运行在HTTP协议之上。
-
默认端口号:80端口,Tomcat是8080。HTTPS协议443。是一个加了密的HTTP协议,安全性更高,效率要低一些。
-
特点:
- 由HTTP请求和HTTP响应组成
- 它是一种无状态的协议,它不记录用户的状态。如果服务器接收到了多个请求,服务器并不能通过HTTP协议知道这是一个用户的多次请求,还是来至于不同的用户。
- 因为它不记录用户的状态,所以传输效率比较高。
2. HTTP请求
2.1 什么是HTTP请求
用来封装浏览器发送给服务器的所有数据
2.2 查看HTTP请求(按F12打开开发者工具)
以Chrome浏览器为例
2.3 HTTP请求的组成
2.3.1 请求行
请求行 | 提交方式 | 请求的URI地址 | 协议(HTTP)和版本(1.1) |
---|---|---|---|
内容 | post方式 | /login | HTTP/1.1 |
请求方式get和post的区别
地址栏:get方式数据通过地址栏发送,post方式数据通过请求体发送
大小:get携带的数据有限,post携带的数据理论上没有限制
安全性:post不会暴露数据在地址栏上,所以安全性更高
缓存:get方法如果请求的内容不发生改变,会使用缓存。post方式不使用缓存
2.3.2 常见请求头
Referer: 得到上一个请求的地址,表示当前页面从哪个页面跳转过来的。
if-Modified-since: 浏览器缓存服务器网页的时间。
User-Agent: 得到客户端的操作系统类型和浏览器的类型
Connection: 当前TCP协议连接状态,两个取值:keep-alive表示连接,closed表示关闭。
Host:表示访问的服务器的名字和端口号。
2.3.3 请求体
如果是post方式提交,数据通过请求体提交。如果是get方式提交,则没有请求体。
3. Request请求对象
3.1 HttpServletRequest接口
Http请求在Java中代表请求对象,可以封装所有的请求数据。HttpServletRequest是一个接口,由第三方服务器厂商(如Tomcat)实现这个接口。
继承结构
3.2 获取请求行相关的方法
HttpServletRequest对象的方法 | 功能描述 |
---|---|
String getMethod() | 得到请求的方式(get或者post) |
String getRequestURI() | 得到URI(统一资源标识符) /资源名 |
StringBuffer getRequestURL() | 得到URL(统一资源定位符) /可以访问的地址 |
String getProtocol() | 得到协议和版本(http/1.1) |
String getContextPath() | 得到当前项目的访问路径 |
String getRemoteAddr() | 得到客户端的IP地址(IPV6) |
String getServletPath() | 得到当前Servlet的访问地址 |
代码演示
package com.zmysna.demo;
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(name = "Demo01RequestLineServlet",urlPatterns = "/demo1")
public class Demo01RequestLineServlet 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("method:"+ request.getMethod() + "<br>");
out.print("uri:"+ request.getRequestURI() + "<br>");
out.print("url:"+ request.getRequestURL() + "<br>");
out.print("protocol:"+ request.getProtocol() + "<br>");
out.print("ContextPath:"+ request.getContextPath() + "<br>");
out.print("RemoteAddr:"+ request.getRemoteAddr() + "<br>");
out.print("ServletPath:"+ request.getServletPath() + "<br>");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
开启Tomcat键入localhost:8080/demo1得到如下结果
3.3 获取请求头相关的方法
请求方法 | 功能描述 |
---|---|
String getHeader(String headName) | 得到指定的请求头的值 参数:键的名字 返回:响应请求头的 |
Enumeration getHeaderNames() | 得到所有的请求头键值对 返回:枚举类。 |
Enumeration中的方法
Enumeration接口中的方法 | 说明 |
---|---|
boolean hasMoreElements() | 如果有其他元素,返回tue |
E nextElement | 返回下一个元素 |
代码演示
package com.zmysna.demo;
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;
import java.util.Enumeration;
@WebServlet("/demo2")
public class Demo02RequestHeadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//根据名字打印请求头
out.print("<h2>根据名字打印请求头</h2>")
out.print("Referer:" + request.getHeader("Referer") + "<br>");
out.print("If-Modified-Since:" + request.getHeader("If-Modified-Since") + "<br>");
out.print("User-Agent:" + request.getHeader("User-Agent") + "<br>");
out.print("Connection:" + request.getHeader("Connection") + "<br>");
out.print("Host:" + request.getHeader("Host") + "<hr>");
//获得所有请求头的枚举类,遍历
out.print("<h2>获取请求头的枚举类并遍历</h2>")
Enumeration<String> headNames = request.getHeaderNames();
while (headNames.hasMoreElements()) {
String name = headNames.nextElement();
String value = request.getHeader(name);
out.print(name + ": " + value + "<br>");
}
}
}
结果
3.4 获取请求参数的方法
请求参数
- 通过form表单提交的参数数据,name属性值为参数名,value属性值为参数值。
- 在地址栏的访问地址填写参数数据:形式为
?参数名=参数值
方法 | 描述 |
---|---|
String getParameter(String name) | 通过参数名得到一项参数值 |
String[] getParameterValues(String name) | 通过参数名获取一组同名的值 用于获取复选框或者下拉列表的值 |
Enumeration getParameterNames() | 得到所有的参数名 |
Map<String,String[]> getParameterMap() | 得到表单所有的参数键和值,封装为Map对象 |
代码演示
前端页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>随便说点</title>
</head>
<body>
<h2>用户注册</h2>
<form action="demo5" method="post">
用户名: <input type="text" name="name"><br/>
性别: <input type="radio" name="gender" value="男" checked="checked"/>男
<input type="radio" name="gender" value="女"/>女 <br/>
城市:
<select name="city">
<option value="广州">广州</option>
<option value="深圳">深圳</option>
<option value="珠海">珠海</option>
</select>
<br/>
爱好:
<input type="checkbox" name="hobby" value="上网"/>上网
<input type="checkbox" name="hobby" value="上学"/>上学
<input type="checkbox" name="hobby" value="上车"/>上车
<input type="checkbox" name="hobby" value="上吊"/>上吊
<br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
Demo:获取请求头参数
package com.zmysna.demo;
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;
import java.util.Arrays;
@WebServlet("/demo3")
public class Demo03ParameterServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//获取参数并打印到页面
out.write("用户名:" + request.getParameter("name") + "<br>");
out.write("性别:" + request.getParameter("gender") + "<br>");
out.write("城市:" + Arrays.toString(request.getParameterValues("city")) + "<br>");
out.write("爱好:" + Arrays.toString(request.getParameterValues("hobby")) + "<br>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
结果
4. HTTP响应
4.1 什么是HTTP响应
HTTP响应是服务端响应客户端的请求,发送给客户端的所有数据。
HTTP响应的查看方式和HTTP请求的查看方式相同
4.2 响应信息的组成
4.2.1 响应行
响应行 | 协议(HTTP)和版本(1.1) | 状态码 | 状态信息 |
---|---|---|---|
内容 | HTTP/1.1 | 200 | OK |
常见的状态码
200 表示服务端将数据正确地响应给客户端。
302 表示页面是重定向的页面。
304 浏览器使用本地缓存,没有从服务器上获取。
404 表示找不到相应的请求地址。
405 表示服务端找不到doGet或者doPost方法
500 服务器内部错误,servlet代码有错误
4.2.2 常见的响应头
Location: www.baidu.com : 表示重定向到百度首页
Server:apache tomcat : 访问的服务器名字
Content-Encoding: gzip: 数据压缩格式,服务器指定压缩格式,客户端根据压缩格式对数据进行解压。
Content-Length: 响应数据的长度
Content-Type: text/html;charset=utf-8 :响应的数据类型和字符集
Refresh:1;url=/index.jsp:表示1秒之后,跳转到index.jsp页面
--------------------------------------------
Content-Disposition:attachment;filename=newboy.zip: (文件以附件形式下载)
Content-Disposition: 内容的处理方式
attcachment: 以附件的方式下载
filename: 下载时默认的文件名。如果文件名有汉字需要用URLEncode进行编码
5. Reponse响应对象
5.1 HttpServletResponse接口
Http响应在Java中代表响应对象,可以封装所有的请求数据。HttpServletResponse是一个接口,由第三方服务器厂商(如Tomcat)实现这个接口。
继承结构
5.2 设置响应行的方法
状态码的方法 | 描述 |
---|---|
setStatus(int status) | 设置状态码 |
response.sendRedirect(“重定向地址”)本质是设置302状态码并修改location的值。
代码演示
package com.zmysna.demo;
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;
/**
* 200 表示正确地从服务器中获得响应的数据
* 304 表示使用浏览器中的缓存
* 302 表示页面被重定向
* 404 表示页面不存在,服务器找不到相应的浏览器路径
* 405 表示服务器找不到doGet或者doPost方法。
* 500 表示服务器产生内部错误。
*/
@WebServlet("/demo1")
public class Demo01Status extends HttpServlet{
/**
* 302重定向
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("过几秒我要重定向");
Thread.sleep(2000);
//重定向到index页面
response.setStatus(302);
response.setHeader("location", "index.html");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
5.3 设置响应头的方法
响应头的方法 | 描述 |
---|---|
void setHeader(String name, String value) | 设置响应头,指定名字和值 |
void setContentType(String type) | 设置响应的内容类型 |
void setCharacterEncoding(String charset) | 设置响应的字符集和打印流的编码 |
案例:实现附件下载功能
效果(输入网址弹出下载页面,图片默认名为苹果手机.jpg
)
package com.zmysna.servlet;
import org.apache.commons.io.IOUtils;
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.net.URLEncoder;
@WebServlet(urlPatterns = "/downLoad")
public class DownLoadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置字符集
response.setContentType("image/jpg;charset=utf-8");
//用输入流读取WEB目录下的一张图片
ServletContext application = getServletContext();
InputStream in = application.getResourceAsStream("WEB-INF/e7e49ed2b25a6e9f (1).jpg");
//设置附件形式下载图片资源
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("苹果手机","utf-8")+".jpg");
//获取一个字节输出流将图片输出到页面
ServletOutputStream out = response.getOutputStream();
//IO流工具进行资源的传输(需要导入common.io包)
IOUtils.copy(in,out);
out.close();
in.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}