Request&Response

一、Servlet规范中核心接口和类的类图

Servlet规范中的核心类图

二、HttpServletResponse

1、使用字节流输出中文数据
    response.getOutputStream().write("中国".getBytes("UTF-8"));
    浏览器会采用本地默认编码解码,会出现乱码问题。
    解决办法:
        a、更改浏览器的编码(不可取)
        b、response.setHeader("Content-Type", "text/html;charset=UTF-8");//通知浏览器以UTF-8进行解码
        c、response.getOutputStream().write("<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>".getBytes("UTF-8"));
           response.getOutputStream().write(data.getBytes("UTF-8"));
        d、response.setContentType("text/html;charset=UTF-8");作用等同b的作用

//b、通知浏览器以utf-8进行编码
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String data = "这是要输出的中文";
    response.setHeader("Content-Type", "text/html;charset=utf-8");
    response.getOutputStream().write(data.getBytes("utf-8"));
}
 
//c、response.getOutputStream().write("<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>".getBytes("UTF-8"));
public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String data = "这是要输出的中文";
		//此处响应的信息全部是英文,所以不会出现乱码问题;通知浏览器以utf-8进行解码
		response.getOutputStream().write(
				"<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>"
						.getBytes("UTF-8"));
		response.getOutputStream().write(data.getBytes("utf-8"));
	}
//response.setContentType("text/html;charset=utf-8");作用等同于b
public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String data = "这是要输出的中文";
		response.setContentType("text/html;charset=utf-8");
		response.getOutputStream().write(data.getBytes("utf-8"));
	}

2、使用字符流输出中文数据
    PrintWriter out = response.getWriter();默认输出字符时查 ISO-8859-1码表,可以通过response.setCharacterEncoding("UTF-8")更改它查询的码表
    输出中文时,不要忘记通知客户端解码的码表。
    response.setContentType("text/html;charset=UTF-8"):有两个作用
                a、通知输出字符流查UTF-8码表
                b、告知客户端查UTF-8进行解码

//使用字符流输出中文及乱码问题,通过setCharacterEncoding方法更改输出流查询的码表
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String data = "这里是中文显示";
		//使用PrintWriter,默认使用ISO-8859-1进行编码,而ISO-8859-1不支持中文显示
		//这里通知输出流使用utf-8进行编码
		response.setCharacterEncoding("utf-8");
		//这里通知浏览器使用utf-8进行解码
		response.setHeader("Content-Type", "text/html;charset=utf-8");
		PrintWriter writer = response.getWriter();
		writer.write(data);
	}

// 使用字符流输出中文及乱码问题
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String data = "这里是中文显示";
		// 使用PrintWriter,默认使用ISO-8859-1进行编码,而ISO-8859-1不支持中文显示
		response.setContentType("text/html;charset=utf-8");// 有两个作用
															// a、通知输出字符流查UTF-8码表
															// b、告知客户端查UTF-8进行解码
		PrintWriter writer = response.getWriter();
		writer.write(data);
	}

总结:               
response.setContentType:
        字节流:只通知客户端解码码表
        字符流:输出时查的码表;通知客户端解码码表

三、HttpServletResponse应用案例
    1、文件下载:中文文件名的下载

//中文文件名文件的下载
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取资源路径
		String path = getServletContext().getRealPath("/蒂法.jpg");
		System.out.println(path);
		//构建输入流
		InputStream in = new FileInputStream(path);
		//获得文件名
		String filename = path.substring(path.lastIndexOf("\\")+1);
		//通知客户端以下载文件方式打开
		response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename, "utf-8"));
		//构建输出流
		OutputStream out = response.getOutputStream();
		//输出模板
		byte[] buf = new byte[1024];
		int len = -1;
		while((len = in.read(buf))!= -1){
			out.write(buf,0,len);
		}
		out.close();
		in.close();
	}


    2、生成随机验证码图片

private static int WIDTH = 120;
private static int HEIGHT = 25;
//生成随机验证码图片
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");

    //获取内存中的画布
    BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
    //获得画笔
    Graphics g = image.getGraphics();
    //画边框
    g.setColor(Color.GRAY);
    g.drawRect(0, 0, WIDTH, HEIGHT);
    //填充背景色
    g.setColor(Color.YELLOW);
    g.fillRect(1, 1, WIDTH-2, HEIGHT-2);
    //画干扰线
    g.setColor(Color.GREEN);
    Random r = new Random();
    for(int i=0;i<9;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 = 20;
    for (int i = 0; i < 4; i++) {
        String num = r.nextInt(10) + "";
        g.drawString(num, x, 20);
        x += 20;
    }
    //输出图片
    ImageIO.write(image, "jpeg", response.getOutputStream());
}

效果图:

image

    3、定时刷新

//定时刷新
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=utf-8");
		response.setHeader("Refresh", "3;URL=/review_day05/index.html");
		response.getOutputStream().write("页面正在跳转中,请稍后...如果5秒内没有反应,请点击<a href='/day05/index.html'>这里</a>".getBytes("utf-8"));
}

   4、控制静态资源的缓存时间

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String data = "控制缓存时间";
    //此处控制缓存的持续时间
    response.setDateHeader("Expires", System.currentTimeMillis()+1*60*60*1000);
    response.getOutputStream().write(data.getBytes());
}

四、HttpServletResponse的一些细节
1、在同一个Servlet中,response的字节流和字符流互斥。
2、response通过字节流或字符流输出的数据不是直接打给浏览器的,是存在自己的缓存中了。
3、response使用的字节流和字符流不用手工关闭。

五、HttpServletRequest

    1、请求头的获取

public class RequestDemo1 extends HttpServlet {

