上下文对象-请求对象-响应对象(ServletContext - response - request)

上下文对象-请求对象-响应对象

ServletContext

什么是ServletContext

  • ServletContext代表是一个web应用的上下文对象(web应用对象)
  • 里面封装的都是web应用信息
  • 一个ServletContext对应一个应用

ServletContext的生命周期

  • 在服务器一启动的时候就会创建
  • 在服务器关闭的时候销毁

如何获得上下文

​ 1.通过init方法当中一个参数ServletConfig来获取
​ 2.直接在HttpServlet当中获取

  • this.getServletContext

  • 这种方法本质还是通过config来去获取的​

获取全局的初始化参数

  • 初始化参数不能再某一个Servlet当中来去配置。在最外层来去配置

  • 获取全局初始化参数

获得Web应用中某一个资源的资源的绝对路径

  • context.getRealPath("文件")
  • 相对的是web应有根目录

​ context.getRealPath("index.html")
​ D:\Java\Tomcat\apache-tomcat-7.0.85\webapps\bei\index.html
​ 在你写的名称前面自动拼接上当前工程的绝对地址

ServletContext是一个域对象

什么是域?
  • 能够存储数据
域对象
  • 能够存取数据流的对象
ServletContext域对象的作用范围
  • 整个web应用
  • 所有的web资源都可以进行存取数据
  • 数据是可以共享的
获取完ServletContext之后向里面写数据

​ context.setAttribute(String name,Object value);

获取完ServletContext之后,通过name取出存放的数据

​ context.getAttribute(String name);

获取完ServletContext之后,删除指定名称的值

​ Context.removeAttribute(String name);

response

response响应过程

  • 在去发送一个请求时, 会找到tomcat引擎
  • 引擎会找到对应的web应用
  • 并且会创建request对象和response对象
  • 找到应用后, 会执行应用的web.xml再去根据url-pattern的内容创建Servlet对象
  • 并且会调用Servlet对象的service方法,把创建的request对象和response对象传入到方法当中
  • 拿到response对象后, 自己可以往响应当中写入一些自己给客户端的内容
  • 通过response.getwrite().wirte("写的内容")方法进行写入
  • 写的内容,是存到一个response缓冲区当中
  • 当方法执行结束之后, tomcat就会从response缓冲区当中取出数据
  • 取出你的数据同时,它自己还会自动的往里面添加一些服务器相关的信息进去
  • 所以响应给浏览器时, 可以看到除了自己写的内容, 还会有一些服务器相关的信息

​ 流程图

通过response设置响应行,响应头 ,响应体

设置响应行

​ response.setState(Int code)

设置响应头
add
  • add代表添加新的内容
  • addHeader(String name,String value)
  • addIntHeader(String name,int value)
  • addDateHeader(String name,date)

set
  • set代表设置,已经存在的内容
  • setHeader(String name,String value)
  • setIntHeader(String name,int value)
  • setDateHeader(String name,Date value)
  • 添加两个相同的name

重定向

​ 什么是重定向

  • 到服务器当中去找servlet1
  • servlet1当中没有这个资源,告诉你去找servlet2
  • 再去发送一个请求到servlet2

​ 状态码
​ 302
​ 特点
​ 1.要访问两次服务器

  • 第一次访问是人为的去访问
  • 第二次是自动的访问

​ 2.浏览器地址栏已经发生变化
​ 设置重定向

  • 设置响应码

  • 设置响应头

封装的重写向

  • 每次都要写状态码,和location比较麻烦

  • 就给封装了一个方法 response.sendRedirect("/bei/servlet2")

    定时刷新重定向
    ​ ​ response.setHeader("refresh","5;url=http://www.baidu.com")

  • 5代表5秒

  • url的值为5秒后要去跳转的地址​

设置响应体
1.通过write方法来写

​ response.getwrite().wirte(“要写的内容”)
​ ​ 默认情况下写的中文内容会乱码
​ ​ 把写的内容存到缓存区中使用的是ISO8859
​ ​ ISO8859不支持中文,所以会乱码
​ ​ 在存之前设置可以设置存放的编码
​ ​ response.setCharacterEncoding("UTF-8")
​ ​ 告知浏览器使用的是utf-8编码
​ ​ response.setHeader("Content-Type", "text/html;charset=UTF-8");

