请求

请求对象介绍

请求:获取资源。在BS架构中,就是客户端浏览器向服务器发出询问

请求对象:就是在项目当中用于发送请求的对象

ServletRequest 和 HttpServletRequest

 

 

请求对象的常用方法-获取各种路径

返回值                 方法名                                        说明

String                  getContextPath()                获取虚拟目录名称

String                  getServletPath()                 获取Servlet映射路径

String                   getRemoteAddr()               获取访问者ip地址

String                   getQueryString()     获取请求的消息数据

String                   getRequestURI()    获取统一资源标识符

StringBuffer     getRequestURL()    获取统一资源定位符

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/ServletDemo01")
public class ServletDemo01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //getContextPath()      获取虚拟目录名称
        String contextPath = request.getContextPath();
        System.out.println(contextPath);
        //getServletPath()      获取Servlet映射路径
        String servletPath = request.getServletPath();
        System.out.println(servletPath);
        //getRemoteAddr()       获取访问者ip地址
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);
        //getQueryString()    获取请求的消息数据     (了解)
        String queryString = request.getQueryString();
        System.out.println(queryString);
        //getRequestURI()     获取统一资源标识符   /request/ServletDemo01  共和国
        String requestURI = request.getRequestURI();
        System.out.println(requestURI);
        //getRequestURL()     获取统一资源定位符   http://localhost:8080/request/ServletDemo01   中华人民共和国
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURL);
    }

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

 

 

 请求对象常用方法-获取请求头信息

返回值                                           方法名                                     说明

String                                      getHeader(String name)            根据请求头名称获取一个值

Enumeration<String>                 getHeaders(String name)       根据请求头名称获取多个值

Enumeration<String>               getHeaderNames()                   根据所有请求头名称

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

/*
* 获取请求头信息的相关方法
* */
@WebServlet("/ServletDemo02")
public class ServletDemo02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //getHeader(String name)     根据请求头名称获取一个值
        String connection = request.getHeader("connection");
        System.out.println(connection);
        System.out.println("----------");
        //getHeaders(String name)   根据请求头名称获取多个值
        Enumeration<String> values = request.getHeaders("Accept-Encoding");
        while(values.hasMoreElements()){
            String value = values.nextElement();
            System.out.println(value);
        }
        System.out.println("----------");
        //getHeaderNames()          根据所有请求头名称
        Enumeration<String> names = request.getHeaderNames();
        while(names.hasMoreElements()){
            String name = names.nextElement();
            String value = request.getHeader(name);
            System.out.println(name+","+value);

        }
    }

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

 

 

 

2.3.3 请求对象常用方法3-获取请求参数(非常重要)

返回值                                                方法名                                                               说明

String                                            getParameter(String name)                           根据名称获取数据

String[]                                           getParameterValues(String name)            根据名称获取所有数据

Enumeration<String>               getParameterNames()                             获取所有名称

Map<String,String[]>                     getParameterMap()                                  获取所有参数键值对

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

/*
* 获取请求信息的相关方法
* */
@WebServlet("/ServletDemo03")
public class ServletDemo03 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.根据名称获取数据   getParameter()
        String username = request.getParameter("username");
        System.out.println(username);
        String password = request.getParameter("password");
        System.out.println(password);
        System.out.println("----------------------");
        //2.根据名称获取所有数据 getParameterValues()
        String[] hobbies = request.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("----------------------");
        //3.获取所有名称  getParameterNames()
        Enumeration<String> names = request.getParameterNames();
        while(names.hasMoreElements()){
            String name = names.nextElement();
            System.out.println(name);
        }
        System.out.println("----------------------");
        //4.获取所有参数的键值对 getParameterMap()
        Map<String, String[]> map = request.getParameterMap();
        for (String key : map.keySet()) {
            String[] values = map.get(key);
            System.out.print(key+":");
            for (String value : values) {
                System.out.print(value+" ");
            }
            System.out.println();
        }

    }

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

2)封装请求参数到实体类中

第一种:最简单直接的封装方式

bean/Student

package com.itheima.bean;

