JavaWeb-Http通信
发布日期:2021-06-29 12:34:09 浏览次数:5 分类:技术文章

本文共 22726 字,大约阅读时间需要 75 分钟。

序言

HttpServletRequest和HttpServletResponse是在Servlet中常见的请求和响应方式,这是web交互最基本的模式。

客户端每次请求,都会创建request对象和response对象 ------ 被传递到 service、doGet、doPost 中。

这里写图片描述
HttpServletRequest 封装 客户端相关信息,服务器Servlet程序可以通过request对象 操作客户端信息。

HttpServletResponse 封装服务器 向客户端发送响应数据信息,Servlet程序通过response对象 向客户端发送响应。


1、HttpServletRequest

request对象是请求对象,在客户端向服务器请求一次就创建一个request对象,并且存储了请求的信息。所以在表单进行提交时,我们可以通过request对象获取用户提交的信息。
这里写图片描述
(1) 常用的API

方    法                           说    明getAttributeNames()              返回当前请求的所有属性的名字集合getAttribute(String name)        返回name指定的属性值getCookies()                     返回客户端发送的Cookiegetsession()                     返回和客户端相关的session,如果没有给客户端分配session 则返回nullgetsession(boolean create)       返回和客户端相关的session,如果没有给客户端分配session, 则创建一个session并返回getParameter(String name)        获取请求中的参数,该参数是由name指定的getParameterValues(String name)	 返回请求中的参数值,该参数值是由name指定的getCharacterEncoding()	         返回请求的字符编码方式getContentLength()	             返回请求体的有效长度getInputStream()                 获取请求的输入流中的数据getMethod()                      获取发送请求的方式,如get、postgetParameterNames()              获取请求中所有参数的名字getProtocol()                    获取请求所使用的协议名称getReader()                      获取请求体的数据流getRemoteAddr()                  获取客户端的IP地址getRemoteHost()                  获取客户端的名字getServerName()                  返回接受请求的服务器的名字getServerPath()                  获取请求的文件的路径

综合实例:

import java.io.IOException; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 通过request api 获得客户机信息 */public class RequestServlet1 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		// 问题一 区分 getRequestURL 和 getRequestURI		System.out.println("url:" + request.getRequestURL()); // 返回 http://192.168.1.114/day06/request1		System.out.println("uri:" + request.getRequestURI()); // 返回 /day06/request1 		// 问题二:了解 通过 getQueryString 可以获得 get方式提交查询串 url中?后面部分		System.out.println("querystring:" + request.getQueryString()); 		// 获得客户端ip		System.out.println("ip: " + request.getRemoteAddr());// 192.168.1.103 		// 通过 getContextPath 获得工程虚拟目录名称		System.out.println(request.getContextPath()); // 返回 /day06 		// 通过getMethod 获得请求方式		System.out.println("请求方式 : " + request.getMethod());// GET 		// 问题: 获得当前访问资源路径 --- /request1		System.out.println("当前访问资源路径 :"				+ request.getRequestURI().substring(						request.getContextPath().length()));//--/request1	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

(2) 从Request获得请求参数

什么是请求参数? 用户通过请求向服务器提交一些数据:

例如:

第1种、Get方式提交数据:其中包含使用超链接(提交数据以“?”方式)、sendRedirect()两种:/day06/request4?name=zhangsan&city=beijing  //包括两个参数的 name 和 city 第2种、通过form(表格)的Post方式提交数据(提交数据能用post就用post)。

获得request请求参数,常用API四个:

getParameter --- String 通过name获取值,如果是多值只取第一个getParameterValues --- String[] 通过name获得多值 checkboxgetParameterNames --- Enumeration
获得所有namegetParameterMap --- Map
key:name value:多值

综合实例(含两种提交参数的方式):

Insert title here

分别以get 和 post方式 提交数据

第一种 通过超链接 提交数据 以?方式

超链接提交数据

第二种 通过form的post方式提交数据

请输入姓名
请输入城市

服务器获取客户端提交的参数:

import java.io.IOException; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 获得请求参数 */public class RequestServlet4 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		// 通过getParameter 获得请求数据		String name = request.getParameter("name");		System.out.println(name);		String city = request.getParameter("city");		System.out.println(city);	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

A、详解get方式提交数据

常见的get方式提交数据有两种:使用超链接sendRedirect()

