Servlet总结(三)- 请求和响应对象概述

    HTTP协议包含请求和响应部分。HttpServletRequest就代表着请求部分,HttpServletResponse就代表着响应部分。

(一)HttpServletResponse详解

(1)中文乱码问题

产生乱码的原因:编码和解码的方式不一致导致产生乱码,英文不存在乱码问题。

解决方法:(1) 更改浏览器的查看编码(不可取)通知浏览器,使用的码表

                 (2)在响应头部设置编码格式,告诉浏览器用哪种方式来解析     

                        response.setHeader("Content-Type", "text/html;charset=UTF-8");

                        或者response.setContentType("text/html;charset=UTF-8");

(2)输出随机验证码

//输出随机验证码图片
public class ResponseDemo3 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-cache");
		
		int width = 120;
		int height = 25;
		//创建一副内存图像:BufferedImage
		BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		//得到属于该图片的画笔:Graphics
		Graphics g = image.getGraphics();
			//画边框
		g.setColor(Color.BLUE);
		g.drawRect(0, 0, width, height);
			//填充背景色
		g.setColor(Color.YELLOW);
		g.fillRect(1, 1, width-2, height-2);
			//画干扰线
		g.setColor(Color.GRAY);
		
		Random r = new Random();
		for(int i=0;i<10;i++)
			g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
		
			//随机数字
		g.setColor(Color.RED);
		g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 20));
		int x = 23;
		for(int i=0;i<4;i++){
			g.drawString(r.nextInt(10)+"", x, 20);
			x+=20;
		}
		//输出到浏览器的页面上:ImageIO
		ImageIO.write(image, "jpg", response.getOutputStream());
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}

(3)控制浏览器对响应数据不要缓存

//通知浏览器不要缓存
response.setHeader("Expires", "-1");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");

(4)控制缓存时间

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	//缓存1hour
	response.setDateHeader("Expires", System.currentTimeMillis()+60*60*1000);
	response.getWriter().write("hello");
}

(5)定时刷新

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	test2(response);
}
private void test2(HttpServletResponse response) throws IOException {
	response.setContentType("text/html;charset=UTF-8");
	PrintWriter out = response.getWriter();
	response.setHeader("Refresh", "2;URL=/day06/index.html");
	out.write("登录成功!2秒后将跳转到主页!若没有跳转,请猛点<a href='/day06/index.html'>这里</a>");
}

(6)文件下载(中文文件名的文件下载)

//中文文件下载
private void test2(HttpServletResponse response)
		throws FileNotFoundException, IOException {
	//得到要下载的文件
	ServletContext sc = getServletContext();
	String path = sc.getRealPath("/美女.jpg");//得到文件的真实路径。路径必须以"/"开头,"/"就代表者当前应用
	//截取文件名  C:\apache-tomcat-6.0.35\webapps\day06\美女.jpg
	String filename = path.substring(path.lastIndexOf("\\")+1);
	System.out.println(filename);
	//构建输入流
	InputStream in = new FileInputStream(path);
	//通知客户端以下载的方式打开
	response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename,"UTF-8"));//中文文件名此处要进行URL编码
	response.setHeader("Content-Type", "application/octet-stream");
	//response.getOutputStream()得到输出流
	OutputStream out = response.getOutputStream();
	int len = -1;
	byte b[] = new byte[1024];
	while((len=in.read(b))!=-1){
		out.write(b, 0, len);
	}
	in.close();
	out.close();
}
//最简单的文件下载
private void test1(HttpServletResponse response)
		throws FileNotFoundException, IOException {
	//得到要下载的文件
	ServletContext sc = getServletContext();
	String path = sc.getRealPath("/f.jpg");//得到文件的真实路径。路径必须以"/"开头,"/"就代表者当前应用
	System.out.println(path);
	//构建输入流
	InputStream in = new FileInputStream(path);
	//通知客户端以下载的方式打开
	response.setHeader("Content-Disposition", "attachment;filename=f.jpg");
	response.setHeader("Content-Type", "application/octet-stream");
	//response.getOutputStream()得到输出流
	OutputStream out = response.getOutputStream();
	int len = -1;
	byte b[] = new byte[1024];
	while((len=in.read(b))!=-1){
		out.write(b, 0, len);
	}
	in.close();
	out.close();
}
(7)请求重定向
public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.sendRedirect("/day06/login.html");//作用同上
}

注意:重定向后,第一个请求中response的对象输出的数据将会被清空,不会在客户端显示,会向重定向后的传递request对象和

清空后的response对象。

(8)HttpServletResponse细节:
字节流和字符流不能同时使用,互斥的。
通过字符流或字节流输出的数据并不是直接打给浏览器的。而是把数据写到response对象的缓存中的。服务器从缓存中取出数据,按照HTTP协议的响应格式输出给浏览器。
如果你调用的response的输出流没有主动关闭,服务器会替你关的。

(二)HttpServletRequest详解

HttpServletRequest代表着客户端的请求。服务器端要获取客户的请求信息只要找这个对象即可,该对象由容器创建。

(1)请求转发和包含

1、请求转发(forward):(当前应用内转)
方式一:
ServletContext.getRequestDispatcher(String path):path必须以"/"开头,表示绝对路径
方式二:
ServletRequest.getRequestDispatcher(String path):path如果"/"开头,表示绝对路径;如果不以"/"开头,表示相对路径

2、转发的细节:AServlet(源组件)--->BServlet(目标组件)
**转发前会清空response的正文。
转发页面上只会输出目标组件的输出,源组件的任何页面输出都无效。
原则:转发前,不要刷新或关闭response的输出流。
3、包含(include):RequestDispatcher
AServlet(源组件)--->BServlet(目标组件):AServlet包含BServlet的输出内容,例如下面的两段代码,第一段包含第二段,第一段中响应头的设置无效,将执行第二段对响应头的设置信息,输出的结果为“我爱中国”。
目标组件所有设置的头都无效,正文有效。

//源组件
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println(request.getContextPath());
		response.setContentType("text/html;charset=ISO-8859-1);
		response.getWriter().print("我爱");
		request.getRequestDispatcher("/RequsetServlet04.do").include(request, response);
	}
//目标组件
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().print("中国");
	}

(2)各种URL地址的写法

绝对地址:建议使用
绝对路径的写法:假设项目名为firstApp,何时需要加上应用名称"/firstApp"(如果地址给客户端用,要加上。如果给服务器端用,"/"就代表当前应用,即"/firstApp")
<img src="path"/>   要加/firstApp
<link type="text/style" href="path"/>   要加/firstApp
<a href="path"/> 要加/firstApp
<script type="text/javascript" src="path"/>   要加/firstApp
<form action="path"/>    要加/firstApp

getRequestDispatcher(String path):  不要加。"/"就代表了
头:Refresh=2;URL=path      要加/firstApp
ServletContext.getRealPath(String path): 不要加。"/"就代表了

response.sendRedirect(String path):  要加/firstApp

在服务器端获取项目名 》》request.request.getContextPath()


猜你喜欢

转载自blog.csdn.net/xingqibaing/article/details/80716732