Request&Response详解

01_响应对象的概述&向客户端发送数据

WEB服务器会针对每一个客户端发出的HTTP请求,分别的创建一个请求对象和一个响应对象
如果需要获取客户端提交的数据,需要使用请求对象
如果需要向客户端发送一些数据,需要使用响应对象
响应 : 响应行 响应头 响应正文 
  1XX:浏览器发送的请求信息不完善,需要浏览器进一步补充资料
  2XX:响应正常完成
  3XX:本次请求已经完成,但是需要浏览器进行进一步操作  302
  4XX:请求的资源错误
  5XX:服务器端错误
注意:
这两个流互相排斥,在一个Servlet中只能使用其中的一个,如果有字符输出流则不能有字节输出流,否则会出现

02_字节流向客户端发送中文的乱码处理

编码:
二进制   A 65  a 97   汉字
ASCII 美国标准信息码(128字符)
ISO-8859-1 -16 一共有15编码 13
//GB2312 2个字节表示一个字符 6700+
GBK   2个字节表示一个字符  18000+ 国家强制标准 
Unicode 万国码   2个字节表示一个字符
UTF-8 用1-6个字节来表示一个字符
ANSI 本地平台默认
     中文版window GBK
英文版的window UTF-8
原因:
乱码的出现是因为前后编码不一致,发送数据的编码,接收数据的编码
服务器发送数据:ISO-8859-1
浏览器接收数据:GBK
解决方法一:
将服务器发送数据格式改为GBK
OutputStream os = response.getOutputStream();
os.write("黑马程序员".getBytes());//默认GBK
解决方法二
//设置响应头,告诉浏览器你应该使用什么编码
response.setHeader("Content-type", "text/html;charset=UTF-8");
os.write("黑马程序员".getBytes("UTF-8"))

03_字符流向客户端发送中文的乱码处理

原因
服务器发送数据:ISO-8859-1 -> GBK
浏览器接收数据:GBK
解决方法一:
response.setCharacterEncoding("GBK");//设置编码的格式,也就是设置服务器发送数据的格式
如果服务器发送的是UTF-8
response.setCharacterEncoding("UTF-8");//服务器
response.setContentType("text/html;charset=UTF-8");//告诉浏览器采用什么方式进行解码
推荐方案
response.setContentType("text/html;charset=UTF-8");//告诉浏览器采用什么方式进行解码

04_响应头Refresh

定时自动刷新
response.setHeader("Refresh", "3");
定时自动跳转
response.setHeader("Refresh", "3;URL=http://www.itcast.cn");    //跳转外部资源
response.setHeader("Refresh", "3;URL=/myResponse/ResponseDemo");//跳转内部资源
转发和跳转的区别
转发:共享请求和响应对象,跳转:不共享
转发:只能是内部地址,跳转:内部地址和外部地址都可以
转发:地址栏不会发生变化,跳转:地址栏会发生变化

05_请求重定向

概念:一个WEB资源接收到客户端的请求之后,通知这个客户端去访问(请求)另外的一个WEB资源
重定向和转发的区别
请求次数
重定向发出两次请求
转发只发出一次请求,共享请求对象和响应对象
访问的路径
重定向可以访问内部的路径,也可以访问外部的路径
转发只能访问内部的路径
地址栏
重定向的地址栏发生变化
转发地址栏不会变化
原理:设置location响应头,同时还需要设置一个响应码(状态码),302/307
  response.setHeader("Location", "http://www.itcast.cn");
  response.setStatus(307);  //立即重定向

06_文件下载案例

步骤
//设置响应头
response.setHeader("Content-disposition", "attachment;filename=pic01.jpg");
//获取字节输出流对象
OutputStream os = response.getOutputStream();
//创建字节输入流对象
String path = getServletContext().getRealPath("/WEB-INF/pic01.jpg");
FileInputStream fis = new FileInputStream(path);
//循环读取并向客户端发送数据
int len = 0;
byte[] bys = new byte[1024];

while((len = fis.read(bys)) != -1) {
//向客户端发送数据
os.write(bys,0,len);
}

//释放资源
fis.close();

