[Servlet]HttpServletRequest的请求参数、标头、编码

来源:互联网 发布:淘宝刷胶机器 编辑:程序博客网 时间:2024/05/17 07:27

1. HttpServletRequest的主要作用:

    1) 前面我们已经非常熟悉了,就是在服务器收到请求后创建该对象并将有关请求的所有信息都分解保存在HttpServlet的各个字段中供Servlet使用;

    2) 还有一个功能就是请求转发的功能,一个Servlet接收到Request对象后经过一分析发现可能需要另一个Servlet来处理(这是绝对允许的,这也是一种设计模式),于是就可以将该Request转发给其它的Servlet,这种转发的过程也处于Request的生命周期中(指导完成相应才会清除该对象),在转发过程中一些需要共享的资料就可以放到Request中传递给其它的Servlet使用,这种资料可以通过request的函数插入到request中;


2. 获取请求信息:可以通过HttpServletRequest的各种get方法获取请求中的信息

!!以下4个函数是用来获取URL中的相关信息的;


    1) String getParameter(String name); // 返回指定参数的值,参数和值在URL中都是字符串

!!如果参数是数字,则需要在获取后使用Integer.parseInt()等方式转换成相应的数值型数据;

!如果请求的参数名不存在则返回null;

    2) 大多数情况下一个参数名对应一个参数值,但是有时一个参数名可以对应多个参数值(比如窗体上有列表等控件,那么此时一个参数名会有多个参数值,形式上相当于param=val1&param=val2&param=val3...),此时可以使用getParameterValues函数获取这样的参数:

String[] getParameterValues(String name); // 可以多个值以String数组的形式返回

    3) 如果想知道URL请求中共有多少个参数并且各个参数名都是什么则可以使用getParameterNames方法进行枚举:

         i. Enumeration<String> getParameterNames(); // 它返回的是要给String的枚举对象,接下来可以使用while迭代枚举

         ii. 迭代枚举各个参数名:

Enumeration<String> e = req.getParameterNames();while (e.hasMoreElements()) {String paraName = e.nextElement();...}
    4) getParameterNames只能获取所有请求参数的名称,如果想连着请求参数的值一块儿获取就可以使用非常强大的getParameterMap函数,它会直接返回一个Map键值对结合,每个对的键就是参数名String,而其对应的值就是参数值String[]数组,因为考虑到有些参数可能具有多个值:Map<String, String[]> getParameterMap();


!!接下来5个常用的函数用来获取请求标头中的相关信息;


    5) 标头中的信息也是以"参数名:参数值"的形式撰写的,因此同样可以用上面类似的方式来获取标头中的有关信息,比如getHeader可以获取标头中某个参数的值:

String getHeader(String name); // 这种方式同样只适用于只有一个值的参数,标头中也允许一个参数由多个值

    6) 获取多值参数的值使用getHeaders:Enumeration<String> getHeaders(String name); // 注意和URL的区别,获取URL的多值参数的值返回的是String[]!!

    7) 获得标头中所有参数的名称:Enumeration<String> getHeaderNames(); // 这回正常了,返回的是String的枚举

    8) 将获取的参数值转换成int型:int getIntHeader(String name);

    9) 将获取的参数值转换成Date型:long getDateHeader(String name);

!!上面两个函数的调用前提就是数据可以转换,如果不能转换会抛出相应的异常


3. 一个获取标头信息的Servlet示例:

protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// TODO Auto-generated method stub// response.getWriter().append("Served at:// ").append(request.getContextPath());PrintWriter out = response.getWriter();out.println("<html>");out.println("<head>");out.println("<title>Header Information List</title>");out.println("</head>");out.println("<body>");out.println("<h1>Servlet at " + request.getContextPath() + "</h1>");Enumeration<String> names = request.getHeaderNames();while (names.hasMoreElements()) {String name = names.nextElement();out.println(name + " : " + request.getHeader(name) + "<br>");}out.println("</body>");out.println("</html>");out.close();}
!URL模式是@WebServlet("/header.view")

!运行结果如下图:



4. 请求参数的编码问题:

    1) URL中的请求参数可以是非西欧语系的语言,比如中文等,此时就设计到编码问题,如果客户端发送的请求使用的编码和服务器端处理请求时使用的编码不一致往往会导致乱码错误;

    2) 客户端可以在请求标头中设置本次请求中请求参数的编码(此项由浏览器设置,Content-Type:text/html;charset=UTF-8),当客户端拿到HttpServletRequest时可以用其成员方法getCharacterEncoding来获取请求使用的编码:String ServletRequest.getCharacterEncoding(); // 可以看到该函数是从ServletRequest继承而来的

!!在获取请求编码后再将服务器端的编码调整成和请求编码一致再进行处理;

    3) HttpServletRequest本身的编码:

         i. 请求编码信息只是存放在Request的某个字段中,并不代表Request对象中存放的信息都是用该编码进行编码的;

         ii. Request被创建后默认的编码方案为"ISO-8859-1",而Request中保存的请求内容是浏览器设定的,如果这两种编码方案不一致就会导致乱码错误;

    4) HttpServletRequest的setCharacterEncoding方法只能对请求body中的内容进行编码!!!

         i. 在获取请求中使用的编码方案后可以使用setCharacterEncoding将请求body中的编码设置成和浏览器一致;

         ii. 函数原型:void ServletRequest.setCharacterEncoding(String env); // 该函数同样是继承自ServletRequest的

         iii. 但是注意!!该函数只能作用于body部分,而只有POST方式的请求参数会放在body部分,因此setCharacterEncoding只适用于POST请求!!!但不适用与GET请求!!!

!!使用setCharacterEncoding必须要在获取参数值之前,只有设置过了才能得到正确编码字符串!!

    5) 如何设置GET请求的请求参数的编码?

         i. 只能先通过getParameter获取相应的参数值;

         ii. 然后再使用String的getBytes函数来获取参数值的二进制字节数据;

         iii. 最后再使用String的构造器,指定字节和字节的编码来构造出一个符合想要的编码的字符串;

!!举例:

String val = req.getParameter("name");String name = new String(name.getBytes("ISO-8859-1"), "UTF-8");
!!getBytes:byte[] String.getBytes(String charsetName); // 使用指定的编码方案将一个字符串编码成字节流

!!构造器:String(byte[] bytes, String charsetName); // 将指定字节流按照指定编码方案编码成字符串

!!这里一定是先获取参数值在Request下默认编码方案的字节流,然后再将字节流转换成请求编码下的字符串


!!!其实直接在Servlet中处理请求参数的编码并不合适,标准的、符合规范的做法是在过滤器(Filter)中设置编码转换!!这在后面会具体讲解!


!!在上面的测试请求参数的编码转换时,结果先利用System.out.print系列函数输出到控制台查看,因为将中文等编码的字符串返回给浏览器显示又需要另外一套机制,这个后面会详细讲解;

0 0