HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。
HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:
状态码404对应的常量
状态码200对应的常量
状态码500对应的常量
使用OutputStream流输出中文注意问题:
在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开,比如:outputStream.write("中国".getBytes("UTF-8"));使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出,此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码,那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?可以通过设置响应头控制浏览器的行为,例如:response.setHeader("content-type", "text/html;charset=UTF-8");通过设置响应头控制浏览器以UTF-8的编码显示数据。
使用PrintWriter流输出中文注意问题:
在获取PrintWriter输出流之前首先使用"response.setCharacterEncoding(charset)"设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒,如下:
1 response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器 2 /** 3 * PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后 4 * 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码 5 */ 6 PrintWriter out = response.getWriter();//获取PrintWriter输出流
然后再使用response.setHeader("content-type", "text/html;charset=字符编码");设置响应头,控制浏览器以指定的字符编码编码进行显示,例如:
1 //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码 2 response.setHeader("content-type", "text/html;charset=UTF-8");
除了可以使用response.setHeader("content-type", "text/html;charset=字符编码");设置响应头来控制浏览器以指定的字符编码编码进行显示这种方式之外,还可以用如下的方式来模拟响应头的作用
1 /** 2 * 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为 3 *response.getWriter().write("<meta http-equiv=‘content-type‘ content=‘text/html;charset=UTF-8‘/>"); 4 * 等同于response.setHeader("content-type", "text/html;charset=UTF-8"); 5 */ 6 response.getWriter().write("<meta http-equiv=‘content-type‘ content=‘text/html;charset=UTF-8‘/>");
文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载
文件下载功能的实现思路:
1.获取要下载的文件的绝对路径
2.获取要下载的文件名
3.设置content-disposition响应头控制浏览器以下载的形式打开文件
4.获取要下载的文件输入流
5.创建数据缓冲区
6.通过response对象获取OutputStream流
7.将FileInputStream流写入到buffer缓冲区
8.使用OutputStream将缓冲区的数据输出到客户端浏览器
package gacl.response.study; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author gacl * 文件下载 */ public class ResponseDemo02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { downloadFileByOutputStream(response);//下载文件,通过OutputStream流 } /** * 下载文件,通过OutputStream流 * @param response * @throws FileNotFoundException * @throws IOException */ private void downloadFileByOutputStream(HttpServletResponse response) throws FileNotFoundException, IOException { //1.获取要下载的文件的绝对路径 String realPath = this.getServletContext().getRealPath("/download/1.JPG"); //2.获取要下载的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1); //3.设置content-disposition响应头控制浏览器以下载的形式打开文件 response.setHeader("content-disposition", "attachment;filename="+fileName); //4.获取要下载的文件输入流 InputStream in = new FileInputStream(realPath); int len = 0; //5.创建数据缓冲区 byte[] buffer = new byte[1024]; //6.通过response对象获取OutputStream流 OutputStream out = response.getOutputStream(); //7.将FileInputStream流写入到buffer缓冲区 while ((len = in.read(buffer)) > 0) { //8.使用OutputStream将缓冲区的数据输出到客户端浏览器 out.write(buffer,0,len); } in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),否则会出现文件名乱码。
package gacl.response.study; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 生成随机图片,用来作为验证码 */ public class DrawImage extends HttpServlet { private static final long serialVersionUID = 3038623696184546092L; public static final int WIDTH = 120;//生成的图片的宽度 public static final int HEIGHT = 30;//生成的图片的高度 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String createTypeFlag = request.getParameter("createTypeFlag");//接收客户端传递的createTypeFlag标识 //1.在内存中创建一张图片 BufferedImage bi = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB); //2.得到图片 Graphics g = bi.getGraphics(); //3.设置图片的背影色 setBackGround(g); //4.设置图片的边框 setBorder(g); //5.在图片上画干扰线 drawRandomLine(g); //6.写在图片上随机数 //String random = drawRandomNum((Graphics2D) g,"ch");//生成中文验证码图片 //String random = drawRandomNum((Graphics2D) g,"nl");//生成数字和字母组合的验证码图片 //String random = drawRandomNum((Graphics2D) g,"n");//生成纯数字的验证码图片 //String random = drawRandomNum((Graphics2D) g,"l");//生成纯字母的验证码图片 String random = drawRandomNum((Graphics2D) g,createTypeFlag);//根据客户端传递的createTypeFlag标识生成验证码图片 //7.将随机数存在session中 request.getSession().setAttribute("checkcode", random); //8.设置响应头通知浏览器以图片的形式打开 response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg"); //9.设置响应头控制浏览器不要缓存 response.setDateHeader("expries", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); //10.将图片写给浏览器 ImageIO.write(bi, "jpg", response.getOutputStream()); } /** * 设置图片的背景色 * @param g */ private void setBackGround(Graphics g) { // 设置颜色 g.setColor(Color.WHITE); // 填充区域 g.fillRect(0, 0, WIDTH, HEIGHT); } /** * 设置图片的边框 * @param g */ private void setBorder(Graphics g) { // 设置边框颜色 g.setColor(Color.BLUE); // 边框区域 g.drawRect(1, 1, WIDTH - 2, HEIGHT - 2); } /** * 在图片上画随机线条 * @param g */ private void drawRandomLine(Graphics g) { // 设置颜色 g.setColor(Color.GREEN); // 设置线条个数并画线 for (int i = 0; i < 5; i++) { int x1 = new Random().nextInt(WIDTH); int y1 = new Random().nextInt(HEIGHT); int x2 = new Random().nextInt(WIDTH); int y2 = new Random().nextInt(HEIGHT); g.drawLine(x1, y1, x2, y2); } } /** * 画随机字符 * @param g * @param createTypeFlag * @return * String... createTypeFlag是可变参数, * Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。注意:可变参数必须位于最后一项 */ private String drawRandomNum(Graphics2D g,String... createTypeFlag) { // 设置颜色 g.setColor(Color.RED); // 设置字体 g.setFont(new Font("宋体", Font.BOLD, 20)); //数字和字母的组合 String baseNumLetter = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ"; //纯数字 String baseNum = "0123456789"; //纯字母 String baseLetter = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; //createTypeFlag[0]==null表示没有传递参数 if (createTypeFlag.length > 0 && null != createTypeFlag[0]) { if (createTypeFlag[0].equals("ch")) { // 截取汉字 return createRandomChar(g, baseChineseChar); }else if (createTypeFlag[0].equals("nl")) { // 截取数字和字母的组合 return createRandomChar(g, baseNumLetter); }else if (createTypeFlag[0].equals("n")) { // 截取数字 return createRandomChar(g, baseNum); }else if (createTypeFlag[0].equals("l")) { // 截取字母 return createRandomChar(g, baseLetter); } }else { // 默认截取数字和字母的组合 return createRandomChar(g, baseNumLetter); } return ""; } /** * 创建随机字符 * @param g * @param baseChar * @return 随机字符 */ private String createRandomChar(Graphics2D g,String baseChar) { StringBuffer sb = new StringBuffer(); int x = 5; String ch =""; // 控制字数 for (int i = 0; i < 4; i++) { // 设置字体旋转角度 int degree = new Random().nextInt() % 30; ch = baseChar.charAt(new Random().nextInt(baseChar.length())) + ""; sb.append(ch); // 正向角度 g.rotate(degree * Math.PI / 180, x, 20); g.drawString(ch, x, 20); // 反向角度 g.rotate(-degree * Math.PI / 180, x, 20); x += 30; } return sb.toString(); } }
1 response.setDateHeader("expries", -1); 2 response.setHeader("Cache-Control", "no-cache"); 3 response.setHeader("Pragma", "no-cache");
1 response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次
请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。
应用场景:用户登陆,用户首先访问登录页面,登录成功后,就会跳转到某个页面,这个过程就是一个请求重定向的过程
实现方式:response.sendRedirect(String location),即调用response对象的sendRedirect方法实现请求重定向
sendRedirect内部的实现原理:使用response设置302状态码和设置location响应头实现重定向
使用PrintWriter流输出中文注意问题:
在获取PrintWriter输出流之前首先使用"response.setCharacterEncoding(charset)"设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒,如下:
1 response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器 2 /** 3 * PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后 4 * 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码 5 */ 6 PrintWriter out = response.getWriter();//获取PrintWriter输出流
然后再使用response.setHeader("content-type", "text/html;charset=字符编码");设置响应头,控制浏览器以指定的字符编码编码进行显示,例如:
1 //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码 2 response.setHeader("content-type", "text/html;charset=UTF-8");
除了可以使用response.setHeader("content-type", "text/html;charset=字符编码");设置响应头来控制浏览器以指定的字符编码编码进行显示这种方式之外,还可以用如下的方式来模拟响应头的作用
1 /** 2 * 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为 3 *response.getWriter().write("<meta http-equiv=‘content-type‘ content=‘text/html;charset=UTF-8‘/>"); 4 * 等同于response.setHeader("content-type", "text/html;charset=UTF-8"); 5 */ 6 response.getWriter().write("<meta http-equiv=‘content-type‘ content=‘text/html;charset=UTF-8‘/>");
原文:https://www.cnblogs.com/deityjian/p/11055361.html