调用getWriter()方法向浏览器输出数据
对付getWriter()方法而言,是Writer的子类,那么只能向浏览器输出字符数据,不能输出二进制数据利用getWriter()方法输出中文数据,代码如下:为什么涌现乱码了呢?由于Tomcat是外国人的写,Tomcat默认的编码是ISO 8859-1,当我们输出中文数据的时候,Tomcat会依据ISO 8859-1码表给我们的数据编码,中文不支持这个码表呀,以是涌现了乱码既然如此,我设置一下编码不就好了吗,代码如下: //原来是ISO 8859-1的编码,我设置成UTF-8 response.setCharacterEncoding(\公众UTF-8\"大众); //获取到printWriter工具 PrintWriter printWriter = response.getWriter(); printWriter.write(\公众看完博客点赞!
\"大众);
为什么乱码问题还没有办理?细心的朋友会创造,我只是在中文转换的时候把码表设置成UTF-8,但是浏览器未必是利用UTF-8码表来显示数据的呀好的,我们来看看浏览器的编码格式,果真,浏览器利用GB2312显示UTF-8的数据,不乱码才怪呢这个问题我们在上面已经是有两种方法办理了【利用标签仿照头、设置头】,Servlet还供应了一个方法给我们
//设置浏览器用UTF-8编码显示数据 response.setContentType(\"大众text/html;charset=UTF-8\公众);好的,我们再来访问一下
既然Servlet有那么多方法办理乱码问题,是不是有一种是最简便的呢?没错!下面这个方法是最简便的,它不仅设置浏览器用UTF-8显示数据,内部还把中文转码的码表设置成UTF-8了,也便是说,response.setContentType(\"大众text/html;charset=UTF-8\"大众);把response.setCharacterEncoding(\"大众UTF-8\"大众)的事情也干了!
利用getWriter()显示中文数据,只须要一个方法就搞掂了!
实现文件下载
下载资源我们在日常中也很常用,它是怎么做到的呢?要能够给别人下载,做事器就该当有这个资源
现在我web站点下有一个图片了!既然浏览器发送所有的要求都是去找Servlet的话,那么我就写一个Servlet,当别人访问我这个Servlet的时候,它们就可以下载我这个图片了!
java的文件上传下载都是通过io流来完成的,既然要下载图片,首先要能够读取到它
//获取到资源的路径 String path = this.getServletContext().getRealPath(\"大众/download/1.png\公众); //读取资源 FileInputStream fileInputStream = new FileInputStream(path); //获取到文件名,路径在电脑上保存是\\形式的。 String fileName = path.substring(path.lastIndexOf(\公众\\\"大众) + 1);见告浏览器,我要下载这个文件
//设置头,见告浏览器,我要下载1.png这个图片 response.setHeader(\公众Content-Disposition\公众, \"大众attachment; filename=\"大众+fileName);将读取到的内容回送给浏览器
//把读取到的资源写给浏览器 int len = 0; byte[] bytes = new byte[1024]; ServletOutputStream servletOutputStream = response.getOutputStream(); while ((len = fileInputStream.read(bytes)) > 0) { servletOutputStream.write(bytes, 0, len); } //关闭资源 servletOutputStream.close(); fileInputStream.close();当我访问时,浏览器就提示下载了。
也可以成功打开!现在问题又有了,如果我文件的名字是中文呢?我们再访问一下,创造名字乱码了(怎么都是乱码)为理解决文件名乱码,我们要进行URL编码,代码如下:
response.setHeader(\公众Content-Disposition\"大众, \"大众attachment; filename=\"大众 + URLEncoder.encode(fileName, \"大众UTF-8\"大众));再次访问时,文件名乱码问题就办理了!
实现自动刷新
以规定的韶光让页面刷新,更新资源
让浏览器实现自动刷新,那肯定又是修正头了。//每3秒自动刷新网页一次 response.setHeader(\"大众Refresh\"大众, \"大众3\"大众);为了更好的看效果,我们加入韶光值进去
response.getWriter().write(\"大众time is :\"大众 + System.currentTimeMillis());每三秒韶光值就会发生变革
学完上面的,彷佛没有什么用,自己上网的时候谁看得见这样的东西。自动刷新,能够实现页面的跳转】我们上岸完网站,很多时候都会瞥见【上岸成功,3秒后自动跳转….】,实在这个便是用Refresh来完成的。response.setContentType(\公众text/html;charset=UTF-8\"大众); response.getWriter().write(\"大众3秒后跳转页面.....\"大众); //三秒后跳转到index.jsp页面去,web运用的映射路径我设置成/,url没有写上运用名 response.setHeader(\"大众Refresh\"大众, \"大众3;url='/index.jsp'\"大众);看下效果
设置缓存
浏览器本身就存在着缓存机制
当我第一次访问index.jsp时,浏览器向做事器发了两次要求【一个是网页的,一个是图片的】当我第二次访问index.jsp的时候,浏览器将图片缓存起来了!图片不是重新加载的,是从缓存里面取出来的。像股票类型的网页是不能取缓存的数据的,数据都是要不断更新的。下面我就禁止缓存的功能
//浏览器有三头设置缓存,为了兼容性!
将三个头都设置了 response.setDateHeader(\公众Expires\"大众, -1); response.setHeader(\"大众Cache-Control\公众,\"大众no-cache\公众); response.setHeader(\公众Pragma\"大众, \"大众no-cache\"大众); //这里为了看效果 PrintWriter printWriter = response.getWriter(); printWriter.print(\公众你好啊\"大众 + new Date().toString());当然了,如果页面有些数据不长期更新,你就将它设置成缓存,这样可以提高做事器的性能
实现数据压缩
网页上的信息量是很大的,如果不将数据压缩再回送给浏览器,这样就十分耗费流量
现在我有一篇文章要输出给浏览器response.setContentType(\公众text/html;charset=UTF-8\"大众); String ss = \"大众fsdfhsdfhuisdhfusdhfuids\公众 + \"大众fsdfdsfsdfsdfdsfdafdsfhsdjfhsdjkfhkjds\"大众 + \"大众fdsfjdslkfjsldkfjsdlkfjsdkfsdjkff\"大众 + \"大众fsjdfjdsklfjdsklfjkldsfjlksdjflksdjflkds\公众 + \公众dsjfklsdjflsdjfkldsfkjsdkfjsldkfjsdlfk\"大众 + \公众fdsjlkfjdslkfjsdlkfjlkasjflk\"大众; response.getWriter().write(\公众原来的长度是:\"大众+ss.getBytes().length+\"大众</br>\公众); //输出给浏览器 response.getWriter().write(ss);访问一下可以看到,原来的长度是201
压缩的事理是什么?我们知道getOutputStream()和getWriter()都是直接把数据输出给浏览器的。现在我要做的便是让数据不直接输出给浏览器,先让我压缩了,再输出给浏览器。java供应了GZIP压缩类给我们就让我们利用GZIP类来对数据压缩吧//GZIP的布局方法须要一个OutputStream子类工具,究竟哪个工具适宜,我们看下write()方法 GZIPOutputStream gzipOutputStream = new GZIPOutputStream(); //查看了下API,write()吸收的是byte[]类型的。 gzipOutputStream.write();于是我就在布局函数上通报个ByteArrayOutputStream给它
//既然是byte[]类型,那么我就给他一个ByteArrayOutputStream GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new ByteArrayOutputStream());而用GZIPOutputStream写数据的时候,是把数据写到ByteArrayOutputStream上的,等会还要把数据取出来,再写给浏览器,于是就不能以匿名内部类的办法给GZIPOutputStream,必须把ByteArrayOutputStream定义出来,
//创建GZIPOutputStream工具,给予它ByteArrayOutputStream ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream); //GZIP对数据压缩,GZIP写入的数据是保存在byteArrayOutputStream上的 gzipOutputStream.write(ss.getBytes()); //gzipOutputStream有缓冲,把缓冲清了,并顺便关闭流 gzipOutputStream.close();把压缩后的数据取出来,写给浏览器
//将压缩的数据取出来 byte[] bytes = byteArrayOutputStream.toByteArray(); //将压缩的数据写给浏览器 response.getOutputStream().write(bytes);我们来比拟一下压缩前的大小和压缩后的大小
数据的确是压缩了,然而,为什么又乱码了啊?很大略,既然你压缩了数据,你写给浏览器,浏览器是不知道你这是压缩后的数据,它因此正常的办法打开数据的。这当然造成乱码啦!,现在我要见告浏览器我这是压缩数据
//见告浏览器这是gzip压缩的数据 response.setHeader(\"大众Content-Encoding\"大众,\"大众gzip\公众); //再将压缩的数据写给浏览器 response.getOutputStream().write(bytes);再次访问一下
生出随机图片
天生随机图片这是非常常见的。在我们上岸的时候常常要写验证码,而那些验证码是一张图片,便是通过HttpServletResponse写给浏览器的。
要天生一张图片,java供应了BufferedImage类供我们利用//在内存中天生一张图片,宽为80,高为20,类型是RGB BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB); //获取到这张图片 Graphics graphics = bufferedImage.getGraphics(); //往图片设置颜色和字体 graphics.setColor(Color.BLUE); graphics.setFont(new Font(null, Font.BOLD, 20)); //往图片上写数据,先写个12345,横坐标是0,纵坐标是20【高度】 graphics.drawString(\"大众12345\"大众, 0, 20);好的,现在我们在内存中创建了一张图片,并写上了12345。接着,我们要把图片写给浏览器了。把图片写给浏览器,java又供应了图片流【ImageIO】给我们利用
//要往浏览器写一张图片,那要见告浏览器回送的类型是一张图片 response.setHeader(\"大众ContentType\"大众, \"大众jpeg\公众); //java供应了图片流给我们利用,这是一个工具类 //把图片传进去,类型是jpg,写给浏览器 ImageIO.write(bufferedImage, \"大众jpg\公众, response.getOutputStream());我们来访问一下,看下图片长什么样
这样太丑了,我们把背景改成白色看看//把白色添补整张图片 graphics.setColor(Color.white); graphics.fillRect(0, 0, 80, 20);再看看效果,这明显好看多了
好的,我们的图片数字不可能是人工写的,数字该当是随机产生的!这个就大略了。现在我要天生7位的随机数,天生随机数的方法如下
private String makeNum() { Random random = new Random(); //这样就会天生0-7位的随机数,现在问题又来了,如果随机数不足7位呢?如果不足7位,我们加到7位就行了 int anInt = random.nextInt(9999999); //将数字转成是字符串 String num = String.valueOf(anInt); //判断位数有多少个,不足就加 StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < 7 - num.length(); i++) { stringBuffer.append(\公众0\"大众); } return stringBuffer.append(num).toString(); }如果要天生中文,就找中文映射表即可。
重定向跳转
什么是重定向跳转呢?点击一个超链接,关照浏览器跳转到其余的一个页面就叫重定向跳转。是关照浏览器去跳转,这很主要。页面之间的跳转有两种办法:重定向和转发,至于什么时候用重定向,什么用转发,我在讲完HttpServletRequest工具的时候会详细解释。
我们来利用以下HttpServletResponse工具的重定向//重定向到index.jsp页面 response.sendRedirect(\"大众/zhongfucheng/index.jsp\"大众);在浏览器的地址栏访问Servlet222
跳转到index.jsp页面,地址栏发生了变革我们再来看看http协议发生了什么从图上看,我们看到了两个状态码,一个是302。一个是200。302状态码在http协议中代表的是临时重定向。举个例子:我找纪律委员说:给我一份请假表,我要回家。纪律委员见告我:我这里没有请假表,你去找辅导员吧。再看回我访问Sevlet222时:我找Servlet222,Servlet222见告浏览器:我没有你想要的资源,你要的资源在index.jsp页面中,你自己去找吧。很随意马虎看出重定向是通过302状态码和跳转地址实现的。于是乎,我们设置http头就可以实现重定向跳转//设置状态码是302 response.setStatus(302); //HttpServletResponse把常用的状态码封装成静态常量了,以是我们可以利用SC_MOVED_TEMPORARILY代表着302 response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); //跳转的地址是index.jsp页面 response.setHeader(\"大众Location\"大众, \公众/zhongfucheng/index.jsp\"大众);实在sendRedirect()方法便是对setStatus()和setHeader()进行封装,事理便是setStatus()和setHeader()
getWriter和getOutputStream细节
getWriter()和getOutputStream()两个方法不能同时调用。如果同时调用就会涌现非常Servlet程序向ServletOutputStream或PrintWriter工具中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作相应的正文,然后再与相应状态行和各相应头组合后输出到客户端。Servlet的serice()方法结束后【也便是doPost()或者doGet()结束后】,Servlet引擎将检讨getWriter或getOutputStream方法返回的输出流工具是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流工具.原文地址:https://dwz.cn/sFsoifui作者:Java3y