07_文件下载的细节

注意:
响应头里不能有中文,中文被认为是不安全的字符
更改如下:
String s = URLEncoder.encode("传智专修学院.jpg", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + s);

08_请求对象的概述&获取请求行

HttpServletRequest
请求对象封装了HTTP协议的请求行,请求头,请求体,我们可以通过请求对象的方法来获取这些信息
获取请求行
StringBuffer getRequestURL() //完整的URL 
String getRequestURI()  //请求行中的资源路径
String getMethod()  //请求方式
String getContextPath() //当前项目的路径
String getQueryString() //请求行中资源路径后面的参数
注意:
getRequestURL()返回的是一个可变字符串,不能直接使用String来接收
getQueryString()获取的是资源路径后面的参数,请求体里的数据无法获取

09_获取请求头

String getHeader(String name) //通过name来获取请求头value
Enumeration getHeaderNames()  //获取所有的请求头name
Enumeration迭代遍历
Enumeration<String> e = request.getHeaderNames();
while(e.hasMoreElements()) {
String name = e.nextElement();
System.out.println(name);
}

10_获取表单提交的数据

String getParameter(String name) :根据表单项的name来获取表单项的value
注意:
有表单项提交过来,但是没有值, 打印的是空字符串
表单项根本没有提交过来,打印的就是null,就不能调用字符串的方法,否则会报空指针异常

11_获取表单提交的数据2

String[] getParameterValues(String name) 根据表单项的name获取表单项value的数组
应用场景: name是重复的,比如密码确认密码 复选框

12_获取表单提交的数据3

Map getParameterMap(): 获取表单提交来的所有数据,并封装成一个map返回,一些框架(工具类)会使用这个方法 
Enumeration getParameterNames()  获取提交过来表单项所有的name
返回值使用泛型时应该是Map<String,String[]>形式,
因为有时像checkbox这样的组件会有一个name对应对个value的时候,
所以该Map中键值对是<String-->String[]>的实现。
注意:
注册按钮提交过来没有意义,所以注册按钮千万不要写个name属性  

14_获取表单提交的数据乱码的处理

原因:
编码前后不一致
表单提交数据用的是UTF-8
请求对象接收数据转换成字符串 用的是默认的ISO-8859-1
对于post请求
request.setCharacterEncoding("UTF-8");//只能处理请求体,这里设置请求对象创建字符串所使用的编码是UTF-
对于get请求
浏览器
按照表单页面的编码(UTF-8)进行转码,转成字节数组,拼接在请求资源的后面
接下来把字节数组做一个转义(url编码)在发送
服务器
服务器首先拿到这个数据做一个url解码,(正确的)
然后把解码之后的数据按照ISO-8859-1拼成字符串(错误)
做法:
//把字符串打回原形
byte[] bys = request.getParameter("username").getBytes("ISO-8859-1");
//把字节数组按照正确的编码转换字符串
String username = new String(bys,"UTF-8");

15_转发和包含

用ServletContext实现转发和包含,路径必须以正斜杠开头
RequestDispatcher rd = getServletContext().getRequestDispatcher("/register.html");
rd.forward(request, response);
rd.include(request, response);
用request对象实现转发和包含,路径可以不用正斜杠开头
RequestDispatcher rd = request.getRequestDispatcher("register.html");
rd.forward(request, response);
rd.include(request, response);

16_使用请求对象实现数据共享

ServletContext 上下文对象 范围是当前的web应用   
时间范围  tomcat 一加载项目 tomcat关闭
空间范围  整个web应用
request 请求对象 范围是当前的请求 需要同一个请求才能实现数据的共享
时间范围 一个请求开始,请求结束
空间范围  当前这个请求里面
//设置数据
request.setAttribute("username", "zhangsan");
//获取数据
Object obj = request.getAttribute("username");
System.out.println(obj);
//删除数据
request.removeAttribute("username");
//转发
RequestDispatcher rd = request.getRequestDispatcher("/RequestDemo9");
rd.forward(request, response);
访问网站访问量



猜你喜欢

转载自blog.csdn.net/qq_34118993/article/details/79720751