servlet详解二:servlet的4个重点对象

本篇文章介绍了几个servlet中比较重要的对象,包括

  • ServletConfig
  • ServletContext
  • HTTPServletRequest
  • HTTPServletResponse

其中穿插了http协议的简单介绍,servlet中的重要对象还有几个比如session,cookie,后面介绍九大对象和四大作用域的时候再详细介绍。

一、ServletConfig

1.1、什么是ServletConfig对象

ServeltConfig代表了Servlet的配置信息的对象。

1.2、ServletConfig获取方法

通过servlet的getServletConfig();方法可以获取

1.3、ServletConfig的功能

  • getServletName(); //获取servlet的名称,也就是我们在web.xml中配置的servlet-name

  • getServletContext(); //获取ServletContext对象,该对象的作用看下面讲解

  • getInitParameter(String); //获取在servlet中初始化参数的值。这里注意与全局初始化参数的区分。这个获取的只是在该servlet下的初始化参数

  • getInitParameterNames(); //获取在Servlet中所有初始化参数的名字,也就是key值,可以通过key值,来找到各个初始化参数的value值。注意返回的是枚举类型
    web.xml内容

<servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>web.FirstServlet</servlet-class>
        <init-param>
            <param-name>测试参数名1</param-name>
            <param-value>测试参数值1</param-value>
        </init-param>
        <init-param>
            <param-name>测试参数名2</param-name>
            <param-value>测试参数值52</param-value>
        </init-param>
    </servlet>

servlet 文件内容

/**
 * 
 */
package web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Administrator
 *
 */
public class FirstServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter(); 
    ServletConfig config = this.getServletConfig();
    String sname= config.getServletName();
    Enumeration<String> initNames = config.getInitParameterNames();
    out.println("Servlet的名字是:"+sname+"<br>");
    while(initNames.hasMoreElements()){
       String name = initNames.nextElement();
       out.println("参数 "+name+"的值为:"+config.getInitParameter(name)+"<br>");
    }
    out.flush();
    out.close();
    }


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

    }

}

浏览器访问http://127.0.0.1:8080/servlet/first,显示

Servlet的名字是:FirstServlet
参数 测试参数名2的值为:测试参数值2
参数 测试参数名1的值为:测试参数值1

out.println是对输出的html内容换行,而HTML换行需要br标签

二、ServletContext对象

2.1、什么是ServletContext对象?

WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用(servlet上下文对象)。

由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象:1,是一个容器 2。作用范围是应用程序范围。

2.2、ServletContext对象的获取方法

ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过
1、ServletConfig.getServletContext方法获得ServletContext对象
2、this.getServletContext()方法;

2.3、ServletContext对象的方法

1、属性操作方法
– setAttribute(String name, Object obj) 在web项目范围内存放内容,以便让在web项目中所有的servlet读能访问到

  • getAttribute(String name) 通过指定名称获得内容

  • removeAttribute(String name) 通过指定名称移除内容

2、参数操作方法

  • getInitPatameter(String name)  //通过指定名称获取初始化值
  • getInitParameterNames()  //获得枚举类型

3、资源和路径操作方法
– getRealPath(“/WEB-INF/web.xml”) 获取web项目下指定资源的路径

  • context.getResource(java.lang.String path) 获取指定文件的统一资源定位符path必须是/开头,代表当前web应用程序的根目录。返回返回的一个代表某个资源的URL对象。

  • getResourceAsStream(java.lang.String path) 获取web项目下指定资源的内容,返回的是字节输入流

  • getResourcePaths(java.lang.String path) 指定路径下的所有内容。

/**
 * 
 */
package web;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Administrator
 *
 */
public class test extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String contextPath = context.getContextPath();
    String realPath = context.getRealPath("/WEB-INF/web.xml");
    System.out.println("获取web.xml的绝对路径"+realPath);
    // 统一资源定位符path必须是/开头,代表当前web应用程序的根目录。返回返回的一个代表某个资源的URL对象。
    URL url = context.getResource("/index.jsp");

    Set set = context.getResourcePaths("/WEB-INF");
    Iterator iterator = set.iterator();
    System.out.println("WEB-INF文件下的所有文件:");
    while (iterator.hasNext()) {
        System.out.println(iterator.next());

    }

    context.setAttribute("contex", "contexValue");
    System.out.println(context.getAttribute("contex"));
    context.removeAttribute("contex");

    System.out.println(context.getAttribute("contex") == null ? "属性删除成功" : "属性删除失败");

    Enumeration<String> enumer = context.getInitParameterNames();
    System.out.println("所有的context参数:");
    while (enumer.hasMoreElements()) {
        String string = (String) enumer.nextElement();
        System.out.println(context.getInitParameter(string));
    }

    InputStream is = context.getResourceAsStream("/index.jsp");

    Reader read = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(read);
    byte[] buffer = new byte[1024];
    String length;
    System.out.println("读取index.jsp文件的内容如下:");
    while ((length = br.readLine()) != null) {
        System.out.println(length);
    }
    br.close();
    }

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

    doGet(request, response);
    }

}

