内置对象

在Servlet实现类中,可以获得ServletConfig、ServletRequest、ServletResponse、Session、Application等内置对象。这些内置对象都由Servlet创建。

ServletConfig

  • ServletConfig是Servlet配置对象,是服务器对Servlet对象的配置的封装,包含Servlet对象名,初始化参数等。初始化参数可以在web.xml或@WebServlet注解的init-param中配置(见Servlet),常用于配置编码等。在init方法中可以获取作为参数的ServletConfig对象:

    1. public void init(ServletConfig config) throws ServletException {
    2. this.encoding = conf.getInitParameter("encoding"); // 获得key为encoding的value值
    3. }

    ServletRequest

  • 在HttpServlet中的HttpServletRequest和HttpServletResponse是对ServletRequest和ServletResponse的封装,将其强转为了HttpServletRequest和HttpServletResponse。所以是属性和方法是差不多一样的。

  • ServletRequest可以获取HTTP请求报文的各个参数。可以添加、修改和删除ServletRequest的部分数据,还可以获取输入流从而获得请求体的请求(主要是POST请求的内容或JSON请求体)、请求头(主要是GET请求中URL的请求参数)、向其中存放数据、获取Session对象、内部跳转对象、Cookies对象等。

    1. req.setCharacterEncoding("utf-8"); // 设置编码
    2. req.getContextPath; // 获取“/项目名”
    3. req.getServletPath; // 获取“/动态资源映射路径”
    4. req.getRequestURI; // 获取去除IP和端口的URI部分
    5. req.getParameter("kk");
    6. // 获取GET请求中URL的参数,如:IP:端口/项目/资源路径?kk=app&bb=coo;或POST请求中请求体的参数
    7. req.getAttribute("kk"); // 获取用于传递数据的属性对应数据
    8. req.setAttribute("kk", obj); // 设置kk的属性值为obj(obj是一个对象)
    9. req.replaceAttribute("kk", obj); // 替换kk属性
    10. req.removeAttribute("kk"); // 移除kk属性
    11. String s = req.getParamter("name属性名"); // 获取POST请求中的属性值
    12. String[] ss = req.getParamterValues("name属性名"); // 批量获取获取属性值
    13. req.getInputStream(); // 获取输入流
    14. req.getReader(); // 获取字符输入流(字符输入流和输入流只能使用其中一个)
    15. request.getRequestDispatcher("Forward.html"); // 获取跳转对象
    16. request.getSession(); // 获取Session对象
    17. req.getCookies(); // 获取Cookies对象

    ServletResponse

  • 可以将响应数据封装到ServletResponse,并设置HTTP响应报文的各个参数,如文字编码、响应类型等;还可以直接返回重定向响应。

    1. resp.setContentType("text/html;charset=utf-8"); // 设置数据类型和编码
    2. resp.setCharacterEncoding("utf-8"); // 设置编码
    3. resp.getOutputStream(); // 获取输出流
    4. resp.getWriter(); // 获取字符输出流
    5. response.sendRedirect("/forward2"); // 返回重定向:IP:端口/forward2
    6. resp.addCookie(cookie); // 添加Cookie

    Session

  • Session对象即HttpSession对象,只能通过HttpServletRequest对象获取,而不能够通过ServletRequest对象获取。它可以通过浏览器发送的JSESSIONID来识别浏览器,从而响应相同的数据,如实现登录状态验证等。

  • 当客户端JSESSIONID为空或JSESSIONID在服务器不存在对应的Session对象时,服务器就会创建一个Session对象,并自动发送一个JSESSIONID给客户端。客户端就会拥有一个JSESSIONID,此后可以凭此对应服务器中的一个Session对象,从而识别浏览器是否登录。当重启浏览器、打开新窗口或使用其它浏览器时,对应的JSESSIONID均不同。
  • 默认情况下,当Session对象不再使用超过30分钟后,即销毁该Session对象。可以在web.xml配置项目中Session对象的默认销毁时间(session-config/session-timeout,单位是分钟),或使用setMaxInactiveInterval()方法(单位是秒)设置单个Session对象的销毁时间。也可以使用invalidate()方法立即销毁。
  • 可以通过Session保存数据,一个属性对应一个对象。取对象时需要判空,避免空指针异常。
  • Session只保存在服务端,并由JSESSIONID对应,生命周期为一次会话(当浏览器重启等对应不同的JSID),适合处理用户登录、会话数据、千人千面等个性化内容。

    Application

  • Application本质是一个ServletContext对象,通过Servlet、ServletConfig、ServletRequest、Session对象均可以获取ServletContext对象。这一对象也是单例的。

  • 可以通过Application保存数据,一个属性对应一个对象,这和Session一样。但不同的是,Application的生命周期为整个服务器存续期间,故不适合保存用户数据,而是网页数据等非个性化内容。
  • 可以通过Application获取和保存Cookie,实现会话追踪。

    几个操作

    内部跳转和重定向

    内部跳转是指服务器内部跳转,可以在客户端发起请求后,跳转到另一个指定Servlet或网页。在跳转期间,客户端请求产生的请求对象也会一并传递到跳转到的页面中。服务器跳转只会让浏览器发出1次请求。可以在跳转之前,通过ServletRequest传递信息。服务器跳转指定的相对路径,是相对于项目的相对路径。
    而重定向是指浏览器重定向,是客户端发起请求后,服务器响应一个数据,让浏览器新发起请求到另一个指定Servlet或网页。浏览器重定向会让浏览器发起2次请求,使得重定向前后收到的ServletRequest对象不一样,故不能通过其传递信息。浏览器重定向指定的相对路径,是相对于IP和端口号的相对路径。浏览器重定向常用于登陆、提交表单等会写入、修改和删除服务器内容的行为中。
    内部跳转前后可以随便使用流向前端写数据,虽然会被覆盖;重定向只能在重定向之前写数据(虽然也没有用),在重定向之后写数据会报错。/WEB-INF中的资源是隐藏的,只能够通过内部跳转访问。
    无论是内部跳转还是重定向,都可以使用Session和Application对象传递信息。

    1. protected void doGet(HttpServletRequest request, HttpServletResponse response)
    2. throws ServletException, IOException {
    3. RequestDispatcher dispatcher =
    4. request.getRequestDispatcher("Forward.html"); // 获取跳转对象,跳转到项目名下的Forward.html
    5. dispatcher.forward(request, response); // 跳转并传递request和response对象
    6. }
    7. /***** 分割线 *****/
    8. protected void doGet(HttpServletRequest request, HttpServletResponse response)
    9. throws ServletException, IOException {
    10. String path = request.getContextPath(); // 获取项目名称
    11. response.sendRedirect(path + "/forward2"); // 指定浏览器重定向至“IP:端口/项目名/forward2”
    12. }

    使用对象传递数据

  • 可以通过ServletRequest、Session、Application的setAttribute()传递数据。根据其生命周期,选用不同的对象传递数据。

    线程安全

    由于Servlet对象只有一个,故在实现类中声明的成员变量就会有线程安全的问题。解决方案主要是:少定义成员变量,即使非要定义成员变量,应使用线程安全的成员变量,如vector;或是一个常量。

    会话追踪技术

    Cookie是用于会话追踪的专用对象。Cookie是一对键值对组成的对象,多个Cookie组成一个Cookies数组,浏览器和服务器都会保存。当浏览器访问服务器时,会将该URL对应的Cookies发送给服务器。服务器可以根据Cookies的数据确定该用户是否曾经登录以及登录的是哪个用户等,而不是像Session只能在一次会话中起作用。服务器可以向响应中写入Cookies,浏览器收到后会将Cookies写入到文件中保存。JSESSIONID就是Cookie的一种。可以设定Cookie的有效期,一般为7天。

    URL重写