• 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");

  • 相关阅读:
    GetBuffer与ReleaseBuffer的用法,CString剖析
    Mysql 关闭自动提交
    Mysql 创建用户和数据库
    老爸陪我去面试——北漂18年(3)
    Java中的“&”和“&&”的区别
    Java常量定义
    利用Java API生成50到100之间的随机数
    Java考查“==”和equals
    列出JDK中常用的Java包
    cognos 配置
  • 原文地址:https://www.cnblogs.com/chenchong/p/2733800.html
Copyright © 2020-2023  润新知