response学习

response:doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response,其response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大。

一、response的运行过程



二、抓取响应内容,共包括响应行,响应头,响应体



三、response分别设置三个部分

1)response.setStatus(1002);  设置响应行(状态码)

2)设置响应头

addHeader(String name,String value)    字符串

addIntHeader(String name, int value)      int

addDateHeader(String name, long date)   时间

setHeader(String name,String value) 

setDateHeader(String name, long date) 

setIntHeader(String name, int value)

其中,add表示添加,而set表示设置

3)设置响应体 共有两个输出流 两个输出流不能同时调用 

getWriter();

getOutputStream();

若输出中文, 通过一个头content-type告知客户端使用哪个码表

具体代码检测如下:

public class Test extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1设置相应行(状态码)
		response.setStatus(302);
		
		//2设置响应头
		//添加
		response.addHeader("cai","cccc");
		response.addIntHeader("cai1",100);
		response.addDateHeader("cai2",89564423);
		//修改
		response.setHeader("cai","lii");
		
		//3设置响应体
		/*
		 * 输出中文:通过一个头content-type告知客户端使用哪个码表
		response.setHeader("Content-Type","text/html;charset-UTF-8");
		或调用下面的方法
		response.setContentType("text/html;charset=UTF-8");	//已经封装好的方法
		
		PrintWriter writer = response.getWriter();
		writer.write("你好");
		*/
		
		//输出图片
		//获得图片 不能同时get两个流 会报错	
		ServletOutputStream out = response.getOutputStream();		//获取字节输出流
		String realPath = this.getServletContext().getRealPath("timg.jpg");	//使用字符串 获取图片的绝对路径
		InputStream in = new FileInputStream(realPath);					//输入流 输入的对象   获取字节
		//输出
		int len = 0;
		byte[] buffer = new byte[1024];
		while((len=in.read(buffer))>0)	//如果还能输入流读取数据 输出流写数据
		{
			out.write(buffer,0,len);	//还有多少个就输出多少个
		}
		in.close();
		out.close();
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

重定向 如果a地址没有资源,则告知服务器到b去找  

设置方法:

1:状态码302   2:响应头:location重定向地址


定时刷新的本质也是重定向



四、利用response完成下载案例

理论上 浏览器可以解析的文件类型,会自动被解析,所以需要编写文件下载代码  实际上需要下载的文件都要编写

下载实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。

所以文件下载需 IO技术将服务器端的文件使用InputStream读取到,在使用 ServletOutputStream写到response缓冲区中

现有html如下,点击标签 跳转到/download servlet 并传入参数req

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="/web14/download?req=a.flv">a.flv</a><br>
	<a href="/web14/download?req=a.jpg">a.jpg</a><br>
	<a href="/web14/download?req=a.mp3">a.mp3</a><br>
	<a href="/web14/download?req=a.mp4">a.mp4</a><br>
	<a href="/web14/download?req=a.txt">a.txt</a><br>
	<a href="/web14/download?req=a.zip">a.zip</a><br>
	<a href="/web14/download2?req=美女.jpg">美女.jpg</a><br>
</body>
</html>
编写download这个servlet 如下
public class Downloadservlet extends HttpServlet {
       
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//从请求中获得点击的参数
		String req = request.getParameter("req");
		//获取所查找的文件的绝对路径
		String realPath = this.getServletContext().getRealPath("download/"+req);
		
		//如果此时是图片等被解析的文件类型 需要告知客户端下载
		//要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
		response.setContentType(this.getServletContext().getMimeType(req));
		//告诉客户端该文件不是直接解析 而是以附件形式打开(下载)
		response.setHeader("Content-Disposition", "attachment;filename="+req);
		
		//输入流和输出流
		InputStream in = new FileInputStream(realPath);//读取客户端的字节
		ServletOutputStream out = response.getOutputStream();
		
		//输出
		int len = 0;
		byte[] buffer = new byte[1024];
		while((len=in.read(buffer))>0)	//如果还能输入流读取数据 输出流写数据
		{
			out.write(buffer,0,len);	//还有多少个就输出多少个
		}
		in.close();	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}


如果文件名称为中文,编码和解码查的码表不同,此时会出现乱码,利用编码解决问题 代码如下

public class DownloadChinese extends HttpServlet {
       
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//下载中文
		//从请求中获得点击的参数
		String req = request.getParameter("req");
		req = new String(req.getBytes("ISO8859-1"),"UTF-8");//将请求的名字编码为中文,然后找寻资源
		String realPath = this.getServletContext().getRealPath("download/"+req);
		//此时可以找寻到对象,但是下载时候没有名称,只有后缀名
		
