1. HttpServletRequest

1.1. 什么是HttpServletReqeust?

1)HttpServletRequest是一个接口,全限定名称:jakarta.servlet.http.HttpServletRequest。
2)HttpServletRequest接口是Servlet规范中的一员,在Tomcat中存在servlet-api.jar。
3)HttpServletRequest接口实现类由Http服务器负责提供。
4)HttpServletReqeust接口负责在doGet/doPost方法运行时读取http请求协议包中信息。
5)开发人员习惯于将HttpServletRequest接口修饰的对象称为【请求对象】。

1.2. HttpServletRequest父接口

jakarta.servlet.ServletRequest:

public interface HttpServletRequest extends ServletRequest {}

1.3. HttpServletRequest实现类

org.apache.catalina.connector.RequestFacade

public class RequestFacade implements HttpServletRequest {}

Tomcat服务器实现了HttpServletRequest接口,也说明了了Tomcat服务器实现了Servlet规范。

1.4. HttpServletRequest对象中有什么信息?

1)HttpServletRequest对象是Tomcat服务器负责创建的。封装了HTTP的请求协议。

实际上是用户发送请求的时候,遵循了HTTP协议,发送的是HTTP的请求协议,Tomcat服务器将HTTP协议中的信息以及数据全部解析出来,然后Tomcat服务器把这些信息封装到HttpServletRequest对象当中,传给了javaweb程序员。

1.5. request对象和response对象生命周期

1)http服务器接收到浏览器发送的【http请求协议包】之后,自动为当前的【Http请求协议包】生成1个【请求对象】和1一个【响应对象】。
2)在http服务器调用doGet/doPost方法时,负责将【请求对象】和【响应对象】作为实参传递到方法,确保doGet/doPost正确执行。
3)在http服务器准备推送http响应协议包之前,负责将本次请求关联的【请求对象】和【响应对象】销毁。

【请求对象】和【响应对象】生命周期贯穿一次请求的处理过程中,【请求对象】和【响应对象】相当于用户在服务端的代言人。

1.6. 获取前端浏览器用户提交的数据

String getParameter(String name)
Map<String,String[]>getParameterMap()
Enumeration<String>getParameterNames()
String[] getParameterValues(String name)

以上4个方法和获取用户提交的数据有关系。

注意:getParameterValues之所以使用String[]格式,是因为前端提交的数据格式可能是:name=张三&name=李四,解决同一个key对应了多个值的问题。

1.7. 获取请求信息

javaweb程序员面向HttpServletRequest接口编程,调用方法就可以获取请求的信息了。

请求信息包括:请求行、请求头、请求体。

1)获取请求行信息:

public class Servlet1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExcepiton {
        // 1. 通过请求对象,读取【请求行】中【url】信息
        String url = request.getRequestURL().toString();
        // 2. 通过请求对象,读取【请求行】中【method】信息
        String method = request.getMethod();
        // 3. 通过请求对象,读取【请求行】中uri信息
        String uri = request.getRequestURI();// substring
        System.out.println("URL "+url);
        System.out.println("method "+method);
        System.out.println("URI "+uri);
    }
}

URI:资源文件精准定位地址,在请求行并没有URL这个属性,实际上URL中截取一个字符串,这个字符串格式“/网站名/资源文件名”,URI用于让Http服务器对被访问的资源文件进行定位。

2)获取请求体信息:

public class Servlet2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExcepiton {
        // 1. 通过请求对象,读取【请求行】中【所有请求参数名】信息
        Enumeration paramNames = request.getParameterNames();// 将所有请求参数名称保存到一个枚举对象进行返回
        while(paramNames.hasMoreElements()) {
            String paramName = (String)paramNames.nextElement();
            // 2. 通过请求对象读取指定的参数名称的值
            String value = request.getParameter(paramName);
            System.out.println("请求参数名 "+paramName+" 请求参数值"+value);
        }
    }
}