import java.util.Arrays;

public class Student {
    private String username;
    private String password;
    private String[] hobby;

    public Student() {
    }

    public Student(String username, String password, String[] hobby) {
        this.username = username;
        this.password = password;
        this.hobby = hobby;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String[] getHobby() {
        return hobby;
    }

    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", hobby=" + Arrays.toString(hobby) +
                '}';
    }
}

ServletDemo04:  

package com.itheima.servlet;

import com.itheima.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

/*
* 封装对象-手动封装
* */
@WebServlet("/ServletDemo04")
public class ServletDemo04 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取所有的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String[] hobbies = request.getParameterValues("hobby");
        //2.封装学生对象
        Student stu=new Student(username,password,hobbies);
        //输出对象
        System.out.println(stu);



    }

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

  

  

第二种:使用反射方式封装  

package com.itheima.servlet;

import com.itheima.bean.Student;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;

/*
* 封装对象-反射方式
* */
@WebServlet("/ServletDemo05")
public class ServletDemo05 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取所有的数据
        Map<String, String[]> map = request.getParameterMap();
        //2.封装学生对象
        Student stu=new Student();
        //2.1.遍历集合
        for (String name : map.keySet()) {
            String[] value = map.get(name);
            //2.2获取Student对象的属性描述器,根据名称拿到 stu里面的get/set方法
            try {
                PropertyDescriptor pd=new PropertyDescriptor(name,stu.getClass());
                //2.3获取对应的setXXX方法
                Method writeMethod = pd.getWriteMethod();
                //2.4执行方法
                if (value.length >1) {
                    writeMethod.invoke(stu,(Object) value);
                }else{
                    writeMethod.invoke(stu,value);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        //输出对象
        System.out.println(stu);



    }

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

当我们写完此种封装方式之后,同学们可以发现,我们绝大多数封装都可以使用这段代码来实现。并且,无论是谁来写这段通用的封装代码,其代码内容都是大同小异的。那么,我们就可以得出一个很有趣的结论:一般遇到这种情况时,肯定有人帮我们写好了,我们只需要用就行了。我们后面还会遇到类似这样的情况。

此时,帮我们写好这段封装代码的是apache软件基金会,我们前面学习的tomcat也是它提供的。它里面有一个开源工具包集合commons,里面有很多开源工具类,今天我们就来讲解第一个:commons-beanutils

第三种:使用工具类封装方式

导入这两个包

 

 

 

package com.itheima.servlet;

import com.itheima.bean.Student;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/*
* 封装对象-工具类方式
* */
@WebServlet("/ServletDemo06")
public class ServletDemo06 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取所有的数据
        Map<String, String[]> map = request.getParameterMap();
        //2.封装学生对象
        Student stu=new Student();
        try {
            BeanUtils.populate(stu,map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //输出对象
        System.out.println(stu);



    }

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

  通过流对象获取请求信息

返回值        方法名        说明

BufferReader    getReader()     获取字符输入流

ServletInputStream  getInputStream()   获取字节输入流 

package com.itheima.servlet;

import com.itheima.bean.Student;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Map;

/*
* 流对象获取数据
* */
@WebServlet("/ServletDemo07")
public class ServletDemo07 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //字符流(必须是post方式)
       /* BufferedReader br = request.getReader();
        String line;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }*/
        //br.close();

        //字节流
        ServletInputStream is = request.getInputStream();
        byte[] arr=new byte[1024];
        int len;
        while((len= is.read(arr))!=-1){
            System.out.println(new String(arr,0,len));
        }



    }

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

 

 

 

2.3.5请求正文中中文编码问题

关于请求中文乱码问题,我们需要分开讨论,第一是POST请求方式,第二是GET方式。

1)POST方式请求

在POST方式请求中,我们的乱码问题可以用如下代码解决:

request.setCharacterEncoding("UTF-8");

GET方式请求的正文是在地址栏中,在Tomcat8.5版本及以后,Tomcat服务器已经帮我们解决了,所以不会有乱码问题了。

而如果我们使用的不是Tomcat服务器,或者Tomcat的版本是8.5以前,那么GET方式仍然会有乱码问题,解决方式如下:(以下代码了解即可,因为我们现在使用的是Tomcat9.0.27版本)

/**
 * 在Servlet的doGet方法中添加如下代码
 */
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
   

        /*
         * GET方式:正文在地址栏
         * username=%D5%C5%C8%FD
         * %D5%C5%C8%FD是已经被编过一次码了
         *
         * 解决办法:
         * 	 使用正确的码表对已经编过码的数据进行解码。
         * 		就是把取出的内容转成一个字节数组,但是要使用正确的码表。(ISO-8859-1)
         * 	 再使用正确的码表进行编码
         * 		把字节数组再转成一个字符串,需要使用正确的码表,是看浏览器当时用的是什么码表
         */
        String username = request.getParameter("username");
        byte[] by = username.getBytes("ISO-8859-1");
        username = new String(by,"GBK");

        //输出到浏览器:注意响应的乱码问题已经解决了
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.write(username);
}

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

  请求对象