	// 获取请求头
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		// 返回客户端发出请求时的完整URL
		String url = request.getRequestURL().toString();
		// 返回请求行中的资源名部分
		String uri = request.getRequestURI();
		// 返回请求行中的参数部分
		String queryString = request.getQueryString();
		// 返回发出请求的客户机的IP地址
		String remoteAddr = request.getRemoteAddr();
		// 返回发出请求的客户机的完整主机名
		String remoteHost = request.getRemoteHost();
		// 返回客户机所使用的网络端口号
		int port = request.getRemotePort();
		// 返回WEB服务器的IP地址
		String localAddr = request.getLocalAddr();
		// 返回WEB服务器的主机名
		String localName = request.getLocalName();
		// 得到客户机请求方式
		String requestMethod = request.getMethod();
		out.write("url=" + url + "<br/>");
		out.write("uri=" + uri + "<br/>");
		out.write("queryString=" + queryString + "<br/>");
		out.write("remoteAddr=" + remoteAddr + "<br/>");
		out.write("remoteHost=" + remoteHost + "<br/>");
		out.write("port=" + port + "<br/>");
		out.write("localAddr=" + localAddr + "<br/>");
		out.write("localName=" + localName + "<br/>");
		out.write("requestMethod=" + requestMethod + "<br/>");
	}

   2、请求参数的获取(内省;BeanUtils框架基本使用)

//请求参数的获取
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    OutputStream out = response.getOutputStream();
    out.write("----------获取指定名称的头值-----------<br/>".getBytes());
    String value = request.getHeader("Accept-Encoding");
    out.write((value+"<br/>").getBytes());
    out.write("----------获取所有的头和值-----------<br/>".getBytes());
    Enumeration<String> e = request.getHeaderNames();
    while(e.hasMoreElements()){
        String name = e.nextElement();
        out.write((request.getHeader(name)+"<br/>").getBytes());
    }
    out.write("----------获取同名的头和值-----------<br/>".getBytes());
     e = request.getHeaders("Accept-Encoding");
    while(e.hasMoreElements()){
        value = e.nextElement();
        out.write((value+"<br/>").getBytes());
    }
}

3、各种表单输入域的获取
        表单:type是radio或checkbox,即使页面有对应名称的选择项,只要一个都不选,什么值都不会传递给服务器,是null
            如果选了其中的任何一个选项,则把该项的value的取值传递给服务器。如果根本没有value属性,则传递on给服务器。

//post请求参数的获取及乱码处理
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    		// 告知服务器程序,请求中的参数值的编码是什么:
		// request.setCharacterEncoding("UTF-8"),但,该方法只适用于POST请求方式。
		request.setCharacterEncoding("utf-8");
		User user = null;
		response.getOutputStream().write(
				"获取请求参数的值,get和post方法通用<br/>".getBytes());
		// 这里能够获取多个同名的请求参数,如果只有一个参数,则String数组中只存一个元素;否则,多个元素
		String[] username = request.getParameterValues("username");
		String password = request.getParameter("password");
		String code = request.getParameter("code");
		response.getOutputStream().write(("封装前:" + user + "<br/>").getBytes());
		user = new User(username, password, code);
		response.getOutputStream().write(("封装后:" + user + "<br/>").getBytes());

}

//get请求参数的获取及乱码处理
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
            // GET请求方式:客户端发送的数据都是ISO-8859-1,需要重新编码
    User user = null;
    response.getOutputStream().write(
            "获取请求参数的值,get和post方法通用<br/>".getBytes());
    // 这里能够获取多个同名的请求参数,如果只有一个参数,则String数组中只存一个元素;否则,多个元素
    String[] username = request.getParameterValues("username");
    String password = request.getParameter("password");
    String code = request.getParameter("code");
    response.getOutputStream().write(("封装前:" + user + "<br/>").getBytes());
    user = new User(username, password, code);
    byte[] b = (user + "").getBytes("ISO-8859-1");// 客户端传递过来的字节数组
    String str = new String(b, "utf-8");
    System.out.println(str);
    response.getOutputStream().write(str.getBytes());

}
	//使用BeanUtils框架获取表单域
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    Student s= new Student();
    try {
        BeanUtils.populate(s, request.getParameterMap());
    } catch (Exception e) {
        e.printStackTrace();
    }
    response.getOutputStream().write((s+"").getBytes());
}
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>student</title>
</head>
<body>
<form action="/review_day05/servlet/RequestDemo3" method="post">
	姓名:<input type="text" name="username"/><br/>
	密码:<input type="password" name="password"/><br/>
	性别:<input type="radio" name="gender" value="1" checked="checked"/>男
	<input type="radio" name="gender" value="0"/>女<br/>
	婚否:<input type="checkbox"/><br/>
	爱好:<input type="checkbox" name="hobby" value="eat"/>吃饭
	<input type="checkbox" name="hobby" value="sleep"/>睡觉
	<input type="checkbox" name="hobby" value="dota"/>打DOTA
	<br/>
	家乡:<select name="city">
	<option value="DY">东营</option>
	<option value="JN">济南</option>
	<option value="QD">青岛</option>
	</select><br/>
	简介:<textarea rows="3" cols="40" name="description"></textarea><br/>
	<input type="hidden" name="id" value="100"/>
	<input type="submit" value="提交"><br/>
	</form>
</body>
</html>

请求参数值的中文乱码问题:
浏览器当前使用什么编码,就以什么编码发送数据。
浏览器什么什么编码,是根据访问的资源而定。建议统一用UTF-8
告知服务器程序,请求中的参数值的编码是什么:request.setCharacterEncoding("UTF-8"),但,该方法只适用于POST请求方式。

GET请求方式:客户端发送的数据都是ISO-8859-1,需要重新编码
new String(name.getBytes("ISO-8859-1"),"UTF-8");

原文地址:https://www.cnblogs.com/chenchong/p/2733800.html