​ ​
​ ​ 上面代码只需要写第二句就行, tom看到设置了为utf-8的编码,它在存在的时候也会使用utf-8的编码
​ ​ 使用封装写法
​ ​ response.setContentType("text/html;charset=UTF-8");

2.通过OutPutStream来写

​ ​ FileInputSteam

​ ​ read方法读取一个字节

​ ​ read(byte[] b)

  • 一次读取多个字节,并存放到数组b中
  • 上面是一次一滴一滴给你,这种是一次装一水桶再给你

​ ​ 读取全部的数据

​ ​ FileOutputSteam

write()
一次性写一个字符
write(buffer)
一个性写多个字符
write(buffer,0,len)
一次性写指定个数的字符

​ ​ response注意点

​ ​ getWrite()和getOutputSteam不能同时调用

下载功能

​ ​ 下载文件
​ ​ 1.直接使用a标签来去下载,存在的问题

  • 有些内容会浏览器自动解析
  • 浏览器不能解析的文件才会被下载

​ ​
​ ​ 2.通过发送Servlet请求来去下载
​ ​

通过发送一个Servlet请求,把文件名发送给服务器
发送给服务器后,接收到文件名参数,获取文件的绝对地址
通过流的形式来去写到浏览器
还得要告诉文件是什么类型
​	浏览器是以MIME的类型来识别类型
​		this.getServletContext().getMimeType(“文件名称”)
​	设置响应的类型
​		res.setContentType("MIME类型")
设置响应头,告诉浏览器不要去解析,是以附件的形式打开,
​	res.setHeader("Content-Dsiposition","attachment;filename="+文件名)
步骤
1.接收文件名参数
2.获取mime类型
3.设置浏览器响应类型
4.告诉浏览器以附件形式下载
5.获取文件的绝对路径
6.读取文件流
7.获取输出流
8.把内容写出到输出流

//1.接收文件名参数
String filename = request.getParameter("filename");
String mime = this.getServletContext().getMimeType(filename);
response.setContentType(mime);
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//2.获取文件的绝对路径
String path = this.getServletContext().getRealPath("download/"+filename);
System.out.println(path);
//3.读取文件流
FileInputStream in = new FileInputStream(path);
//4.获取输出流
ServletOutputStream out = response.getOutputStream();
//5.把内容写出到输出流
byte[] buffer = new byte[1024];
int len = 0;
while((len = in.read(buffer)) != -1) {
	out.write(buffer, 0, len);
}
解决中文名称乱码问题
获取中文参数报错问题
    			高版本tomcat中的新特性:就是严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])
    			.../conf/catalina.properties中,找到最后注释掉的一行 #tomcat.util.http.parser.HttpParser.requestTargetAllow=|  ,改成tomcat.util.http.parser.HttpParser.requestTargetAllow=|{},表示把{}放行
    		1.把获取的字符串参数的字节码获取,再重新使用utf-8编码
    		2.在设置以附件形式打开时, 不同的浏览器会对默认的名字进行解码
    		所以根据不同的浏览器,要对名称进行编码之后,再放入文件名
    		对文件名进行编码
    			不同的浏览器编码不一样
    			要先获取agent,取出浏览器的类型
                根据不同的浏览器类型进行编码
                步骤
                1.接收文件名称
                2.获取mimeType
                3.设置浏览器响应类型
                4.先对传入的参数转成二进制流,再使用UTF-8进行编码
                5.获取浏览器的信息
                6.判断是哪一种浏览器,根据不同的浏览器获取一个编码的文件名
                7.设置以附件形式下载,传的名称是编码过的名称 
                8.获取文件的绝对路径
                9.读取文件流
                10.获取输出流
                11.把文件写到响应当中

