Servlet读书笔记(四)ServletRequest和ServletResponse的对象讲解

1 ServletRequest接口

HttpServletRequest就是ServletRequest的子接口。我们再调用Servlet的service(ServletRequest request, ServletResponse response)的时候第一个参数就是ServletRequest接口类型。
ServletRequest表示来自客户端的请求。当Servlet容器收到客户端要求访问特定的Servlet请求的时候,容器首先解析客户端请求上来的原始数据,然后把它们包装成一个ServletRequest的对象。当容器调用service方法的时候,该对象就会传递给service方法。

ServletRequest提供了一系列的处理客户端请求数据的方法:

  • getContentLength():返回请求正文的长度,如果请求正文的长度为空,返回-1

  • getContentType():获得请求政委的mine类型,如果请求正文为空,返回null

  • getInputStream():返回用于读取正文的输入流 getLocalAddr():返回服务器端的Ip地址

  • getLocalName():返回服务器端的主机名 getLocalPort():返回应用服务器的端口号

  • getParameter(String name):根据指定的名字,返回来自客户端请求中匹配的请求参数值,包括Get和Post的参数

  • getProtocol():返回客户端与服务器端通信所用的协议的名称以及版本号

  • getReader():返回用于读取字符串形式的请求正文的BufferedReader对象

  • getRemoteAddr():返回客户端的Ip地址 getRemoteHost():返回客户端的主机名

  • getRemotePort():返回客户端的端口号

ServletRequest还定义了一组在请求范围内共享数据的方法。

  • setAttribute(String name, Object
    object):在请求范围内保存一个属性,参数name表示属性名,参数Object表示属性值。
  • getAttribute(String name):根据name参数给定的属性名,返回请求范围内匹配的属性值

2 HttpServletRequest接口

HttpServletRequest接口是ServletRequest接口的子接口。在HttpServlet类重载service方法以及提供的doXXX方法里面有一个参数就是HttpServletRequest。
HttpServletRequest接口提供了用于读取Http请求中相关信息的方法:

  • getContextPath():返回客户端所请求访问的Web应用的URL入口,比如,我们访问的是
  • http://localhost:8080/001helloword/login,name该方法返回/001helloword。
  • getCookies():返回Http请求中所有的Cookie
  • getHeader(String name):返回Http请求头部特定项
  • getHeaderNames():返回一个Enumeration对象,他包含了Http请求头中所有的项目名
  • getMethpd():返回Http请求方式
  • getRequestURI:返回Http请求头中的第一行的URI
  • getQueryString():返回查询字符串,就是?后面的东西

3 ServletRequest和HttpServletRequest的作用:

我们使用Servlet Api 来创建Servlet的时候,无须费力的解析原始Http请求。原始内容的解析,直接交给HttpServletRequest对象就好了。我们程序员只需要调用各种getXXX方法来获取对应的数据就行了。

4 Request相关实例

package com.vgxit.helloworld.servlet;

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

/**
 * HttpServletRequest的具体案例
 */
public class RequestInfoServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1,设置响应正文类型
        response.setContentType("text/html;charset=utf-8");
        //2,获取request里面的各种信息,并展示在页面上
        try (PrintWriter pw = response.getWriter()) {
            pw.println("<html>");
            pw.println("<head>");
            pw.println("<title>Request信息展示</title>");
            pw.println("</head>");
            pw.println("<body>");
            pw.println("<h2>请求正文长度为:" + request.getContentLength() + "</h2>");
            pw.println("<h2>请求正文的类型:" + request.getContentType() + "</h2>");
            pw.println("<h2>服务器端Ip地址是:" + request.getLocalAddr() + "</h2>");
            pw.println("<h2>服务器端主机名是:" + request.getLocalName() + "</h2>");
            pw.println("<h2>服务器端端口号是:" + request.getLocalPort() + "</h2>");
            pw.println("<h2>通信协议和版本号是:" + request.getProtocol() + "</h2>");
            pw.println("<h2>客户端Ip地址是:" + request.getRemoteAddr() + "</h2>");
            pw.println("<h2>客户端主机名是:" + request.getRemoteHost() + "</h2>");
            pw.println("<h2>客户端端口号是:" + request.getRemotePort() + "</h2>");
            pw.println("<h2>Http请求方式是:" + request.getMethod() + "</h2>");
            pw.println("<h2>客户端请求的URI是:" + request.getRequestURI() + "</h2>");
            pw.println("<h2>客户端请求的URL入口是:" + request.getContextPath() + "</h2>");
            pw.println("<hr/>");
            pw.println("<h2>下面是请求头:</h2>");
            Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement().toString();
                pw.println("<p><b>" + headerName + ":</b>" + request.getHeader(headerName) + "<p/>");
            }
            pw.println("</body>");
            pw.println("</html>");
        }
    }
}

Servlet读书笔记(四)ServletRequest和ServletResponse的对象讲解
在这个请求过程当中,只需要创建完新的servlet之后,在web.xml当中进行配置即可,这当中的配置就包含了<servlet><servlet-mapping>当中的设置,设置完之后就进行servlet的编写,当中就是response进行的是一个显示的配置。

(二)ServletResponse接口