控制台输出

获取web.xml的绝对路径E:\workspace\myeclipse\servlet Maven Webapp\src\main\webapp\WEB-INF\web.xml
WEB-INF文件下的所有文件:
/WEB-INF/web.xml
contexValue
属性删除成功
所有的context参数:
上下文参数值1
上下文参数值2
读取index.jsp文件的内容如下:
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

三、http协议简介

HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。HTTP 协议是基于请求-响应的协议,客户端请求一个文件,服务器对该请求进行响应。HTTP 使用 TCP 协议,默认使用 80 端口。最初的 HTTP 协议版本是 HTTP/0.9,后被 HTTP/1.0 替代。目前使用的版本是 HTTP/1.1,

HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。

在 HTTP 协议中,总是由主动建立连接、发送 HTTP 请求的客户端来初始化一个事务。服务器不负责连接客户端,或创建一个到客户端的回调连接(callback connection)。

3.1、工作流程

一次HTTP操作称为一个事务,其工作过程可分为四步:

1)首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。

2)建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。

3)服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。

4)客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。

如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。

3.2、请求报文

《servlet详解二:servlet的4个重点对象》
请求行:请求方式、资源路径、协议

①请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。
②请求对应的URL地址,它和报文头的Host属性组成完整的请求URL。
③协议名称及版本号。

请求头:

④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。
与缓存相关的规则信息,均包含在header中

请求体:

⑤是报文体,它将一个页面表单中的组件值通过param1=value1,param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/chapter15/user.html? param1=value1¶m2=value2”的方式传递请求参数。

3.3、HTTP请求报文头属性

  • Accept

    请求报文可通过一个“Accept”报文头属性告诉服务端 客户端接受什么类型的响应。
    如下报文头相当于告诉服务端,俺客户端能够接受的响应类型仅为纯文本数据啊,你丫别发其它什么图片啊,视频啊过来,那样我会歇菜的~~~

  • Accept:text/plain

    Accept属性的值可以为一个或多个MIME类型的值(描述消息内容类型的因特网标准, 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据)

  • cookie

    客户端的Cookie就是通过这个报文头属性传给服务端的哦!如下所示:

    Cookie: $Version=1; Skin=new;jsessionid=5F4771183629C9834F8382E23
    服务端是怎么知道客户端的多个请求是隶属于一个Session呢?注意到后台的那个jsessionid = 5F4771183629C9834F8382E23木有?原来就是通过HTTP请求报文头的Cookie属性的jsessionid的值关联起来的!(当然也可以通过重写URL的方式将会话ID附带在每个URL的后面哦)。

  • Referer
    表示这个请求是从哪个URL过来的,假如你通过google搜索出一个商家的广告页面,你对这个广告页面感兴趣,鼠标一点发送一个请求报文到商家的网站,这个请求报文的Referer报文头属性值就是http://www.google.com。

  • Cache-Control

    对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。

3.4、响应报文

HTTP的响应报文也由三部分组成(响应行+响应头+响应体)
《servlet详解二:servlet的4个重点对象》
响应行:

①报文协议及版本;
②状态码及状态描述;

响应头:

③响应报文头,也是由多个属性组成;

响应体:

④响应报文体,即我们真正要的“干货”

3.4.1、响应状态码

和请求报文相比,响应报文多了一个“响应状态码”,它以“清晰明确”的语言告诉客户端本次请求的处理结果。
HTTP的响应状态码由5段组成:

1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。

以下是几个常见的状态码:

