请求,响应。
http协议:为了更好去连接请求和响应。
协议介绍
学习目的:了解http协议的内容。
在request,请求,response 响应会涉及到协议的内容。
协议:双方的约定。
网络协议:计算机网络中进行数据交换而建立的规则、标准或约定等等。
http协议:超文本传输协议(HTTP,HyperTextTransfer Protocol)是互联网上应用最为广泛的一种网络协议。设计http的最初目的是为了提供一种发布和接受html页面的方法。
互联网数据交互一种规则。
http特点:
1、http协议是基于tcp协议的。属于应用层
2、默认端口是80(如果是80可以省略:80) 地址栏可以省略不写
3、基于请求响应模型。
请求:浏览器向服务器发送的信息,request
响应:服务器向浏览器发送的信息,response
请求和响应涉及到数据的发送。涉及到数据的格式。请求和响应的格式,满足http的规范。
查看http协议的内容方式:
ie:安装httpwatch
firefox(火狐):firebug可以查看
chrome(谷歌):自带
2. 请求格式
准备一个项目,供浏览器去请求。
准备一个页面,可以发送get或者post方式。
目的:知道浏览器把什么样的信息发送个服务器。
知道服务器把什么样的信息发送给浏览器。
2.1. 请求的组成说明
POST /day10/httpDemo HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Referer: http://localhost:8080/day10/http.html
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 13
Connection: Keep-Alive
Cache-Control: no-cache
username=aaaa
第一行是请求行
--- 请求方式 请求路径 请求协议以及版本
2.2. 请求行中的信息
POST /day10/httpDemo HTTP/1.1
post 表示 请求的方法,有post和get
/day10/httpServlet1 请求的路径
HTTP/1.1 http协议
http表名是http协议 /1.1 表示当前协议的版本。
1.1 和 1.0的区别
1.0 一次连接。一次请求。
1.1 一次连接多次请求
2.1. post和get区别----重要
2.2. 区分出那些是get请求,那些是post请求
1、区分出那些是post的请求,那些是get的请求
get:1、地址栏中直接输入。
2、<form method=”get”/>
3、超链接---<a href=””/>
post:学习到当前内容。<form method=”post”>
2、请求数据(用户自己输入的数据)的位置
get的请求数据在请求行中
GET /test/loginServlet?username=zhangsan&password=123456 HTTP/1.1
post的请求数据在请求体中
POST /test/loginServlet HTTP/1.1
username=zhangsan&password=123456
请求体的位置
http---请求的组成
请求行
请求头
空行
请求体
3、get的数据在url中,所以请求的数据有所限制,通常是1kb(不同的浏览器限制不同。)
2.3. 请求方法
2.4. 常见的http请求头中的参数说明
Accept: text/html,image/* 客户端识别文件类型
Accept-Charset: ISO-8859-1 客户端字符集
Accept-Encoding: gzip 客户端支持编码类型 gzip 压缩格式
Accept-Language:zh-cn 客户端语言
Host: www.itcast.com:80 访问服务器地址
If-Modified-Since: Tue, 11 Jul 200018:23:51 GMT和
Last-Modified 一起使用 控制缓存 (tomcat 提供缓存 过滤器 缓存处理)
Referer: http://www.itcast.com/index.jsp (重要) 防止盗链 获取网站域名地址
User-Agent: Mozilla/4.0 (compatible; MSIE5.5; Windows NT 5.0) 浏览器类型(文件下载时,不同浏览器进行不同处理) 不同的浏览器器存在兼容性!!
Connection: close/Keep-Alive 请求后连接是关闭还是保持
Date: Tue, 11 Jul 2000 18:23:51 GMT 请求时间
在http1.1版本之后,一次连接可以发送多个请求。
在http1.0的时候,一次连接一次请求。
2.5. 响应格式
2.5.2. 状态行
HTTP/1.1 200 OK
http/1.1 表示http协议以及版本
200 ok 状态码。 表示请求的状态。
2.5.3. 相应状态码
常见状态码:
200 - 请求成功
302 – 请求重定向 (response+302)==重定向
404 - 请求的资源(网页等)不存在 (请求的url找不到具体的资源,例如找不到servlet,或者html,如果遇到404的错误,通常检查url是否写错,或者url-patten 是否配置错。)
500 - 内部服务器错误(如果遇到500的情况,表示的是java代码出错误)
状态码分类:
详细状态码:
2.5.4. 常见的响应头信息参数说明
Location: http://www.it315.org/index.jsp // 通常告知浏览器 马上向该地址发送请求 通常 和 302 一起使用!!
(重点) 结合302完成重定向 操作 Location重定向后地址
Server:apache tomcat 服务器类型
Content-Encoding: gzip 响应编码类型 gzip压缩
Content-Length: 800 响应体的长度
Content-Language: zh-cn 响应语言
Content-Type: text/html; charset=GB2312 响应字符集 决定浏览器打开文件格式类型 以及编码
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT 和If-Modified-Since 一起使用,实现服务器缓存策略
Refresh: 3;url=http://www.it315.org (页面自动刷新)
1表示是的时间,秒
url 地址
到1秒后,页面刷新url
Content-Disposition: attachment; filename=aaa.zip 文件下载 告知浏览器 附件形式下载
2.5.5. 响应体:
服务器输出给浏览器显示的内容。
3. HttpServletResponse
HttpServletResponse对象是服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
HTTP/1.1 200 OK
Location: http://www.it315.org/index.jsp // 通常告知浏览器 马上向该地址发送请求 通常 和 302 一起使用!!
(重点) 结合302完成重定向 操作 Location重定向后地址
Server:apache tomcat 服务器类型
Content-Encoding: gzip 响应编码类型 gzip压缩
Content-Length: 800 响应长度
Content-Language: zh-cn 响应语言
Content-Type: text/html; charset=GB2312 响应字符集 决定浏览器打开文件格式类型 以及编码
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT 和If-Modified-Since 一起使用,实现服务器缓存策略
Refresh: 1;url=http://www.it315.org (页面自动刷新)
1表示是的时间,秒
url 地址
到1秒后,页面刷新url
Content-Disposition: attachment; filename=aaa.zip 文件下载 告知浏览器 附件形式下载
abc
response提供了方法(api) ,可以去设置相应信息(响应的状态行,响应头,响应体)
3.1. HttpServletResponse常用API---设置响应头和状态码
tomcat会调用servlet中的service方法。需要两个参数(httpServletRequest.httpServletRespons)
tomcat 会把请求的信息以及相应的信息。都封装到对象里么。然后通过service方法。传递给servlet。
在servlet中可以获取用户的请求信息,以及要发送给浏览器的相应信息。
setStatus 设置响应状态码
void setStatus(int sc)
Sets the status code for this response.
int sc 是状态码(200,302,404,500)
默认设置的是200.
setHeader 设置响应头信息
void setHeader(String name, String value)
Sets a response header with the given name and value.
name:表示 响应头中的key
value:相应头对应值
3.2. 案例之重定向
通过response实现请求重定向。
请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重
假设:day09是新的地址,day10是老地址。day10中去设置重定向的功能
定向
302+Location ------ 使用response.sendRedirect进行替代
代码实现
效果:
3.3. 设置响应体
---设置相应体的。(实际html(显示内容),下载文件,)
response 以流的形式 把内容输出给浏览器。
response .getWriter 获得响应体字符输出流,
response .getOutputStream 获得响应体字节输出流
通过这两个流,可以输出响应体。
注意问题:
1)、文件复制时 getOutputStream , 手动生成响应内容时 getWriter
手动设置相应体的内容
2)、getOutputStream和getWriter相互排斥不能同时使用
一个请求有一个响应。
一个响应 有一个输出流(通道), 如果你设置了字符流,就不能够在设置字节流(如果设置了两个流,会冲突)
3)、getOutputStream和getWriter生成响应体内容,不能改变状态行和头信息的
4)、tomcat服务器会自动调用response输出流 close方法,调用close时自动flush缓冲区内容。可以在写输出留的时候(不需要写close,fluse) tomcat会自动关闭。
注意:响应乱码解决:以后都采用setContentType(“text/html;charset=utf-8”)去设置字符集。setCharacterEncoding方式很少使用了。
建议使用utf-8,有的浏览器识别utf-8,但是不识别utf8.有一些浏览器两个都识别。
3.4. 响应乱码解决:
// 此时浏览器会采用系统默认的字符集去解析当前的html文件 gkb。设置了当前流的字符集。 但是没有告诉浏览器应该使用什么编码去解析当前的html
//response.setCharacterEncoding("gbk");
// response.setContentType("text/html");
// response.setHeader("Content-Type", "text/html;charset=utf-8");
// 直接去设置相应头信息中的Content-type.可以解决乱码问题。 可以告诉浏览器使用什么样的编码去解析我们html
// response.setContentType("text/html;charset=utf-8");
3.5. 自动刷新页面
举例:经常在网页中看到,页面的自动跳转,例如,点击一个页面的时候,提示您访问的页面不存在,3秒中后自动跳转到主页。
通过设置相应头中的refresh来实现页面的自动跳转。
refresh的格式 秒数;url=
举例:referes:3;url=/test/index.html 表示3秒钟后跳转到index.html
代码:
多学一招:利用mate标签实现同样的功能
<meta http-equiv="refresh"content="3;url=/test/index.html">
效果截图:
3.6. 生成图片验证码
/**
* 生成验证码Servlet
*/
package cn.yanqi.response;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 生成验证码Servlet
*
*
*/
public class CheckImgServlet extends HttpServlet {
/**
* 存放的要验证的中文字幕
*/
private List<String> words = new ArrayList<String>();
/**
* 当servlet被初始化的时候,调用
*/
@Override
public void init() throws ServletException {
// 读取成语文件内容
try {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(getServletContext().getRealPath("/WEB-INF/classes/new_words.txt")),"utf-8"));
String line;
while ((line = in.readLine()) != null) {
words.add(line);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 定义了图片的宽度,和高度。
*/
int width = 120;
int height = 30;
// 步骤一 绘制一张内存中图片
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 步骤二 图片绘制背景颜色 ---通过绘图对象
Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
// 绘制任何图形之前 都必须指定一个颜色
graphics.setColor(getRandColor(200, 250));
graphics.fillRect(0, 0, width, height);
// 步骤三 绘制边框
graphics.setColor(Color.WHITE);
graphics.drawRect(0, 0, width - 1, height - 1);
// 步骤四
Graphics2D graphics2d = (Graphics2D) graphics;
// 设置输出字体
graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
Random random = new Random();// 生成随机数
int index = random.nextInt(words.size());
// 生成一个随机数,从words list中,获取文字。(要验证的内容)
String checkcode = words.get(index);// 获得生成成员
// 定义x坐标
int x = 10;
for (int i = 0; i < checkcode.length(); i++) {
// 随机颜色
graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
// 旋转 -30 --- 30度
int jiaodu = random.nextInt(60) - 30;
// 换算弧度
double theta = jiaodu * Math.PI / 180;
// 获得字母数字
char c = checkcode.charAt(i);
// 将生成汉字 加入buffer
// 将c 输出到图片
graphics2d.rotate(theta, x, 20);
graphics2d.drawString(String.valueOf(c), x, 20);
graphics2d.rotate(-theta, x, 20);
x += 30;
}
// 将验证码内容保存session
request.getSession().setAttribute("checkcode_session", checkcode);
// 步骤五 绘制干扰线
graphics.setColor(getRandColor(160, 200));
int x1;
int x2;
int y1;
int y2;
for (int i = 0; i < 30; i++) {
x1 = random.nextInt(width);
x2 = random.nextInt(12);
y1 = random.nextInt(height);
y2 = random.nextInt(12);
graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
}
// 将上面图片输出到浏览器 ImageIO
graphics.dispose();// 释放资源
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* 取其某一范围的color
*
* @param fc
* int 范围参数1
* @param bc
* int 范围参数2
* @return Color
*/
private Color getRandColor(int fc, int bc) {
// 取其随机颜色
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
}
Web.xml配置访问路径
Test.jsp
4. HttpServletRequest
请求:浏览器给服务器发送的信息,会被服务器封装到httpServletRequest,中HttpServletRequest由服务器创建好,调用servlet中的service方法的时候把httpServletRequset传递到servlet中。
4.1. 常用api
api介绍:
1、获取请求行中的信息
2、获取请求头中的的信息
3、获取请求的参数信息(获取表单提交过来的数据)
4.1.1. 获取请求行的信息
请求方法:getMethod 可以得到 请求的方法。请求方式,post,get
getMethod |
请求url
getRequestURI | |
getRequestURL |
uri:统一资源标识符,用来唯一标识一个资源,资源路径
url:统一资源定位符,是一种具体的URI,可以用来标识一个资源。并且指明了如何定位一个资源。
uri的表示范围>url。url是一种特殊的uri 。url相当于uri的子类
协议
获取客户端的ip地址
public StringgetRemoteAddr()
获取客户端的ip地址。
代码片段:
4.1.2. 获得请头中的api---了解
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive
getHeader(name)方法 --- String ,通过头信息中key,获取请求的内容。
getHeaders(String name)方法 ---返回值:枚举类型的结合 Enumeration<String>
getHeaderNames方法 --- Enumeration<String>,返回的内容是请求头中的key的集合。
getIntHead(name)方法 --- int,如果请求头的信息是整形的,可以通过getIntHead(),获取
getDateHead(name)方法 --- long(日期对应毫秒)
代码:
获取请求参数
请求参数,用户提交的数据。
请求的参数传递方式。
key=value&key=value&key=value
username=123&password=123&sex=男&hobby=LoL&hobby=吃饭&hobby=睡觉
*request.getParameter("key");获取请求体内容
public String getParameter(String name)
以 String
形式返回请求参数的值,如果该参数不存在,则返回 null
。请求参数是与请求一起发送的额外信息(表单的内容)。
*request.getParameterValues("key");获取请求体内容(多个内容)
public String[] getParameterValues(Stringname)
返回包含给定请求参数拥有的所有值的 String
对象数组,如果该参数不存在,则返回 null
。
checkbox 复选框。name 会对应多个value。把这些value放到字符串数组中();
*request.getParameterMap();获取请求体内容,获取所有请求体内容,自动封装 Map<String,String[]>
doGet方法
doPost方法:
4.1. 请求乱码解决
4.1.1. get请求乱码:
get方式请求,请求的参数在url中。
url实际不能够包含中文。uriEecode()把中文进行编码在传输。编码的格式utf-8
get请求乱码解决方案:
方法1,把编码的过程逆转解决乱码。
username = URLEncoder.encode(username,"iso-8859-1");
username = URLDecoder.decode(username,"utf-8");
或者:newString(username.getBytes("iso-8859-1"), "utf-8")
表单是get请求解决乱码问题
//GET请求乱码、tomcat默认的编码是iso-8859-1,然后对getBytes进行编写utf-8
String username = request.getParameter("username");
String name = newString(username.getBytes("iso-8859-1"),"UTF-8");
System.out.println("转过来的"+name); 效果跟上面的一样
方法2:更改字符集的
配置tomcat的默认解码字符集
在conf/server.xml.
<Connectorport="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"URIEncoding="utf-8"/>
方法不是很常用。修改tomcat中server.xml。
会很死板。
如果一个tomcat部署2个项目,
1个utf-8
1个是gbk;
4.1.2. post请求乱码的解决方案
request,提供setCharacterEncoding(); 在获取参数之前设置字符集。
public void setCharacterEncoding(Stringenv)
重写此请求正文中使用的字符编码的名称。必须在使用 getReader() 读取请求参数或读取输入之前调用此方法。否则,此方法没有任何效果
4.2. 案例:serlvet获取注册页面的内容
写一个注册页面,在servlet中,获取用户注册信息
4.2.1. doget代码:
4.2.2. doPost代码:
4.1. 转发传递数据
public RequestDispatchergetRequestDispatcher(String path)
返回一个 RequestDispatcher
对象,它充当位于给定路径上的资源的包装器。可以使用RequestDispatcher
对象将请求转发给资源,或者在响应中包含资源。资源可以是动态的,也可以是静态的。
4.2. 转发和重定向的区别
5. 整理