Servlet深入服务之响应response

HttpServletResponse与HttpServletRequest
Web服务器收到哭护短的http请求时,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象,获取客户机提交过来的数据,只需要找到request对象即可,要向客户机输出数据只需要找到response对象即可,HTTP请求时,对应的对象是HttpServletRequest封装请求数据,HTTP响应的时候对应的对象是HttpServletResponse封装响应数据。

HttpServletResponse接口
常用API方法
setStatus(int sc)设置状态码
setHeader(String name,String value)设置头信息
addHeader(String name,String value)当头信息存在多个值时使用这个方法添加值。
getWriter();//获取字符写入流
getOutreponse();//获取字节输出流。
这四个方法可以生成响应头信息的所有内容
要知道在JavaEE中并没有提供这两个接口的实现类,这些实现类是在服务器中完成的。从这里可以看出以后由于框架等外部环境的应用面向对象编程要向面向接口编程转换。

重定向功能的实现
两种方法
1,通过传统方式更改响应头信息Status和location
response.setStatus(302);
response.setHeader("location",url)url是绝对路径且要包含根目录
2,使用封装好的方法sendRedirect
response.sendRedirect(url)

自动刷新的实现
通过更改响应头信息refresh
response.setHeader("refresh",time,url);

注意HTML中有个<meta>标签可以模拟头信息
name属性指定关键词,content指定关键词的内容。之前百度关键词搜索就是通过这样指定关键词,通过扒取关键词来确定网页信息,但是这种方式可以人为指定关键词所以信息经常不正确,现在是开始扒取整体网页的数据来搜素关键词。
http-equiv属性指定协议状态模拟信息头,content指定时间,url指定协议访问地址。这样一般用来自动跳转网页。

禁止浏览器缓存的实现
缓存是保存在浏览器的临时文件中的,本地缓存的坏处是对于Servlet动态程序设计经常需要改变的网页来说,如果浏览器中有缓存的话,是优先访问缓存的,这样就不能做到实时动态的更新
Expires:-1//设置过期时间,-1是禁止缓存,正常日期格式是缓存有效时间
Cache-Control:NoCache
program:Nocache//这三个是一起使用的用来控制客户端是否进行缓存,对于动态的资源应该禁止缓存。之所以三句是为了解决浏览器的兼容问题的。

response输出流字符编码问题
1,获取输出流对象
OutputStream out=response。getOutputStream();字节流
PrintWriter pw=response.getWriter();字符流
2.指定body内容的类型
setContentType("text/html;charset=utf-8");
3,指定输出数据的编码格式
setCharacterEncoding("");//此方法与上面的方法的区别在于此方法只能设置响应内容的编码但是无法设置浏览器的查看编码,上面的方法是可以设置浏览器查看编码的,因为此方法不能封装在头信息中,ContentType是封装在响应头信息中的,开发中使用setContentType方法之后就不再使用setCharaterEncoding方法。
默认情况下编码格式是ISO-8859-1;
需要注意的是2和3一定要写在1获取流对象之前,将编码封装进流中。getOutputStream和getWriter是存在缓冲的,在service方法结束时会自动关闭流,flsuh缓冲内容。

实现response文件下载
Content-Type:text/html,charsetGB2132---响应数据类型,响应数据类型采用Mime协议规定默认类型html文件,在tomcat/conf/web.xml中可以查看
相关响应头信息,Content-Disposition:attachment;filename=aaa.zip;----文件下载时指定文件附件名称
实现下载的两种方式
第一种:通过超链接完成文件下载
在HTML中直接超链接指定文件路径,这种方式如果浏览器能够识别文件的话,是直接打开文件是下载不下来的,只有不能识别的文件格式才会下载
第二种:通过Servlet程序完成

1.超链接指向Servlet程序,并通过?号附带文件参数信息
<a href="url?filename">
2.通过request获取文件名
String filename=request.getParameter("filename");
3.设置头信息指定文件类型//写法基本上固定。
response.setContentType(getServletContext().getMimeType(filename));
response.setHeader("Content-Dispositon","attachment;filename="+filename);
4.绝对磁盘路径读取文件
String realFilename=getServletContext().getRealPath("根目录+filename");
InputStream in=new FileInputStream(realFilename);
OutputStream out=response.getOutputStream();
int b;
while((b=in.read())!=-1){
  out.write(b);
}
in.close()
out.close()//这个响应流是自动关的可以不写

实现验证码输出案例
通过java图形API生成验证码图片

//创建一张内存中的缓冲图片
//image是JAVA中用于操作图形的类。
//width,height是像素,imageType是图片类型,封装在Image内部的静态字段
BufferedImage bufferedImage=new BufferedImage(width,height,imageType);
//背景色;绘图的过程其实是上色的过程。默认初始背景色是黑色。
//Graphics绘制画笔的封装类
Graphics graphics=BufferedImage.getGraphics();
graphics.setColor(Color.YELLOW);//设置画笔颜色
graphics.fillRect(0,0,width,height)//填充矩形,参数是四个方向的坐标
graphics.setColor(Color.BLUE);
graphics.drawRect(0,0,widt-1,height-1);绘制矩形边框
//写验证内容
String Content="ABCDEFGHIJK1234567890"
graphics.setColor(Color.Red);
graphics.setFont(new Font(name,style,size));
//将验证码随机从content中抽取
Random random=new Random();
for(int i=0;i<4,i++){
  int index=random.nextInt(content.length());
  char letter=content.charAt(index);
  graphics.drawString(letter+"",x,y);
  x+=30
}
//绘制随机干扰线,需要两个点的坐标
graphics.setColor(Color.LIGHT_GRAY);
int x1,x2,y1,y2;
forint i=0,i<20;i++){
  x1=random.nextInt(width);
  x2=random.nextInt(width);
  y1=random.nexInt(height);
  y2=random.nextInt(height);
  graphics.drawLine(x1,y1,x2,y2);
}
//释放内存中图形资源。
graphics.dispose();
//通过图片IO流写入响应流中的输出流并生成jpg格式的图片
ImageIO.write(BufferedImage,"jpg",response.getOutputStream);
之后就是在HTML文件中配置
在<img src="Servleturl" onclik="change()" id="" style="cusor pointer">更改style属性,鼠标放上去会变成手指。
<script>
  function change(){
      document.getElementById().src="Servleturl?"+new Date().getTime();//重新加载路径,记得要禁止缓存。在路径后面加入当前的时间也是解决缓存问题的方法。
}
</script>
原文地址:https://www.cnblogs.com/ss561/p/4618043.html