1、重定向——sendRedirect():   sendRedirect("servlet的地址?参数名="+参数值 &"参数名="+参数值);2、使用超链接:   使用超链接将数据带给浏览器

我们来使用一下,通过超链接将数据带给浏览器:

使用超链接将数据带给浏览器

在Servlet111接收数据:

//接收以username为参数名带过来的值String username = request.getParameter("username");System.out.println(username);

注意看浏览器左下角:

这里写图片描述
服务器成功接收到浏览器发送过来的数据:
这里写图片描述
并且,传输数据明文的出现在浏览器的地址栏上:
这里写图片描述
sendRedirect()和超链接类似,在这里就不赘述了


B、详解使用Post提交数据

案例1:

下面咱们来编写一个最复杂表单,及其数据的获取:

这里写图片描述
代码:

Insert title here
用户名
密码
性别
爱好 运动 颤酒 音乐
城市
个人简介

获取参数:

import java.io.IOException;import java.util.Arrays;import java.util.Enumeration;import java.util.Map;import java.util.Set; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 获得最复杂form 的所有数据 */public class RequestServlet5 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		// 解决post乱码		//request.setCharacterEncoding("utf-8");//只能对请求体重新编码				// 通过 getParameter 获得指定数据		String username = request.getParameter("username");		System.out.println(username);// 获得一个值				// 解决get乱码 --- 使用手动编码		// username = URLEncoder.encode(username, "ISO-8859-1");// 用ISO编码		// username = URLDecoder.decode(username, "utf-8"); // 用utf-8解码				username = new String(username.getBytes("ISO-8859-1"), "utf-8");		System.out.println(username);				// 非空校验		if(username !=null && username.trim().length()>0){			System.out.println("username 合法");		}				// 使用 getParameter 获得 checkbox 提交数据。默认只能获得第一个数据		String hobby = request.getParameter("hobby"); // 多选框		System.out.println(hobby);				// 获得checkbox所有提交数据--- getParameterValues		String[] hobbies = request.getParameterValues("hobby");		System.out.println(Arrays.toString(hobbies));				System.out.println("--------------------------");				// 打印所有请求提交参数		// 方式一 : 先获得所有参数 name ,然后通过name 获得value		Enumeration
names = request.getParameterNames(); while(names.hasMoreElements()){ String name = names.nextElement(); System.out.println(name +":"+ Arrays.toString(request.getParameterValues(username))); } System.out.println("--------------------------"); // 方式二 :通过request.getParameterMap Map
parameterMap = request.getParameterMap(); Set
keys = parameterMap.keySet(); for (String key : keys) {// key是参数 name System.out.println(key +":"+ Arrays.toString(parameterMap.get(key))); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

案例2

用户名
密码
性别
爱好 游泳 跑步 飞翔
你的来自于哪里
详细说明:

在Servlet111中获取到提交的数据,代码如下:

//设置request字符编码的格式request.setCharacterEncoding("UTF-8");//通过html的name属性,获取到值String username = request.getParameter("username");String password = request.getParameter("password");String gender = request.getParameter("gender");//复选框和下拉框有多个值,获取到多个值String[] hobbies = request.getParameterValues("hobbies");String[] address = request.getParameterValues("address");//获取到文本域的值String description = request.getParameter("textarea");//得到隐藏域的值String hiddenValue = request.getParameter("aaa");....各种System.out.println().......

向表单输入数据:

这里写图片描述
Servlet111得到表单带过来的数据,最后的一个数据是隐藏域带过来的:
这里写图片描述

(3) 解决中文乱码问题

细心的朋友会发现,我在获取表单数据的时候,有这句代码request.setCharacterEncoding(“UTF-8”);,如果没有这句代码,会发生什么事呢?我们看看。

再重新填写数据:

这里写图片描述
在服务器查看提交过来的数据,所有的中文数据都乱码了:
这里写图片描述

来这里我们来分析一下乱码的原因,在前面的博客中我已经介绍了,Tomcat服务器默认编码是ISO 8859-1,而浏览器使用的是UTF-8编码。浏览器的中文数据提交给服务器,Tomcat以ISO 8859-1编码对中文编码,当我在Servlet读取数据的时候,拿到的当然是乱码。而我设置request的编码为UTF-8,乱码就解决了。

接下来使用get方式传递中文数据,把表单的方式改成get即可当我们访问的时候。又出现乱码了!

这里写图片描述
这里写图片描述
于是我按照上面的方式,把request对象设置编码为UTF-8试试:

request.setCharacterEncoding("UTF-8");String name = request.getParameter("name");

结果还是乱码。这是为什么呢?我明明已经把编码设置成UTF-8了,按照post方式,乱码问题已经解决了!。我们来看看get和post方式的区别在哪?为什么post方式设置了request编码就可以解决乱码问题,而get方式不能呢。

首先我们来看一下post方法是怎么进行参数传递的。当我们点击提交按钮的时候,数据封装进了Form Data中,http中多了一个上传请求头,既然request对象封装了http请求,所以request对象可以解析到发送过来的数据,于是只要把编码设置成UTF-8就可以解决乱码问题了

这里写图片描述
而get方式不同,它的数据是从消息行带过去的,没有封装到request对象里面,所以使用request设置编码是无效的。
这里写图片描述
要解决get方式乱码问题也不难,我们既然知道Tomcat默认的编码是ISO 8859-1,那么get方式由消息体带过去给浏览器的时候肯定是用ISO 8859-1编码了

/此时得到的数据已经是被ISO 8859-1编码后的字符串了,这个是乱码String name = request.getParameter("username");//乱码通过反向查ISO 8859-1得到原始的数据byte[] bytes = name.getBytes("ISO8859-1");//通过原始的数据,设置正确的码表,构建字符串String value = new String(bytes, "UTF-8");

上面的代码有些难理解,我画张图说明一下:

这里写图片描述
经过我们手工转换,再来访问一下:
这里写图片描述
总结:

1、post方式直接改request对象的编码;2、get方式需要手工转换编码;3、提交数据能用post就用post。

(4) 转发request中的数据

Request对象同时是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其他web资源处理。

|--setAttribute方法|--getAttribute方法|--removeAttribute方法|--getAttributeNames方法

request方法提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发,从而共享请求中的数据

使用request实现Servlet之间的通讯的简单代码:

//以username为关键字存ShenBinwei值request.setAttribute("username", "ShenBinwei");//获取到requestDispatcher对象RequestDispatcher requestDispatcher = request.getRequestDispatcher("/Servlet222");//调用requestDispatcher对象的forward()实现转发,传入request和response方法requestDispatcher.forward(request, response);

HttpServletRequest 和 ServletContext 类似 都是数据域对象 , 以Map方式保持数据,二者的主要区别在于存活时间不同:

ServletContext对象 服务器启动对象创建,服务器停止对象销毁ServletRequest对象 当产生一次请求时 创建,当响应结束后,对象销毁

一般的原则:可以使用request就尽可能使用request。因为ServletContext代表着整个web应用,使用ServletContext会消耗大量的资源,而request对象会随着请求的结束而结束,资源会被回收。使用request域进行Servlet之间的通讯在开发中是非常频繁的。

Request数据域对象传递数据原理:

这里写图片描述
代码示例:

import java.io.IOException; import javax.servlet.RequestDispatcher;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 通过AServlet传递一个数据 给 BServlet */public class AServlet extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		//在使用forward之前 不能将响应内容传输到客户端				// 情况一 如果flush ,不能forward		// response.getWriter().println("Hello");// Hello默认输出浏览器,服务器内部缓存		// response.getWriter().flush(); 		// 情况二 在同一个Servlet不能使用多次 forward 或者 sendRedirect		// response.sendRedirect("/day06/welcome.html"); 		response.getWriter().println("Hello"); // Hello输出到内存缓冲区。在forward时,缓冲区会被清除 		// 通过request对象传递		// 向request域对象 保存一个属性		request.setAttribute("name", "itcast"); 		// 传递数据给 BServlet 必须使用请求转发		RequestDispatcher dispatcher = request.getRequestDispatcher("/b");		dispatcher.forward(request, response);	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

获取传递的Request的参数:

import java.io.IOException; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 接收A转发 request对象 */public class BServlet extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		// 因为是同一个Request对象		System.out.println(request.getAttribute("name"));	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

【转发重定向 的区别】:

Response的sendRedirect()可以实现重定向,做到的功能是页面跳转,使用request的getRequestDispatcher.forward(request,response)实现转发,做到的功能也是页面跳转,他们有什么区别呢?

这里写图片描述

(5) RequestDispatcher的include()方法

RequestDispatcher对象调用forward()可以实现转发上面已经说过了。RequestDispatcher还有另外一个方法include(),该方法可以实现包含,有什么用呢?

我们在写网页的时候,一般网页的头部和尾部是不需要改变的。如果我们多个地方使用Servlet输出网头和网尾的话,需要把代码重新写一遍。而使用RequestDispatcher的include()方法就可以实现包含网头和网尾的效果了。

我们来操作吧!现在我有网头和网尾的Servlet:

这里写图片描述
使用Servlet111将网头和网尾包含:

request.getRequestDispatcher("/Head").include(request, response);response.getWriter().write("--------------------------------------------");request.getRequestDispatcher("/Foot").include(request, response);

访问一下Servlet111,成功把网头和网尾包含了:

这里写图片描述

(6) HttpServletRequest应用-防盗链

什么是防盗链呢?

比如:我现在有海贼王最新的资源,想要看海贼王的要在我的网页上看。现在别的网站的人看到我有海贼王的资源,想要把我的资源粘贴在他自己的网站上。这样我独家的资源就被一个CTRL+C和CTRL+V抢走了?而反盗链就是不能被他们CRTL+C和CRTL+V。

下面我模拟一下场景。

1、现在我首页先有一个超链接,指向着海贼王最新资源:

这里写图片描述
2、当我点进去,就能看到海贼王最新资源了:
这里写图片描述
3、其他的人可以通过复制粘贴我的地址,放到它们的网页上:
这里写图片描述
4、这样我就划不来啦【我的广告你来没看呢!】。想要看我的资源,就必须经过我的首页点进去看

想要实现这样的效果,就要 获取Referer这个消息头,判断Referer是不是从我的首页来的。如果不是从我的首页来的,跳转回我的首页。

//获取到网页是从哪里来的String referer = request.getHeader("Referer");//如果不是从我的首页来或者从地址栏直接访问的,if ( referer == null || !referer.contains("localhost:8080/zhongfucheng/index.jsp") ) {    //回到首页去   response.sendRedirect("/zhongfucheng/index.jsp");   return;}//能执行下面的语句,说明是从我的首页点击进来的,那没问题,照常显示response.setContentType("text/html;charset=UTF-8");response.getWriter().write("路飞做了XXXXxxxxxxxxxxxxxxxx");

5、首先按正常预想的,别人从首页点击我的资源,访问我海贼王最新的资源:

这里写图片描述
能够成功访问到资源:
这里写图片描述
6、如果我在浏览器直接输入地址【此时Referer是为null的】,我们来看看:
这里写图片描述
结果是跳回到首页上,不能顺利直接访问到海贼王资源:
这里写图片描述
7、再试试,如果别人粘贴了我的资源url,在它的网页上挂了一个网址呢:
这里写图片描述
在别人网页上点击的时候:
这里写图片描述
又跳回到了我的首页了:
这里写图片描述
哈哈哈!!你必须老老实实访问我的主页(看完广告)才能访问到我的资源!防盗链实施成功!


2、HttpServletResponse

在Servlet中,当用户发出请求后,接下来就是需要响应,而响应用另一个对象Response对象。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

HttpServletResponse继承了ServletResponse接口,并提供了与Http协议有关的方法,这些方法的主要功能是设置HTTP状态码和管理Cookie。HttpServletResponse对象代表服务器的响应。

HttpServletResponse对象可以向客户端发送三种类型的数据:

a.响应头(Response headers)b.状态码(Protocol—Status code—Description)c.实体数据(Entity body )

(1) Http响应的格式

A、来个实例:

响应(服务器—>浏览器)HTTP/1.1 200 OK     --响应行Server: Apache-Coyote/1.1   --响应头(key-value)Content-Type: text/html;charset=utf-8Content-Length: 17Date: Wed, 16 Nov 2016 07:16:46 GMT                            --一个空行this is a Servlet           --实体内容

B、响应行:

1)http协议版本:同请求行2)状态码: 服务器处理请求的结果(状态)常见的状态码:200 302 304 404 500 a)200: 请求处理成功b)302: 客户端重定向c)304:  客户端访问资源没有被修改,客户端访问本地缓存d)404: 访问资源不存在e)500: 服务器内部出错