1,ServletResponse接口
Servlet接口的service方法的第二个参数就是一个ServletResponse类型的参数。这个ServletResponse是专门用来生成响应结果返回给客户端的。当Servlet容器收到客户端的请求的时候,容器会创建一个ServletResponse的对象,并且作为参数传递给service方法,直接使用这个ServletResponse对象来构造返回数据。ServletResponse接口提供了很多方法来生成相关结果:

setCharacterEncoding(String charset):设置响应正文的字符编码。默认是ISO-8859-1

setContentLength(int len):设置响应正文的长度 setContentType(String type):设置响应正文的mime类型 getCharacterEncoding():返回响应正文的字符编码
getContentType():返回响应正文的MIME类型 setBufferSize(int size):设置用于存放响应正文数据的缓冲区大小 getBufferSize():获得用户存放响应正文数据缓冲区的大小
reset():清空缓冲区内的正文数据,并且清空响应状态代码以及响应头
resetBuffer():仅仅清空缓冲区内的正文数据,不清空响应状态代码以及响应头
flushBuffer():强制性的把缓冲区的正文数据发送到客户端
isCommited():返回一个boolean类型的数据,如果为true表示缓冲区的数据已经提交给了客户,否则就是没有
getOutputStream():返回一个ServletOutputStream对象,Servlet用它来输出二进制正文数据。
getWriter():返回一个PrintWriter对象,Servlet用它来输出字符串形式的正文数据。

为了提高传输效率,ServletOutputStream和PrintWriter先把数据写到缓冲区。当缓冲区内的数据被提交给了客户之后,ServletResponse的isCommitted()方法返回true。在一下几种情况下,缓冲区内的数据会被提交给客户:

  • 缓冲区内数据已经满了的时候,ServletOutputStream或者PrintWriter会自动把缓冲区内的数据发送给客户端并清空缓冲区
  • Servlet调用ServletResponse对象的flushBuffer()
  • Servlet调用ServletOutputStream或者PrintWriter的flush()方法或者close()方法

所以说为了保证数据能够真的发送到客户端,我们比较好的做法就是在完成所有的业务代码之后调用一次ServletOutputStream或者PrintWriter的flush()方法。

ServletResponse还可以通过setContentLength(),SetContentType()和setCharacterEncoding()分别来设置响应正文的长度,MINE类型和字符编码,这些setXXX方法会把响应的设置写入到Http响应头中

2 HttpServletResponse接口
HttpServletResponse是ServletResponse的子接口。在HttpServlet类的重载service方法和doXXX方法中第二个参数就是一个HttpServletResponse类型的。
HttpServletResponse提供了一些和Http协议相关的方法,Servlet可通过这些方法来设置Http响应头或向客户端写Cookie等操作:

  • addHeader(String name, String value):向Http响应头中加入一些内容
  • sendError(int sc):向客户端发送一个代码特定错误的Http响应状态码
  • sendError(int sc, String msg):向客户端发送一个代码特定错误的Http响应状态码,并且带上错误信息
  • setHeader(String name, String value):设置响应头中的一项内容。如果响应头中已经存在了这项内容,那么覆盖
  • setStatus(int sc):设置Http状态码
  • addCookie(Cookie cookie):向Http响应中加入一个cookie

HttpServletResponse中定义很多Http状态码的常量:

  • HttpServletResponse.SC_BAD_REQUEST : 对应400状态码
  • HttpServletResponse.SC_FOUND: 对应302状态码
  • HttpServletResponse.SC_METHOD_NOT_ALLOWED: 对应405状态码
  • HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION:对应203状态码
  • HttpServletResponse.SC_FORBIDDEN:对应403状态码
  • HttpServletResponse.SC_NOT_FOUND: 对应响应状态码为404
  • HttpServletResponse.SC_OK: 对应200状态码

3 ServletResponse具体实例

package com.vgxit.helloworld.servlet;

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

public class ResponseTestServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        if (username == null || username.equals("")) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
        }
        //设置一下Http响应正文的类型和编码
        response.setContentType("text/html;charset=utf-8");
        PrintWriter pw = response.getWriter();
        pw.println("<html>");
        pw.println("<head>");
        pw.println("<title>ServletResponse简单实例</title>");
        pw.println("</head>");
        pw.println("<body>");
        pw.println("<h1>您好:" + username + "</h1>");
        pw.println("</body>");
        pw.println("</html>");
        System.out.println("关闭之前是否把数据发给了客户端:" + response.isCommitted());
        pw.close();
        System.out.println("关闭之后是否把数据发给了客户端:" + response.isCommitted());
    }
}

在上面代码中,我们使用了response.setContentType(“text/html;charset=utf-8”);这样一行代码来设置了响应正文的mime类型和正文编码。"text/html"代表响应正文的类型是html文档。"charset=utf-8"代表采用的编码是utf-8编码。其实我们上面的这行代码,也可以用下面的两个方式来替换:

  • response.setContentType(“text/html”);
  • response.setCharacterEncoding(“utf-8”);

第二种方式:

  • response.setHeader(“Content-type”, “text/html;charset=utf-8”);
上一篇:一个简单的Filter过滤器


下一篇:2020-12-8 Filter过滤器