1.8. 请求转发

可以代替浏览器向Http服务器申请资源文件调用。

// 第一步:获取请求转发器对象
RequestDispatcher dispatcher = request.getRequestDispatcher("/xxx");
// 第二步:调用转发器的forward方法完成跳转/转发
dispatcher.forward(request, response);
// 第一步和第二步代码可以联合在一起
request.getRequestDispatcher("/xxx").forward(request, response);
  • 转发的时候是一次请求,不管你转发了多少次,都是一次请求。
  • AServlet转发到BServlet,再转发到CServlet,再转发到DServlet,不管转发了多少次,都在同一request中。
  • 这是因为调用forward方法的时候,会将当前的request和response对象传递给下一个Servlet。

转发的时候,转发的路径以“/”开始,不加项目名。

1.9. 中文乱码

1)Post请求

public class Servlet3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExcepiton {
        // 通过请求对象,读取【请求体】参数信息
        String value = request.getParameter("userName");
        Sytem.out.println("从请求体得到参数值 "+value);
    }
}

问题:以POST方式发送中文参数内容“劳瘁是个男人”,得到【乱码】“?????”

原因:浏览器以POST发送请求,请求参数保存在【请求体】,在Http请求协议包到达http服务器之后,第一件事就是进行解码,请求体二进制内容由当前请求(request)负责解码,request默认使用【ISO-8859-1】字符集,一个东欧语系字符集,此时如果请求体参数内容是中文,将无法解码只能得到乱码。

解决:在Post请求方式下,在读取请求体内容时,应该通知请求对象使用utf-8字符集请求体内容进行一次重新解码。

request.setCHaracterEncoding("utf-8");

Tomcat10不会乱码,Tomcat8、9都会乱码。

2)Get请求

public class Servlet3 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExcepiton {
        // 通过请求对象,读取【请求头】参数信息
        String userName = request.getParameter("userName");
        System.out.println("从请求头得到参数值 "+userName);
    }
}

问题:以GET方式发送中文参数内容“老杨是个正经人”时,得到正常值,

原因:浏览器以GET方式发送请求,请求参数保存在【请求头】,在Http请求协议包到达http服务器之后,第一件事就是进行解码请求头二进制内容由Tomcat9.0默认使用【utf-8】字符集,可以解析一切国家文字。

Get请求中文乱码怎么解决?修改CATALINA_HOME/conf/server.xml配置文件。

<Connector- URIEncoding="UTF-8" />

如何查看Tomcat默认使用什么字符集解析Get请求:CATALINA_HOME/webapps/docs/config/http.html找到URIEncoding说明。例如tomcat7:

This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

3) Response中文乱码
在Tomcat9及之前,响应中文也是有乱码的,如何解决:

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

1.10. 请求域对象

1)请求域对象要比应用域对象范围小很多,生命周期短很多,请求域只在一次请求内有效。
2)一个请求对象request对应一个请求域对象,一次请求结束之后,这个请求域就销毁了。
3)请求域对象也有这三个方法:

void setAttribute(String name, Object o)// 向请求域绑定数据
void removeAttribute(String name)// 从域当中根据name获取数据
Object getAttribute(String name)// 将域当中绑定的数据移出

4)请求域和应用域的选用原则

尽量使用小的域对象,因为小的域对象占用的资源较小。

1.11. 其他常用方法

// 获取客户端的IP地址
String remoteAddr = request.getRemoteAddr();
// 获取应用的根路径
String contextPath = request.getContextPath();
// 获取请求方式
String method = request.getMethod();
// 获取请求的URI
String requestURI = request.getRequestURI();
// 获取servlet路径
String servletPath = request.getServletPath();

1.12. 视频地址

start:https://www.bilibili.com/video/BV1Z3411C7NZ?p=22
end:https://www.bilibili.com/video/BV1Z3411C7NZ?p=26

2023.12.4 00:38

results matching ""

    No results matching ""