		//如果不加编码 下载的时候仅有后缀,没有文件名,此时用如下代码对该资源进行编码,则解码后刚好为所需中文
		//获得请求头中的User-Agent
		String agent = request.getHeader("User-Agent");
		//根据不同浏览器进行不同的编码
		String filenameEncoder = "";
		if (agent.contains("MSIE")) {
			// IE浏览器
			filenameEncoder = URLEncoder.encode(req, "utf-8");
			filenameEncoder = filenameEncoder.replace("+", " ");
		} else {
			// 其它浏览器
			filenameEncoder = URLEncoder.encode(req, "utf-8");	
		}
		
		
		response.setContentType(this.getServletContext().getMimeType(req));
		response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);	//文件名修改为编码后的
		InputStream in = new FileInputStream(realPath);
		ServletOutputStream out = response.getOutputStream();
		int len = 0;
		byte[] buffer = new byte[1024];
		while((len=in.read(buffer))>0)	
		{
			out.write(buffer,0,len);	
		}
		in.close();	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}


五、实现验证码功能代码

编写html如下

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	window.onload = function(){
		
	}
	
	function changeImg(obj){
		obj.src="/web14/checkImg?time="+new Date().getTime();
	}
</script>
</head>
<body>
	<form action="/web14/Login" method="post">	<!-- 不能点击 -->>
		用户名:<input type="text"name="username"><br/>
		密码:<input type="password"name="password"><br/>
		验证码:<input type="text" name="username"><img onclick="changeImg(this)" src="/web14/checkImg"><br/>	<!-- 点击刷新 -->
		<input type="submit"value="登录"><br/>
	</form>
</body>
</html>

servlet 代码如下,流程为 绘画一张验证码 利用response写到浏览器

public class CheckImgServlet extends HttpServlet {
       
	/*// 现有一个txt中存着成语,使用集合中保存所有成语
		private List<String> words = new ArrayList<String>();

		@Override
		public void init() throws ServletException {
			// 初始化阶段,读取new_words.txt
			// web工程中读取 文件,必须使用绝对磁盘路径
			String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
			try {
				BufferedReader reader = new BufferedReader(new FileReader(path));
				String line;
				while ((line = reader.readLine()) != null) {
					words.add(line);
				}
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}*/
		
	/**
	 * 取其某一范围的color
	 * 
	 * @param fc
	 *            int 范围参数1
	 * @param bc
	 *            int 范围参数2
	 * @return Color
	 */
	private Color getRandColor(int fc, int bc) {
		// 取其随机颜色
		Random random = new Random();
		if (fc > 255) {
			fc = 255;
		}
		if (bc > 255) {
			bc = 255;
		}
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		int width = 120;
		int height = 30;

		// 步骤一 绘制一张内存中图片
		BufferedImage bufferedImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);

		// 步骤二 图片绘制背景颜色 ---通过绘图对象
		Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
		// 绘制任何图形之前 都必须指定一个颜色
		graphics.setColor(getRandColor(200, 250));
		graphics.fillRect(0, 0, width, height);

		// 步骤三 绘制边框
		graphics.setColor(Color.WHITE);
		graphics.drawRect(0, 0, width - 1, height - 1);

		// 步骤四 四个随机数字
		Graphics2D graphics2d = (Graphics2D) graphics;
		// 设置输出字体
		graphics2d.setFont(new Font("宋体", Font.BOLD, 18));

		Random random = new Random();// 生成随机数
		
		/*int index = random.nextInt(words.size());
		String word = words.get(index);// 获得成语*/

		String word = ""+random.nextInt(10)+random.nextInt(10)+random.nextInt(10)+random.nextInt(10);
		
		// 定义x坐标 开始画四个数字
		int x = 10;	//第一个的位置
		for (int i = 0; i < word.length(); i++) {
			// 随机颜色
			graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
			// 旋转 -30 --- 30度
			int jiaodu = random.nextInt(60) - 30;
			// 换算弧度
			double theta = jiaodu * Math.PI / 180;

			// 获得字母数字
			char c = word.charAt(i);

			// 将c 输出到图片
			graphics2d.rotate(theta, x, 20);
			graphics2d.drawString(String.valueOf(c), x, 20);
			graphics2d.rotate(-theta, x, 20);
			x += 30;
		}

		// 将验证码内容保存session 用于验证
		request.getSession().setAttribute("checkcode_session", word);

		// 步骤五 绘制干扰线
		graphics.setColor(getRandColor(160, 200));
		int x1;
		int x2;
		int y1;
		int y2;
		for (int i = 0; i < 30; i++) {
			x1 = random.nextInt(width);
			x2 = random.nextInt(12);
			y1 = random.nextInt(height);
			y2 = random.nextInt(12);
			graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
		}
		// 将上面图片输出到浏览器 ImageIO
		graphics.dispose();// 释放资源

		//将图片写到response.getOutputStream()中
		ImageIO.write(bufferedImage, "jpg", response.getOutputStream());	
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}





猜你喜欢

转载自blog.csdn.net/cairuojin/article/details/80145304