状态码 含义
200 OK 你最希望看到的,即处理成功!
302/307 临时重定向,指出请求的文档已被临时移动到别处, 此文档的新的url在location响应头中给出
303 See Other 我把你redirect到其它的页面,目标的URL通过响应报文头的Location告诉你。
304 Not Modified 告诉客户端,你请求的这个资源至你上次取得后,并没有更改,你直接用你本地的缓存吧,我很忙哦,你能不能少来烦我啊!
401 (UNAUTHORIZED) 客户端无权访问该资源。这通常会使得浏览器要求用户输入用户名和密码,以登录到服务器。
403 (FORBIDDEN) 客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。
404 Not Found 你最不希望看到的,即找不到页面。如你在google上找到一个页面,点击这个链接返回404,表示这个页面已经被网站删除了,google那边的记录只是美好的回忆。
500 Internal Server Error 看到这个错误,你就应该查查服务端的日志了,肯定抛出了一堆异常,别睡了,起来改BUG去吧!

3.5、常见的HTTP响应报文头属性

Cache-Control

响应输出到客户端后,服务端通过该报文头属告诉客户端如何控制响应内容的缓存。

常见的取值有private、public、no-cache、max-age,no-store,默认为private。
private: 客户端可以缓存
public: 客户端和代理服务器都可缓存(前端的同学,可以认为public和private是一样的)
max-age=xxx: 缓存的内容将在 xxx 秒后失效
no-cache: 需要使用对比缓存来验证缓存数据
no-store: 所有内容都不会缓存

默认为private,缓存时间为31536000秒(365天)也就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。

ETag

一个代表响应服务端资源(如页面)版本的报文头属性,如果某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可以让客户端“更智能”地处理什么时候要从服务端取资源,什么时候可以直接从缓存中返回响应。

Location

我们在JSP中让页面Redirect到一个某个A页面中,其实是让客户端再发一个请求到A页面,这个需要Redirect到的A页面的URL,其实就是通过响应报文头的Location属性告知客户端的,如下的报文头属性,将使客户端redirect到iteye的首页中:

Location: http://www.iteye.com

Set-Cookie

服务端可以设置客户端的Cookie,其原理就是通过这个响应报文头属性实现的:

Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1

cookie机制:

客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。

如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。

如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。

如果maxAge为0,则表示删除该Cookie。

Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。
如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。

Cookie cookie = new Cookie(“username”,”helloweenvsfei”); // 新建Cookie

cookie.setMaxAge(0); // 设置生命周期为0,不能为负数

response.addCookie(cookie); // 必须执行这一句 输出到客户端

3.6、一个Htpp请求响应信息

《servlet详解二:servlet的4个重点对象》

四、HttpServletRequest

request就是将请求文本封装而成的对象,所以通过request能获得请求文本中的所有内容,请求头、请求体、请求行 。

4.1、接口HttpServletRequest的常用方法

方 法 说 明
getAttributeNames() 返回当前请求的所有属性的名字集合
getAttribute(String name) 返回name指定的属性值
getCookies() 返回客户端发送的Cookie
getsession() 返回和客户端相关的session,如果没有给客户端分配session,则返回null
getsession(boolean create) 返回和客户端相关的session,如果没有给客户端分配session,则创建一个session并返回
getParameter(String name) 获取请求中的参数,该参数是由name指定的
getParameterValues(String name) 返回请求中的参数值,该参数值是由name指定的
getCharacterEncoding() 返回请求的字符编码方式
getContentLength() 返回请求体的有效长度
getInputStream() 获取请求的输入流中的数据
getMethod() 获取发送请求的方式,如get、post
getParameterNames() 获取请求中所有参数的名字
getProtocol() 获取请求所使用的协议名称
getReader() 获取请求体的数据流
getRemoteAddr() 获取客户端的IP地址
getRemoteHost() 获取客户端的名字
getServerName() 返回接受请求的服务器的名字
getServerPath() 获取请求的文件的路径
getRequestURL() 方法返回客户端发出请求时的完整URL。
getRequestURI() 方法返回请求行中的资源名部分。
getQueryString() 方法返回请求行中的参数部分。
getLocalName() 方法返回WEB服务器的主机名
getHeader(string name) 方法获取请求头
getHeaders(String name) 方法获取请求头
getHeaderNames() 方法获取请求头
request.setCharacterEncoding(“utf-8”) 设置服务器以UTF-8的编码接收数据后
getReader() 获取请求体的数据流
getInputStream() 获取请求的输入流中的数据

4.2、request.getQueryString()会乱码

request.getQueryString()容器不会解码该值

使用 URLDecoder.decode()可得到正确内容。

request.getParameter()容器已用默认编码方式解码

4.3、乱码解决

jsp设置

<%@ page pageEncoding="utf-8"   contentType="text/html;charset=utf-8"%>

