一个完整的http响应包括响应行,若干响应头和响应数据主体三部分构成。如果我们能用响应对象来进行这三部分的处理,就能向客户发送特定的响应数据包。

先从HttpServletResponse对象的方法中可以看到有如下方法(部分):
这只是一部分,但是我们却可以看出,通过响应对象的方法,我们就能设置响应客户端数据的一些信息。比如setStatus(int sc)方法,我们从HttpServletResponse的API中的字段定义可找到已经设置好的响应码(部分):
我们通过setHeader或者addHeader就能对一些数据进行跟客户端的告知,比如我想让某个页面的数据在客户端保存一天,也就是如果客户端再向我请求的话,则它应该去缓存中获取,直到一天之后才能重新向我请求,那么我就必须使用到了“Expires”响应头,将这个响应头的值设为一天后的时间告诉给客户端:
在MyEclipse中的【myservlet】web工程下,创建名为ServletDemo1的Servlet,代码如下:
public class ServletDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long expiresTime = System.currentTimeMillis()+1*24*60*60*1000; //将缓存截止时间设置为一天后
response.setDateHeader("expires", expiresTime);
}
}
这时候用浏览器来访问这个Servlet(访问之前最好现将浏览器中的缓冲清除干净),访问之后我们再来看看这个缓存的页面文件:
右键查看其属性:
可以看到我们是在9月28日访问的这个文件,而服务器已经将这个文件的缓冲时间设置为了29日。
注意:对于”Expires”响应头的设置必须使用setDateHeader方法,使用setHeader方法无效。
使用响应对象可以向客户端写入数据,我们采用获取响应对象的输出流,将数据用write方法写,这些数据是写入到响应对象中,而服务器再将这些响应对象回传给客户端进行解析。而这些数据在响应对象中正是处于HTTP协议的响应数据实体中。
通过HttpServletResponse对象的父类ServletResponse对象的getOutputStream方法和getWriter方法可以获取向响应对象的数据实体中写入数据。这里如果传送的是英文数据一般都没有什么问题,而中文编码则是会令人头疼的。
首先我们来看响应对象的getOutputStream方法,我们在一个Servlet程序中代码如下:
String data = "银魂"; OutputStream out = response.getOutputStream(); out.write(data.getBytes());
而在浏览器中访问这个Servlet,看到的是:
是的,没有出现乱码的问题,这主要有两点原因:
一个是浏览器本身的解码方式是根据平台语言环境来设置的,我的操作系统是Windows的中文版本,因此浏览器的解码采用的编码表为“GB2312”:
另一个原因是因为,在将字符串转为字节数组时,采用了getBytes()方法,这个方法在String类的API文档中明确说明了采用平台默认的字符集,根据我的系统这个方法也采用了“GB2312”编码表。
因此服务器编码和客户端解码都采用同一编码表这就不会出现中文乱码问题。
如果我在getBytes方法中采用UTF-8编码,那么结果自然会出错:
String data = "银魂";
OutputStream out = response.getOutputStream();
out.write(data.getBytes("UTF-8"));
除非你也在浏览器中更改编码方式,改成UTF-8就可以重新看到正确的中文数据了:
当然这肯定不适合给用户这么操作,毕竟不是谁都懂浏览器的编码。
如果我们一定要将中文数据采用“UTF-8”的方式(UTF-8有利于国际化),有这么两种解决采用UTF-8编码方式的中文乱码问题:
第一种解决方式:使用HttpServletResponse响应对象的setHeader的方法,将“Content-type”这个响应头中设置编码方式。同时,sun公司也提供了更便捷的代码语句setContentType给编程人员使用。
在Servlet中的代码:
response.setHeader("content-type", "text/html;charset=UTF-8");
//response.setContentType("text/html;charset=UTF-8"); //这句功能同上一句
String data = "银魂";
OutputStream out = response.getOutputStream();
out.write(data.getBytes("UTF-8"));
这样在浏览器中可以看到正确的中文数据,并且浏览器自动将编码方式采用UTF-8:
附带从HttpWatch中观察到的数据包:
注意:如果response.setHeader("content-type", "text/html;charset=UTF-8");中将"text/html;charset=UTF-8"中的分号“;”写成了逗号“,”就会变成下载该Servlet文件。
所以书写要注意。
第二种解决方式:我们不直接在响应对象中设置“Content-type”这个响应头,而是通过HTML的<meta>标签,该标签的作用就是模拟一个响应头,这样在回传的响应对象中,某些响应头就不会被设置,但是还是有这个响应头的功能,例如我们在HTML页面中经常能见到的<meta http-equiv="content-type" content="text/html;charset=utf-8">这个标签,是不是和第一种方式很像。相关代码为:
String data = "银魂";
OutputStream out = response.getOutputStream();
out.write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes());
out.write(data.getBytes("UTF-8"));
这时候在浏览器中同样能观察到正确的中文数据,同时可以看到浏览器已经自动采用“UTF-8”编码方式:
同时,在浏览器浏览源代码和观察HttpWatch窗口:
从上面可以看出,服务器发回的响应中没有“Content-type”这个响应头,但是在响应数据实体中有<meta>标签,浏览器能解析这个HTML语言,得到这个标签中设置的“Content-type”模拟响应头,因此能根据这个模拟响应头中的编码方式来设置浏览器应该采用的码表。
如果我们用输出流直接输出数字的话,会是输出这个数字在编码表中代表的字符,如代码为:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getOutputStream().write(97);
}
在浏览器中得到:a。
说完了从响应对象中得到OutputSteam对象,接着我们来讨论从响应对象中得到Writer对象,众所周知,字符流是由字节流加编码表组成,那么在响应对象中的字符流采用什么编码表方式呢?我们来看看HttpServletResponse对象的getWriter()方法的API手册说明:
从这里面看出如果没有为这个getWriter()方法设置编码表,那么则默认采用 “ISO-8859-1”编码表。或者采用响应对象的getCharacterEncoding()方法查看也可以。
那么在服务器端如果要改变对封装数据的编码格式可以有两种方式:
第一种:使用响应对象的setCharacterEncoding()方法来设置服务器采用的编码表,接着使用setContendType或者setHeader告知客户端服务器采用的编码表,后者在上面已经说过。
示例代码:
public class ServletResponse extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
String data = "银魂";
writer.write(data);
}
}
注意,光只有setCharacterEncoding()方法只能改变服务器端采用的编码表,而没能通知客户端,所以需要setContentType设置“Content-type”响应头,或者如之前所说的写入<meta>标签来模拟“Content-type”响应头。
第二种:直接使用setContentType方法,通过这种方法,可以在服务器和客户端同时设置编码表,也就是第一种方式中两个方法的结合,因此上述示例的代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
String data = "银魂";
writer.write(data);
}
}
以上分别从响应对象HttpServletResponse中根据获取的字节流或者字符流向客户端输出数据时会碰到的中文乱码问题做出了分析和解决。
# HttpServletResponse乱码问题
# HttpServletResponse乱码
# Java Servlet响应httpServletResponse过程详解
# 使用HttpServletResponse对象获取请求行信息
# 如何使用spring ResponseEntity处理http响应
# 解决golang处理http response碰到的问题和需要注意的点
# Java HttpServletResponse响应实现过程详解
# Java中HttpServletResponse响应中文出现乱码问题
# NoHttpResponseException问题分析解决记录
# 客户端
# 可以看到
# 器中
# 第一种
# 象中
# 的是
# 就能
# 采用了
# 可以看出
# 第二种
# 数据包
# 中得
# 回传
# 这时候
# 有什么
# 我就
# 就会
# 是在
# 是因为
# 我在
相关文章:
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
三星网站视频制作教程下载,三星w23网页如何全屏?
七夕网站制作视频,七夕大促活动怎么报名?
如何打造高效商业网站?建站目的决定转化率
javascript中的try catch异常捕获机制用法分析
完全自定义免费建站平台:主题模板在线生成一站式服务
如何通过宝塔面板实现本地网站访问?
制作网站公司那家好,网络公司是做什么的?
如何在Mac上搭建Golang开发环境_使用Homebrew安装和管理Go版本
,购物网站怎么盈利呢?
制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?
MySQL查询结果复制到新表的方法(更新、插入)
如何规划企业建站流程的关键步骤?
建站10G流量真的够用吗?如何应对访问高峰?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
如何通过西部建站助手安装IIS服务器?
Swift中switch语句区间和元组模式匹配
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
如何用景安虚拟主机手机版绑定域名建站?
建站之星在线客服如何快速接入解答?
南宁网站建设制作定制,南宁网站建设可以定制吗?
制作农业网站的软件,比较好的农业网站推荐一下?
如何在阿里云购买域名并搭建网站?
建站之星代理如何优化在线客服效率?
如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?
如何用虚拟主机快速搭建网站?详细步骤解析
清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?
建站之星24小时客服电话如何获取?
制作电商网页,电商供应链怎么做?
如何在Golang中使用replace替换模块_指定本地或远程路径
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
建站之星安装需要哪些步骤及注意事项?
免费制作海报的网站,哪位做平面的朋友告诉我用什么软件做海报比较好?ps还是cd还是ai这几个软件我都会些我是做网页的?
安云自助建站系统如何快速提升SEO排名?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
网站制作报价单模板图片,小松挖机官方网站报价?
如何选择高性价比服务器搭建个人网站?
建站之星多图banner生成与模板自定义指南
股票网站制作软件,网上股票怎么开户?
如何在万网自助建站中设置域名及备案?
北京的网站制作公司有哪些,哪个视频网站最好?
小型网站建站如何选择虚拟主机?
网站制作公司广州有几家,广州尚艺美发学校网站是多少?
如何通过主机屋免费建站教程十分钟搭建网站?
如何通过智能用户系统一键生成高效建站方案?
专业商城网站制作公司有哪些,pi商城官网是哪个?
装修招标网站设计制作流程,装修招标流程?
如何获取上海专业网站定制建站电话?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
*请认真填写需求信息,我们会在24小时内与您取得联系。