// 获取客户端信息
String agent = request.getHeader("User-Agent");
// 定义一个变量记录编码之后的名字
String filenameEncoder = "";
if (agent.contains("MSIE")) 
{
	// IE编码
	filenameEncoder = URLEncoder.encode(filename, "utf-8");
	filenameEncoder = filenameEncoder.replace("+", " ");
} 
else if (agent.contains("Firefox")) 
{
	// 火狐编码
	BASE64Encoder base64Encoder = new BASE64Encoder();
	filenameEncoder = "=?utf-8?B?" + 	base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} 
else 
{
	// 浏览器编码
	filenameEncoder = URLEncoder.encode(filename, "utf-8");
}

注册验证码功能

​ 1.把别人写好的验证码Servlet拿到程序当中

​ 2.编写静态页面

​ 3.编写判断验证码是否正确Servlet

​ 1.设置响应编码
​ 2.从ServletContext当中获取验证码
​ 3.获取传入的请求参数
​ 4.从servletContext当中取出存放的验证码
​ 5.把接收的验证码与取出的验证码时行比较
​ 6.相同时,显示成功
​ 7.不同时, 显示失败,隔3秒钟跳转到输入验证码界面

request

如何获取请求行, 请求头,请求体

获取请求行

​ 获取请求方法
​ String getMethod()

获取请求资源

​ String getRequestURL()

​ String getRequestURI()

获取应用名称

​ String getContextPath()

获取get查询参数

​ String getQueryString()

获取请求头
1.获取所有的请求头名称

2.获取指定的头信息


3.打印所有的请求头和请求头内容

referer

​ 告诉服务器我是从哪个页面链接过来的

​ 注意事项
​ 通过以下方式发送请求才会获取

​ 通过以下方式不会有referer

  • 从收藏夹链接
  • 单击主页或自定义的地址
  • 在浏览器中直接输地址
获取请求体

​ 1.获取一个值
​ req.getParameter("名称")

​ 2.获取多个值
​ req.getParameterValues("名称")
​ 返回的是一个数组

​ 3.获取所有请求参数名称
​ req.getParameterNames()
​ 返回的是一个枚举

​ 4.获取所有请求参数
​ req.getParameterMap()
​ 获取所有请求参数的key-value集合Map<String,String[]>

解决中文乱码问题

​ 什么时候使用get方式与post方式
​ 1.发送的参数不需要写到数据库当中使用get
​ 2.发送的参数需要保存到数据库当中使用post
​ form一般提交数据的数据为post
​ 造成乱码的原因
​ 发送请求时, 会对参数进行编码,编码使用的是ISO8859-1 不支持中文,所以乱码
​ 通用解决办法
​ 获取对应的参数
​ 通过iso8859-1转回二进制位,再以utf-8的形式转成字符串
​ 存在的问题,每一个参数都必须得要转回二进制位,再转为字符串
​ request方法解决中文乱码
​ 只适用于post

请求转发
重定向与请求转发的区别

​ 重定向

  • 找servlet1,通过设置响应,告诉浏览器, 再让浏览器发送请求到servlet2
  • 发两次请求
  • 地址栏会发生变化

​ 请求转发

  • 请求转发只需要发送一次直接,找servlet1,在servlet1当中直接转发给servlet2,不要再告诉浏览器
  • 只发送一次请求
  • 浏览器地址栏当中还是servlet1,不会发生变化
实现转发

​ 1.通过请求对象获取一个转发器

  • request.getRequestDispatcher(String path)
  • 返回一个RequestDispatcher

​ 2.通过转发器进行转发

  • 调用转发器的forward方法进行转发
  • disp.forward(req,rep)
request域对象
在一次请求过程当中
		request是共享的。在一个servlet当中设置的参数,转发到另外一个servlet,取出来的是同一个
		生命周期
			创建
				发送一个请求时创建一个request对象
			销毁
				请求结束,浏览器给出响应时,销毁
			作用范围
				一次请求当中
客户端地址与服务器端地址

​ 客户端地址

  • 客户端访问服务器使用的地址
  • 服务器外部地址
  • 在写的时候要写上web应用的名称 /应用名称/资源

​ 服务器地址

  • 在服务内部当中使用的地址
  • 不需要写web应用名称 /资源名称
posted @ 2019-03-26 22:06  海韵༒听心  阅读(1324)  评论(0编辑  收藏  举报