这个设置的是jsp文件转为html文件时的编码,默认是gbk的,必须设置

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

这个是html的编码设置

servlet设置

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

request代码必须写在request获取数据之前,不然还是容易乱码,处理请求来的数据编码
response是对响应信息进行编码设置

4.4、参数(parameter)和属性(Attribute)的区别

在JAVA WEB开发中经常遇到获取请求参数的值和在request对象中set或者get属性,初学者往往容易混淆,那么二者之间关系到底如何呢?

区别:

来源不同:

  • 参数(parameter)是从客户端(浏览器)中由用户提供的,若是GET方法是从URL中提供的,若是POST方法是从请求体(request body)中提供的;
  • 属性(attribute)是服务器端的组件(JSP或者Servlet)利用requst.setAttribute()设置的

操作不同:

  • 参数(parameter)的值只能读取不能修改,读取可以使用request.getParameter()读取;
  • 属性(attribute)的值既可以读取亦可以修改,读取可以使用request.setAttribute(),设置可使用request.getAttribute()

数据类型不同:

  • 参数(parameter)不管前台传来的值语义是什么,在服务器获取时都以String类型看待,并且客户端的参数值只能是简单类型的值,不能是复杂类型,比如一个对象。
  • 属性(attribute)的值可以是任意一个Object类型。

4.5测试代码

/**
 * 
 */
package web;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Administrator
 *
 */
public class Request extends HttpServlet {
    public void p() {
    System.out.println("=============================================");
    System.out.println();
    }

    public void p(Object obj) {
    System.out.println(obj);

    }

    public void p(Object function, Object text, Object value) {
    System.out.println(function + "方法" + "   |  " + text + "   |  " + value);

    }

    @SuppressWarnings("deprecation")
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");

    // 参数获取

    Enumeration<String> paramets = request.getParameterNames();

    while (paramets.hasMoreElements()) {
        String paName = (String) paramets.nextElement();
        System.out.println("参数" + paName + "的值为:" + request.getParameter(paName));

    }
    p();

    // 属性设置获取
    request.setAttribute("Attribute", "一个设置的属性值");
    Enumeration<String> attributs = request.getAttributeNames();
    while (attributs.hasMoreElements()) {
        String attrName = (String) attributs.nextElement();
        System.out.println("属性" + attrName + "的值为:" + request.getAttribute(attrName));
    }
    p();
    // 路径和信息的获取
    // 统一资源定位符
    String url = request.getRequestURL().toString();
    p("getRequestURL()", "获取统一资源定位符", url);

    // 统一资源标识符
    String uri = request.getRequestURI().toString();
    p("getRequestURI()", "获取统一资源标识符", uri);

    //协议和版本
    p("getProtocol()", "获取协议和版本号", request.getProtocol());

    //协议
    p("getScheme()", "获取协议", request.getScheme());

    //主机(域名) 如localhost,当用ip访问时,获取的是ip
    p("getServerName()", "获取主机(域名)", request.getServerName());

    //获取在tomcat下的项目名称
    p("getContextPath()", "tomcat下的项目名称", request.getContextPath());

    //获取所有请求参数?之后的
    p("getQueryString()", "获取主机(域名)", URLDecoder.decode(request.getQueryString()));

    //获取远程的ip地址
    p("getRemoteAddr", "获取远程主机ip", request.getRemoteAddr());


    //获取远程的主机(ip)地址
    p("getRemoteHost()", "获取远程主机ip", request.getRemoteHost());


    p("getHeader(String name)", "获取请求头", request.getHeader("Accept-Language"));

    Enumeration<String> headers = request.getHeaderNames();
    p("所有请求头信息:");
    while (headers.hasMoreElements()) {
        String name = (String) headers.nextElement();
        p("获取请求头"+name+":         "+request.getHeader(name));
    }

    }

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

    doGet(request, response);
    }

}

index.jsp内容

<%@ page pageEncoding="utf-8"   contentType="text/html;charset=utf-8"%>
<html>
  <head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <title>用户表单</title>
  </head>
 <body>
 <center>
     <form action="/servlet/request?parame1=parame值1&parame2=parame值2" method="post">
         <table>
             <tr>
                 <td colspan="2">用户表单</td>
             </tr>
            <tr>
                 <td>用户名:</td>
                 <td><input type="text" name="username"></td>
             </tr>
             <tr>
                 <td>密  码:</td>
                 <td><input type="password" name="userpassword"></td>
            </tr>
             <tr>
                 <td colspan="2">
                 <input type="submit" name="提交">
                 <input type="reset" name="重置">
             </tr>
         </table>
     </form>
 </center>
 </body>
 </html>

