Web服务器收到客户端的http请求,会针对每一次的请求,分别创建一个用于代表请求的request对象和response对象。我们要获取客户端提交的数据,只需要找request对象。要向客户端输出数据,只需要找response对象。
一、常用方法
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。
(1)负责向客户端发送数据的方法
(2)负责向客户端发送响应头的方法
(3)负责向客户端发送响应状态码的方法
(4)响应状态码的常量
HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:
二、使用OutputStream流向客户端浏览器输出中文数据
使用OutputStream流输出中文注意问题:
在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开,比如:outputStream.write("中国".getBytes("UTF-8"));使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出,此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码,那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?可以通过设置响应头控制浏览器的行为,例如:response.setHeader("content-type", "text/html;charset=UTF-8");通过设置响应头控制浏览器以UTF-8的编码显示数据。
private void dealReq(HttpServletRequest req,HttpServletResponse resp) throws IOException{ resp.setHeader("Content-type","text/html;charset=UTF-8"); String data = "中国"; OutputStream out = resp.getOutputStream(); //data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表。 //如果是中文的操作系统环境,默认就是查找查GB2312的码表, 将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字 out.write(data.getBytes("UTF-8")); } }
三、使用PrintWriter流向客户端浏览器输出中文数据
使用PrintWriter流输出中文注意问题:
在获取PrintWriter输出流之前首先使用"response.setCharacterEncoding(charset)"设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒,如下:
private void dealReq(HttpServletRequest req,HttpServletResponse resp) throws IOException{ //设置Response使用的码表,以控制response以什么码表向浏览器写出数据 resp.setCharacterEncoding("UTF-8"); //指定浏览器以什么码表打开服务器发送的数据 resp.setHeader("Content-type","text/html;charset=UTF-8"); String data = "今天小雨吖"; PrintWriter out = resp.getWriter(); out.write(data); out.flush(); out.close(); } }
四、文件的下载
文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载
文件下载功能的实现思路:
1.获取要下载的文件的绝对路径。
2.获取要下载的文件名。
3.设置content-disposition响应头控制浏览器以下载的形式打开文件。
4.获取要下载的文件输入流。
5.创建数据缓冲区。
6.通过response对象获取OutputStream流。
7.将FileInputStream流写入到buffer缓冲区。
8.使用OutputStream将缓冲区的数据输出到客户端浏览器。
/* * 实现文件的下载 */ public class DownloadServlet extends HttpServlet{ private OutputStream fos; private FileInputStream fis; public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ ///1.获取要下载的文件的绝对路径 String realPath = this.getServletContext().getRealPath("/download/1.jpg"); //2.获取要下载的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\") + 1) ; /* * 1.设置content-disposition响应头控制浏览器以下载的形式打开文件 * 2.下载中文文件,中文文件下载时,文件名要经过URL编码,否则会出现文件名乱码 */ resp.setHeader("content-disposition","attachment;filename=" + URLEncoder.encode(fileName,"UTF-8")); try{ fos = resp.getOutputStream(); fis = new FileInputStream(realPath); int len = 0; byte[] buffer = new byte[1024]; while((len = fis.read(buffer)) != -1){ //使用OutputStream将缓冲区的数据输出到客户端浏览器 fos.write(buffer,0,len); } }finally{ if(fis != null){ try{ fis.close(); }catch(Exception e){ e.printStackTrace(); } } if(fos != null){ try{ fos.close(); }catch(Exception e){ e.printStackTrace(); } } } } public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ } }
五、随机验证码
<html> <head> <title>验证信息</title> <script type="text/javascript"> function changeImg() { document.getElementById("validateCodeImg").src = "RandomImgServlet?" + Math.random(); } </script> </head> <body> <form action="ValidateServlet" method="post"> 请输入验证码:<input type="text" name="validateCode"> <img alt="验证码看不清,换一张" src="RandomImgServlet" id="validateCodeImg" onclick="changeImg()"> <a href="javascript:void(0)" onclick="changeImg()">看不清,换一张</a> <br /> <input type="submit" value="提交"> </form> </body> </html>
public class RandomImgServlet extends HttpServlet{ public static final int AUTHCODE_LENGTH = 5; // 验证码长度 public static final int SINGLECODE_WIDTH = 15; // 单个验证码宽度 public static final int SINGLECODE_HEIGHT = 30; // 单个验证码高度 public static final int SINGLECODE_GAP = 4; // 单个验证码之间间隔 public static final int IMG_WIDTH = AUTHCODE_LENGTH * (SINGLECODE_WIDTH + SINGLECODE_GAP); public static final int IMG_HEIGHT = SINGLECODE_HEIGHT; private static String randString = "01234456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static int srtLen = randString.length(); public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ String authCode = getAuthCode(); // 将验证码保存到session中,便于以后验证 request.getSession().setAttribute("checkCode",authCode); try{ // 发送图片 ImageIO.write(getAuthImg(authCode),"JPEG",response.getOutputStream()); }catch(IOException e){ e.printStackTrace(); } } public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ doGet(req,resp); } public static String getAuthCode(){ String authCode = ""; for(int i = 0;i < AUTHCODE_LENGTH;i++){ int randNum = new Random().nextInt(srtLen); authCode += randString.substring(randNum,randNum + 1); } return authCode; } public static BufferedImage getAuthImg(String authCode){ // 设置图片的高、宽、类型 // RGB编码:red、green、blue BufferedImage img = new BufferedImage(IMG_WIDTH,IMG_HEIGHT,BufferedImage.TYPE_INT_BGR); // 得到图片上的一个画笔 Graphics g = img.getGraphics(); // 设置画笔的颜色,用来做背景色 g.setColor(Color.white); // 用画笔来填充一个矩形,矩形的左上角坐标,宽,高 g.fillRect(0,0,IMG_WIDTH,IMG_HEIGHT); // 将画笔颜色设置为黑色,用来写字 g.setColor(Color.BLACK); // 设置字体:宋体、不带格式的、字号 g.setFont(new Font("宋体",Font.PLAIN,SINGLECODE_HEIGHT + 5)); // 输出数字 char c; for(int i = 0;i < authCode.toCharArray().length;i++){ // 取到对应位置的字符 c = authCode.charAt(i); // 画出一个字符串:要画的内容,开始的位置,高度 g.drawString(c + "",i * (SINGLECODE_WIDTH + SINGLECODE_GAP) + SINGLECODE_GAP / 2,IMG_HEIGHT); } Random random = new Random(); // 干扰素 for(int i = 0;i < 20;i++){ int x = random.nextInt(IMG_WIDTH); int y = random.nextInt(IMG_HEIGHT); int x2 = random.nextInt(IMG_WIDTH); int y2 = random.nextInt(IMG_HEIGHT); g.drawLine(x,y,x + x2,y + y2); } return img; } }
public class ValidateServlet extends HttpServlet{ public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ String clientCode = req.getParameter("validateCode"); String serverCode = (String)req.getSession().getAttribute("checkCode"); if(clientCode.equals(serverCode)){// 将客户端验证码和服务器端验证比较,如果相等,则表示验证通过 this.getServletContext().getRequestDispatcher("/success.jsp").forward(req,resp); }else{ this.getServletContext().getRequestDispatcher("/error.jsp").forward(req,resp); } } public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ doGet(req,resp); } }