C、常见响应头:

Location: http://www.it315.org/index.jsp   --表示重定向的地址,该头和302的状态码一起使用。Server:apache tomcat                 --表示服务器的类型Content-Encoding: gzip               --表示服务器发送给浏览器的数据压缩类型Content-Length: 80                   --表示服务器发送给浏览器的数据长度Content-Language: zh-cn              --表示服务器支持的语言Content-Type: text/html; charset=GB2312   --表示服务器发送给浏览器的数据类型及内容编码Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT  --表示服务器资源的最后修改时间Refresh: 1;url=http://www.it315.org     --表示定时刷新Content-Disposition: attachment; filename=aaa.zip --表示告诉浏览器以下载方式打开资源(下载文件时用到)Transfer-Encoding: chunkedSet-Cookie:SS=Q0=5Lb_nQ; path=/search   --表示服务器发送给浏览器的cookie信息(会话管理用到)Expires: -1                           --表示通知浏览器不进行缓存Cache-Control: no-cachePragma: no-cacheConnection: close/Keep-Alive           --表示服务器和浏览器的连接状态。close:关闭连接 keep-alive:保存连接

(2) 常用的API

方    法                                   说    明addCookie(Cookie cookie)                将指定的Cookie加入到当前的响应中addHeader(String name,String value)     将指定的名字和值加入到响应的头信息中containsHeader(String name)	            返回一个布尔值,判断响应的头部是否被设置encodeURL(String url)                   编码指定的URLsendError(int sc)                       使用指定状态码发送一个错误到客户端sendRedirect(String location)           发送一个临时的响应到客户端setDateHeader(String name,long date)    将给出的名字和日期设置响应的头部setHeader(String name,String value)     将给出的名字和值设置响应的头部setStatus(int sc)                       给当前响应设置状态码setContentType(String ContentType)      设置响应的MIME类型