运行结果

参数parame1的值为:parame值1
参数parame2的值为:parame值2
参数username的值为:中国
参数userpassword的值为:
参数提交的值为:提交查询
=============================================

属性Attribute的值为:一个设置的属性值
=============================================

getRequestURL()方法   |  获取统一资源定位符   |  http://127.0.0.1:8080/servlet/request
getRequestURI()方法   |  获取统一资源标识符   |  /servlet/request
getProtocol()方法   |  获取协议和版本号   |  HTTP/1.1
getScheme()方法   |  获取协议   |  http
getServerName()方法   |  获取主机(域名)   |  127.0.0.1
getContextPath()方法   |  tomcat下的项目名称   |  /servlet
getQueryString()方法   |  获取主机(域名)   |  parame1=parame值1&parame2=parame值2
getRemoteAddr方法   |  获取远程主机ip   |  127.0.0.1
getRemoteHost()方法   |  获取远程主机ip   |  127.0.0.1
getHeader(String name)方法   |  获取请求头   |  zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
所有请求头信息:
获取请求头host:         127.0.0.1:8080
获取请求头user-agent:         Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0
获取请求头accept:         text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
获取请求头accept-language:         zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
获取请求头accept-encoding:         gzip, deflate
获取请求头referer:         http://127.0.0.1:8080/servlet/
获取请求头content-type:         application/x-www-form-urlencoded
获取请求头content-length:         97
获取请求头connection:         keep-alive
获取请求头cookie:        ======太长就省掉了======
获取请求头upgrade-insecure-requests:         1
获取请求头cache-control:         max-age=0

五、HttpServletResponse

response就是将响应文本封装而成的对象,所以通过response能设置响应文本中的内容,响应包括请求头、请求体、请求行 。

接口HttpServletResponse的常用方法

方 法 说 明
addCookie(Cookie cookie) 将指定的Cookie加入到当前的响应中
addHeader(String name,String value) 将指定的名字和值加入到响应的头信息中
containsHeader(String name) 返回一个布尔值,判断响应的头部是否被设置
encodeURL(String url) 编码指定的URL
sendError(int sc) 使用指定状态码发送一个错误到客户端
sendRedirect(String location) 发送一个临时的响应到客户端
setDateHeader(String name,long date) 将给出的名字和日期设置响应的头部
setHeader(String name,String value) 将给出的名字和值设置响应的头部
setStatus(int sc) 给当前响应设置状态码
setContentType(String ContentType) 设置响应的MIME类型
/**
 * 
 */
package web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Administrator
 *
 */
public class Response extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    Object count = context.getAttribute("count");
    int i =0;
    if(count==null){
        context.setAttribute("count", new Integer(0));

    }else{
        i = Integer.parseInt(count.toString());
        i++;
        context.setAttribute("count", new Integer(i));
    }


    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.print("你是第"+(i++)+"位访客");
    if(i>3){
        /*
        //302表示重定向,等价于sendRedirect
        response.setStatus(302);
        response.setHeader("location","http://www.baidu.com");
        */
        //response.sendRedirect("request");
        response.sendRedirect("/servlet/request");
    }else{
        response.setHeader("Refresh","3");
    }

    }

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

    doGet(request, response);
    }

}

重定向(浏览器网址和网站内容跳转到指定的网址)

response.sendRedirect("http://www.baidu.com")

等价于

response.setStatus(302);
response.setHeader("location","http://www.baidu.com");
response.sendRedirect("request");
response.sendRedirect("/servlet/request");

以上两个request不带/的直接以web根目录跳转,而带/的以tomcat的根目录跳转

其中在ServletContext中设置了属性来统计网页访问的次数,因为四大作用域中application作用域最大,也是能跨浏览器和不同客户端的作用域,本质代表整个web应用

请求转发

request.getRequestDispatcher("request").forward(request, response);

请求转发,url地址不变,但是之后的处理交给转发的组件
转发的源组件和目标组件在request范围内共享数据,及他们拥有同一个request对象啊。请求转发只能转发给同一个WEB应用中的组件。

参考

http协议详解(超详细)

HTTP请求报文(请求行、请求头、请求体)

Java Web(一) Servlet详解!!

HttpServletRequest 和 HttpServletResponse详解

点赞

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注