请求域(request域):可以在一次请求范围内进行共享数据

请求对象操作共享数据方法

返回值        方法名                说明

void      setAttribute(String name,Object value)   向请求域对象中存储数据

Object     getAttribute(String name)          通过名称获取请求域对象中的数据

void      removeAttribute(String name)      通过名称一处请求域对象中的数据

2.3.6 请求转发(与重定向的区别)

在实际开发中,重定向和请求转发都是我们要用到的响应方式,那么他们有什么区别呢?我们通过下面的示例来看一下:

请求转发:客户端的一次请求到达后,发现需要借助其他Servlet来实现功能

特点:

  • 浏览器地址栏不变
  • 域对象中的数据不丢失
  • 负责转发的Servlet转发前后的相应正文会丢失
  • 有转发的目的地来响应客户端

返回值        方法名                说明  

RequestDispatcher  getRequestDispatcher(String name)  获取请求调度对象

 

 返回值        方法名                说明

void         forward(ServletRequest req,ServletResponse resp)  实现转发

ServletDemo09

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
* 请求转发
* */
@WebServlet("/ServletDemo09")
public class ServletDemo09 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);



    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        //设置共享数据
        request.setAttribute("encoding","gbk");
        //获取请求调度对象
        request.getRequestDispatcher("/ServletDemo10").forward(request,response);
    }
}

ServletDemo10

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
* 请求转发
* */
@WebServlet("/ServletDemo10")
public class ServletDemo10 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取共享数据
        Object encoding = request.getAttribute("encoding");
        System.out.println(encoding);

        System.out.println("ServletDemo10执行了");

    }
}

 

2.3.7 请求包含

在实际开发中,我们可能需要把两个Servlet的内容合并到一起来响应浏览器,而同学们都知道HTTP协议的特点是一请求,一响应的方式。所以绝对不可能出现有两个Servlet同时响应方式。那么我们就需要用到请求包含,把两个Servlet的响应内容合并输出。我们看具体使用示例:

 请求包含:可以合并其他Servlet中的功能一起响应给客户端

 返回值        方法名                说明

 RequestDispatcher  getRequestDispatcher(String name)    获取请求调度对象

 返回值        方法名                说明  

void        include(ServletRequest req,ServletReponse resp)   实现包含

ServletDemo13

package com.itheima.servlet;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
    请求包含
 */
//@WebServlet(name = "ServletDemo09",urlPatterns = "/ServletDemo09")
@WebServlet("/ServletDemo13")
public class ServletDemo13 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ServletDemo13执行了");

        //获取请求的调度对象
        req.getRequestDispatcher("/ServletDemo14").include(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

 ServletDemo14

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
    请求包含
 */
//@WebServlet(name = "ServletDemo09",urlPatterns = "/ServletDemo09")
@WebServlet("/ServletDemo14")
public class ServletDemo14 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ServletDemo14执行了");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

  

 

 

 

posted @ 2020-12-21 16:00  星梦泪痕  阅读(136)  评论(0编辑  收藏  举报