(3) 设置状态码

A、response.setStatus() 设置状态码

这里写图片描述
B、response.sendError() 设置状态码,调用默认对应页面
这里写图片描述

(4) 设置响应头

response.setHeader(“name”,”value”) 设置响应头。

这里写图片描述

(5) 设置实体内容

A、response.getWriter().writer(); 发送字符(中文)实体内容。

这里写图片描述
B、response.getOutputStream().writer() 发送字节实体内容 。
这里写图片描述

(6) Response完成请求重定向

请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。

案例一:

通过302 + Location 头信息实现页面重定向效果

response.setStatus(302);response.setHeader("Location", "/day06/welcome.html");

完整代码:

package ustc.lichunchun.servlet.response.demo1; import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 验证 状态码 设置效果 */public class ResponseServlet1 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		System.out.println("response1 ...");		//response.setStatus(500);//通过setStatus 向客户端设置不同响应 状态码				// 302 客户端重定向 --- 结合 Location头信息一起使用		response.setStatus(302);		// 通知浏览器 定向到哪个页面		response.setHeader("Location", "/day06/welcome.html");// 相对路径 和 绝对路径	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

这里写图片描述

(7) Response登陆重定向功能

在Response API 中提供 response.sendRedirect---- 完成302+Location重定向效果.例如: response.sendRedirect("/day06/welcome.html");

