response对象
一】原理
1)web容器(tomcat等)会传入与web容器相关的HttpServletRequest和HttpServletResponse的实现。
2)每一次浏览器的请求web服务器都会创建一个新的HttpServletReques和ServletResponse对象,并且
这两个对象的声明周期仅限于web容器内。
二】response对象常用方法
1》setStatues
2》setHeader
3》getWriter
4》getOutputStream
三】response常见应用
1)向浏览器输出数字
原理:
无论是ServletOutputStream对象还是ServletWrite对象的write(int c);方法
都会自动将c去查询iso8859-1编码表,并取出相应的字符传送到客户端,
所以输入的是数字,客户端得到的却是对应的字符。
解决办法:
将数字转换成字符串,再通过字符串的形式进行输出。
又因为OutputStream对象write()方法参数中不支持对字符串的输出,所以需要通过getBytes方法进行转换
而ServletWriter的write()方法参数支持字符串的输出,所以可以直接输出,不必转换
code:
response.getOutputStream().write(97);//a response.getWriter().write(65);//A response.getOutputStream().write((97+"").getBytes());//97 response.getWriter().write(65+"");//65
2)向浏览器输出中文字符【重点】
原因:
1》byte[] getBytes();方法在进行编码的时候会按照当前的编码方式进行编码
2》byte[] getBytes(String charset);方法在进行编码的时候会按照指定的编码方式进行编码
3》而iso8859-1不支持中文字符的编码,所以,在进行编码的时候需要指定能够编码中文字符的编码方式。
注意:在以字符流方式输出中文到客户端,需要提前告诉客户端用utf-8去接受。
code:
//1,输出数字 字节流方式 response.getOutputStream().write(97);//a response.getWriter().write(65);//A response.getOutputStream().write((97+"").getBytes());//97 response.getWriter().write(97+""); //2,输出中文字符 【两种方式:重点】 response.getOutputStream().write("中国".getBytes("utf-8")); or response.setContentType("text/html;charset=utf-8"); response.getWriter().write("美国");
3)设置响应头发送给客户端【重点】
当遇到中文字符的时候,需要使用URLEncoder类的静态方法使用指定的编码机制将字符串转换为客户端浏览器能正确解析的编码方式。
方法原型:
String encode(String s, String enc);
code:
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(file.getName(), "utf-8"));
补充:
HTML中的所有<meta>标签,类似于response.setHeader(),目的是通知浏览器以特定的页面方式显示页面信息
四】response案例----制作验证码
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置客户端禁止缓存 response.setHeader("expires", "-1"); response.setHeader("cache-control", "no-cache"); response.setHeader("pragma", "no-chche"); // 在内存中构造一幅图片 BufferedImage image = new BufferedImage(600, 50, BufferedImage.TYPE_INT_RGB); // 得到一个画笔 Graphics graph = image.getGraphics(); // 指定画笔的参数 graph.setColor(Color.red); graph.setFont(new Font("黑体", Font.BOLD, 16)); // 将指定的字符串绘在图上 graph.drawString(getString(), 20, 20);// 坐标 //将内存中的图片输出到指定的流中 ImageIO.write(image, "JPG", response.getOutputStream()); } // 产生一个随机字符串 private String getString() { String str = ""; String numberAndLetter = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; int length = numberAndLetter.length(); for (int i = 1; i <= 4; i++) { if (i == 1 || i == 3) {// 数字 while (true) { Random random = new Random(); int index = random.nextInt(length); String value = numberAndLetter.substring(index, index + 1); if (value.matches("[0-9]")) { str += value; break; } } } else if (i == 2 || i == 4) {// 大小字母 while (true) { Random random = new Random(); int index = random.nextInt(length); String value = numberAndLetter.substring(index, index + 1); if (value.matches("[A-Za-z]")) { str += value; break; } } } } return str; } 或者 public class Demo3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置客户端禁止缓存 response.setHeader("expires", "-1"); response.setHeader("cache-control", "no-cache"); response.setHeader("pragma", "no-chche"); //在内存中构造一幅图片 BufferedImage img = new BufferedImage(200,300,BufferedImage.TYPE_INT_RGB); //获得在图中的画笔 Graphics graph = img.getGraphics(); //在图片中画上验证码 graph.drawString(getString(), 20, 20); ImageIO.write(img, "JPG", response.getOutputStream()); } private String getString() { Random random = new Random(System.currentTimeMillis()); String str = null; String str_1 = random.nextInt(10)+""; String str_2 = (char)(random.nextInt(26)+random.nextInt(2)*('a'-'A')+'A')+""; String str_3 = random.nextInt(10)+""; String str_4 = (char)(random.nextInt(26)+random.nextInt(2)*('a'-'A')+'A')+""; System.out.println("str_1 = " + str_1); System.out.println("str_2 = " + str_2); System.out.println("str_3 = " + str_3); System.out.println("str_4 = " + str_4); str = str_1+str_2+str_3+str_4; return str; } }
·知识点补充
1)BufferedImage类 ----在内存中构建一幅图片
重点方法:
1》构造方法:
BufferedImage(int width, int height, int imageType);
参数:
width :构造的图片的宽度
height:构造的图片的宽度
imageType:构造的图片的类型 --取的只是此类的字段
2》取得一个图片的画笔,可以对这个图片进行绘画
Graphics getGraphics();
2)Graphics类: --- 画笔类
重点方法:
void setColor(Color c);//指定颜色
void setFont(Font font);//指定字体
void drawString(String str, int x, int y);
//使用此图形上下文的当前字体和颜色绘制由指定 string 给定的文本
//X和Y代表的是绘制出的内容的坐标
3)Font类:
重点方法
1》构造函数:
Font(String name, int style, int size);
参数:
name:字体名称 ”隶书“等
style: Font的样式常量。
size: 字体的大小
4)ImageIO类
重点方法:
static boolean write(图片类对象,"将内存中的图片以什么格式输出",OuputStream os);
参数:
os:图片通过哪个流输出
eg:
//以内存中构造一副图片
BufferedImage image = new BufferedImage(80,25,BufferedImage.TYPE_INT_RGB);
//取得画笔
Graphics g = image.getGraphics();
//设置字体大小和颜色
g.setColor(Color.YELLOW);
g.setFont(new Font("黑体",Font.BOLD,22));
//在图片中,画一个字符串"1A2B"
g.drawString(getString(),20,20);
//将内存中的图片以JPG格式输出到浏览器
ImageIO.write(image,"JPG",response.getOutputStream());
5)UUID类:产生随机的字符串---很随机!!!
重点方法:
static UUID randomUUID();//获取类型 4(伪随机生成的)UUID 的静态工厂
Sring toString();//返回表示此 UUID 的 String 对象、
应用:
获取一个随即字符串的方法:
String random_str = UUID.randomUUID().toString;
五】response案例----转发
六】response案例----重定向
函数原型:
void sendRedirect(java.lang.String location)
code:
七】关于方法重复使用的细节
1》关于输出流:使用字节和字符输出内容到服务器,只能使用其中一种。否则抛出IllegalStateException
原因:
当使用其中一种方式输出完毕并不再用这种方式输出之后,response对象马上被销毁了,这时候便不能使用它来调用方法了。
2》当定义了相同的消息头的时候,后者定义的消息头会覆盖掉前面的消息头,即后则起决定作用。
code:
response.setContextType("text/html;charset=iso8859-1");
response.setContextType("text/html;charset=gbk");
response.getWriter().write("中国");
3》在没有关闭流的情况下,web容器的引擎会自动关闭由response对象取得的不再使用的流。
但是其他的普通流并不会自动关闭。
补充:要明白转发和重定向的区别,详见图。