案例二:

登陆重定向:用户登录时,用户名密码错误,重定向回登陆页面

这里写图片描述
代码:

Insert title here
用户名
密码
package ustc.lichunchun.servlet.response.demo2; import java.io.IOException; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 通过这个程序 完成用户登陆 */public class ResponseServlet2 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		// 1. 获得客户端提交用户名和密码		String username = request.getParameter("username");		String password = request.getParameter("password");				// 2、判断是否正确 ,假设 admin / admin		if("admin".equals(username) && "admin".equals(password)){			// 用户名 和 密码正确			// response.setStatus(302);			// response.setHeader("Location", "/day06/welcome.html"); 			// 使用response.sendRedirect完成重定向			response.sendRedirect("/day06/welcome.html");		}else{			// 不正确			// response.setStatus(302);			// response.setHeader("Location",			// "/day06/response/demo2/login.html");			//第一个/day06代表绝对路径工程名,第二个/代表WebRoot			response.sendRedirect("/day06/response/demo2/login.html");		}	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

结果:

这里写图片描述
对比:
这里写图片描述

(8) Response自动刷新

案例三:自动刷新网页

  • 登陆成功,5秒后自动跳转XX页面
    原理:通过refresh 头信息
    格式:refresh:时间;url=跳转路径(绝对路径)
    例如: refresh:3;url=http://www.itcast.cn -------- 3秒后自动跳转http://www.itcast.cn网站

代码:

Insert title here

自动刷新 跳转后页面!!!

package ustc.lichunchun.servlet.response.demo3; import java.io.IOException; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 完成自动跳转功能 */ public class ResponseServlet3 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		// 通过refresh 头信息完成跳转		response.setHeader("refresh", "3;url=/day06/response/demo3/result.html");		response.setContentType("text/html;charset=utf-8");// 设置响应编码		response.getWriter().println("3秒后 将跳转 result.html页面!");	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

结果:

这里写图片描述
跳转以后:
这里写图片描述

  • HTML 页面中存在一类非常特殊标签 , 起到设置头信息作用,和http头信息相同效果。http-equiv相当于头信息 name、content相当于头信息 value
---- 完成自动跳转
Insert title here

通过 meta实现 3秒页面自动跳转

(9) Response禁止浏览器缓存

通过response头信息设置 浏览器 禁止缓存。

原理:

和禁用缓存相关头信息有三个 :    Cache-Control:no-cache    Expires:Thu, 01 Dec 1994 16:00:00 GMT  ----- setDateHeader("expires",-1);    Pragma : no-cache
package ustc.lichunchun.servlet.response.demo4; import java.io.IOException; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 通过Servlet禁止 缓存 */public class ResponseServlet4 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		// 默认 浏览器产生 该程序缓存 		// 禁用浏览器缓存		response.setHeader("Cache-Control", "no-cache");		response.setHeader("Pragma", "no-cache");		// 设置expires 因为日期格式很复杂		// response.setHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); 		// 通过 setDateHeader 为 expires设置 毫秒值 --- 从1970年1月1日 00:00:00毫秒		response.setDateHeader("expires", -1);// 已经过期				response.getWriter().println("No Cache! We can change~");	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

查看缓存:IE 工具—Internet选项 —常规 — 设置 — 查看文件

实际开发中,对于Servlet生成HTML页面,会经常需要改变,所以需要禁止Servlet动态程序缓存

  • 设置Expires时,通常使用 setDateHeader 为过期时间设置一个毫秒值,生成HTTP响应时,会自动转换日期字符串表示

(10) Response输出流字符编码问题

通过response 生成 客户端响应体,通过字节流和字符流两种输出方式 。

哪些情况用字节流? 哪些情况用字符流 ?

文件拷贝 ---- 字节流 分析文件内容 --- 字符流 (中文操作 字符流)

案例五:

输出中文信息——对中文信息进行编码 :

response.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");

setCharacterEncodig 和 setContentType 区别 ?

|–setCharacterEncodig 设置响应内容编码,无法设置浏览器查看编码
|–setContentType 设置响应内容编码,同时通知浏览器查看编码
|–原理:setContentType可以在响应报文中添加 Content-Type:text/html;charset=utf-8 的头信息
这里写图片描述
代码:

package ustc.lichunchun.servlet.response.demo5; import java.io.IOException;import java.io.PrintWriter; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 向浏览器输出 中文信息 */public class ResponseServlet5 extends HttpServlet { 	public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		response.setCharacterEncoding("utf-8");		System.out.println("c1: "+ response.getCharacterEncoding());// 设置响应内容编码集 ,无法设置浏览器查看编码				// 需要通知浏览器 查看编码		response.setContentType("text/html;charset=gbk");// 设置响应编码 与 浏览器查看编码				System.out.println("c2: "+ response.getCharacterEncoding());//c2: gbk				// 输出中文信息--- 字符流		PrintWriter out = response.getWriter();		out.println("response向浏览器输出中文信息--setContentType中文编码!");				// 默认在方法结束后,自动关闭 response输出流,flush缓冲区内容	} 	public void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		doGet(request, response);	} }

结果:

这里写图片描述
结论:开发中只需要使用setContentType就可以了。


转载地址:https://bwshen.blog.csdn.net/article/details/82355197 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JavaWeb-Servlet
下一篇:Java-数组/集合工具类

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月03日 15时16分21秒