http

1. http简介

HTTP(HyperText Transfer Protocol)即超文本传输协议,是一种详细规定了浏览器和万维网服务器之间互相通信的规则,它是万维网交换信息的基础,它允许将HTML(超文本标记语言)文档从Web服务器传送到Web浏览器。

它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定义了今天普遍使用的一个版本——HTTP 1.1。

HTTP是一种无状态的协议,无状态是指Web浏览器与Web服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求(Request),然后Web服务器返回响应(Response),连接就被关闭了,在服务器端不保留连接的有关信息。也就是说,HTTP协议永远都是客户端发起请求,服务器回送响应。

response headers token 如何获取_java

HTTP工作流程
1 首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。
2 建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
3 服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
4 客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。
一次HTTP操作称为一个事务,某一步出现错误,那么产生错误的信息将返回到客户端。

在客户端与服务器进行交换信息的时候,Request和Response相当于两个人在写信交流,而Cookie和Session则相当于两个人各自写下日记,记录着自己或者对方的信息。在JavaWeb编程中,正确操作这四个对象是非常重要的,因此下文将会介绍如何用java 调用servlet中关于Request、Response、Cookie和Session的方法。

http之Request

Request对象,又称为请求对象,是由客户端发起的请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后服务器通过request对象的相关方法来获取这些数据。

Request与Response的的运行流程

response headers token 如何获取_服务器_02


Request之get与post

http有多种请求方式,其中最为常用的get和post。

get相对不安全,因为get的数据会被放在请求的URL中一并发出,并且get传送的数据量较小,受url长度限制。

post的所有操作对用户来说都不可见,且Post传送的数据量较大,一般被默认为不受限制。

请求消息

请求消息包括请求行(request line)、请求头部(header)、空行和请求数据,如下图所示。

response headers token 如何获取_客户端_03


请求头的常见头部字段名

Server:服务器版本信息

Date:日期

Content-Type:实际返回的内容的内容类型

Content-Length:描述HTTP消息实体的传输长度

User-Agent:浏览器版本信息

Java处理Request
Request这个对象不用事先声明,就可以在JSP网页中使用,在编译为Servlet之后,它会转换为HttpServletRequest形态的对象,HttpServletRequest对象是有关于客户端所发出的请求的对象,只要是有关于客户端请求的信息,都可以藉由它来取得,例如请求标头、请求方法、请求参数、客户端IP,客户端浏览器等等信息。

Request继承结构

ServletRequest接口
          |- 继承
  		 HttpServletRequest接口
				|- org.apache.catalina.connector.RequestFacade 实现类 (tomcat提供)

有关HttpServletRequest方法,想要更全面的信息请访问HttpServletRequest api文档 http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletRequest.html 下文会介绍常用的HttpServletRequest 方法

1.获取请求行信息

getMethod();获取请求方式

	getRequestURL();方法返回客户端发出请求时的完整URL。

  getRequestURI();方法返回请求行中的资源名部分。

  getQueryString(); 方法返回请求行中的参数部分。

  getPathInfo();方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。

  getRemoteAddr();方法返回发出请求的客户机的IP地址。

  getRemoteHost();方法返回发出请求的客户机的完整主机名。

  getRemotePort();方法返回客户机所使用的网络端口号。

  getLocalAddr();方法返回WEB服务器的IP地址。
  
	getLocalName();方法返回WEB服务器的主机名。
jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form method="post" action="/test">
        <input type="submit" value="提交">
    </form>
</body>
</html>


servlet代码:
package com.southwind.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("/test")
public class TestServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      System.out.println("req.getMethod()= "+req.getMethod());
        System.out.println("req.getRequestURL()= "+req.getRequestURL());
        System.out.println("req.getRequestURI()= "+req.getRequestURI());
        System.out.println("req.getQueryString()= "+req.getQueryString());
        System.out.println("req.getPathInfo()= "+req.getPathInfo());
        System.out.println("req.getRemoteAddr()= "+req.getRemoteAddr());
        System.out.println("req.getRemoteHost()= "+req.getRemoteHost());
        System.out.println("req.getRemotePort()= "+req.getRemotePort());
        System.out.println("req.getLocalAddr()= "+req.getLocalAddr());
        System.out.println("req.getLocalName()= "+req.getLocalName());
    }
}

输出:

req.getMethod()= POST
req.getRequestURL()= http://localhost:8080/test
req.getRequestURI()= /test
req.getQueryString()= null
req.getPathInfo()= null
req.getRemoteAddr()= 0:0:0:0:0:0:0:1
req.getRemoteHost()= 0:0:0:0:0:0:0:1
req.getRemotePort()= 57041
req.getLocalAddr()= 0:0:0:0:0:0:0:1
req.getLocalName()= 0:0:0:0:0:0:0:1

2.获取请求头信息

getHeader(string name);方法:String 
getHeaders(String name);方法:Enumeration 
getHeaderNames();方法
jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form method="post" action="/test">
        <input type="submit" value="提交">
    </form>
</body>
</html>


servlet代码:
package com.southwind.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("/test")
public class TestServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //获取所有请求头字段
        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            //获取字段对应的值
            String value = req.getHeader(name);
            System.out.println(name+": "+value);
        }
    }
}

输出:(所有头信息字段及其值)

host: localhost:8080
connection: keep-alive
content-length: 0
cache-control: max-age=0
upgrade-insecure-requests: 1
origin: http://localhost:8080
content-type: application/x-www-form-urlencoded
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site: same-origin
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
referer: http://localhost:8080/test.jsp
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cookie: JSESSIONID=4385440600ABA12937C60FDD40D10661

3.获取传递参数

String getParameter(String name)	返回name指定参数的参数值
String[] getParameterValues(String name)	返回包含参数name的所有值的数组

4.共享数据

void setAttribute(String,Object)	存储此请求中的属性
Object getAttribute(String name)	返回指定属性的属性值

要注意,只有先set了才能get到。

5.转发

getRequestDispatcher(String url).forward(request,response);

由转发后的地址来对转发的请求进行响应。

http之Response

Response对象用于动态响应客户端请示,控制发送给用户的信息,并将动态生成响应。Response对象只提供了一个数据集合cookie,它用于在客户端写入cookie值。若指定的cookie不存在,则创建它。若存在,则将自动进行更新。结果返回给客户端浏览器。
	和HttpServletRequest类似,HttpServletResponse也继承了ServletResponse 接口,这个对象中封装了向客户端**发送数据、发送响应头,发送响应状态码**的方法。我们可以直接调用HttpServletResponse的方法来操作Response。

Response主要包含响应行、响应头和响应体。

响应行:协议版本 状态 描述

响应头:必要信息

响应体:返回的数据

response headers token 如何获取_java_04


Java处理Response

HttpServletRequest的API库:http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletResponse.html 1.向客户端发送数据

resp.getOutputStream();
resp.getWriter();

getOutputStreamgetWriter方法分别用于得到输出二进制数据ServletOuputStream对象和输出文本数据的Printwriter对象。并且两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。
这两个方法写入的数据会作为响应消息的正文,与响应状态行和各响应头组合后输出到客户端。Serlvet的service方法结束后,web容器将检查getWritergetOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,web容器将调用close方法关闭该输出流对象。

在向服务端发送数据的时候,可能会发现自己要传输的中文显示成乱码,那么这时候需要设置编码格式,以下两种选一即可,但都需要在向客户端发送数据之前执行才能生效,二者区别在于前者不仅发送到浏览器的内容会使用UTF-8编码,而且还通知浏览器使用UTF-8编码方式进行显示。所以总能正常显示中文。

resp.setContentType(“text/html; charset=UTF-8”);//更稳妥
resp.setCharacterEncoding(“UTF-8”);

2.实现重定向

resp.sendRedirect(String url);

有细心的人看到这里应该会想到,request有转发,response有重定向,二者的功能类似,都是将页面跳转,那么这两者有什么区别呢?
首先, RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的其他资源; sendRedirect方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
request的转发是在服务器端实现的。一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发。调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
而response的重定向是在客户端实现的。一个web资源收到客户端请求后,通知客户端的浏览器去访问另外一个web资源,称之为请求重定向。所以调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL。
从本质上看,转发是请求实现的,这意味着是将请求给转发给另外一个网址,而重定向是响应实现的,那么因此是对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求。
最终表现出来转发:浏览器地址不变,重定向:浏览器地址变成新的url

3.设置响应头

setDateHeader(String name, long date);用一个给定的名称和日期值设置响应头,这里的日期值应该是反映自1970-1-1日(GMT)以来的精确到毫秒的长整数。如果响应头已经被设置,新的值将覆盖当前的值。
setHeader(String name, String value);用一个给定的名称和域设置响应头。如果响应头已经被设置,新的值将覆盖当前的值。
setHeader(String name, String value);用一个给定的名称和整形值设置响应头。如果响应头已经被设置,新的值将覆盖当前的值。
setStatus(int statusCode);这个方法设置了本次响应的状态码,如果状态码已经被设置,新的值将覆盖当前的值。
addCookie(Cookie cookie);在响应中增加一个指定的cookie
containsHeader(String name);返回布尔值,检查是否设置了指定的响应头。

httpResponse状态消息

五种状态码:

  • 1xx:信息提示,表示请求已被成功接收,继续处理
  • 2xx:请求被成功提交。 3xx:客户端被重定向到其他资源。
  • 4xx:客户端错误状态码,格式错误或者不存在资源。
  • 5xx:描述服务器内部错误。

常见的状态码:
200:客户端请求成功,是最常见的状态。
302:重定向。
404:请求资源不存在,是最常见的状态。
400:客户端请求有语法错误,不能被服务器所理解。
401:请求未经授权。
403:服务器收到请求,但是拒绝提供服务。
500:服务器内部错误,是最常见的状态,通常是代码写错了。
503:服务器当前不能处理客户端的请求。

http之Cookie

1.什么是Cookie
Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息 。
它是存储在浏览器中的小型文本文件,携带用户信息,方便服务端提供服务,同时也可能会导致个人信息的泄漏。

创建cookie

Cookie cookie = new Cookie(String name,String value);

添加cookie

resp.addCookie(Cookie cookie);

2.Cookie的方法使用

Cookie API文档:http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/Cookie.html

setMaxAge(int expiry);设置cookie有效时间,秒。如果不设置则仅在本次session会话中有效.
getMaxAge();获取cookie有效时间
getName();获取cookie name值
getValue();获取cookie value值
setValue();设置新的cookie value值
setPath(String url);设置cookie的访问域
getPath();取出cookie的访问域
setComment(String str);指定描述cookie用途的注释
getComment();取出注释
getSecure();如果浏览器仅通过安全协议发送cookie,则返回true。如果浏览器可以使用任何协议发送cookie,则返回false。
jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form method="post" action="/test2">
        <input type="submit" value="提交">
    </form>
</body>
</html>
----------------------------------------------------
servlet代码:
package com.southwind.servlet;

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

@WebServlet("/test2")
public class Test2Servlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //编码
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        //测试代码
        Cookie cookie = new Cookie("name","tom");
        cookie.setMaxAge(1000);
        resp.getWriter().println("getMaxAge()= "+cookie.getMaxAge()+"<br/>");
        resp.getWriter().println("getName()= "+cookie.getName()+"<br/>");
        resp.getWriter().println("getValue()= "+cookie.getValue()+"<br/>");
        cookie.setComment("注释");
        resp.getWriter().println("getComment()= "+cookie.getComment()+"<br/>");
        resp.getWriter().println("getSecure()= "+cookie.getSecure()+"<br/>");
    }
}

网页输出:

response headers token 如何获取_servlet_05

http之Session

1.什么是session
Session是另一种记录客户状态的机制。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。
获取Session对象

HttpSession session = req.getSession();

2.session与cookie的区别

  • Cookie保存在客户端浏览器中,而Session保存在服务器上。
  • Session保存数据为Object类型,Cookie为String类型
  • Session会长期保存,并且会存放重要的数据

3.session的方法使用

Session API文档:http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSession.html

setAttribute(String attribute, Object value);存入对象
getAttribute(String attribute);取出对象
removeAttribute(String attribute)	移除Session属性
getCreationTime();返回创建此会话的时间,以毫秒为单位,自1970年1月1日零点起计算。常被转化为Date类型,例如:Date createTime = new Date(session.getCreationTime())
getId() 返回Session的ID。该ID由服务器自动创建,不会重复
getLastAccessedTime()	返回Session的最后活跃时间。返回类型为long
getMaxInactiveInterval()	返回Session的超时时间。单位为秒。

测试代码:

jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form method="post" action="/test3">
        <input type="submit" value="提交">
    </form>
</body>
</html>

------------------------分割线----------------------------------------------
servlet代码:

package com.southwind.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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/test3")
public class SessionServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("UTF-8");

        HttpSession session = req.getSession();
        session.setAttribute("name","tom");
        resp.getWriter().println("setAttribute()= "+session.getAttribute("name"));
        resp.getWriter().println("getCreationTime()= "+session.getCreationTime());
        resp.getWriter().println("getId()= "+session.getId());
        resp.getWriter().println("getLastAccessedTime()= "+session.getLastAccessedTime());
        resp.getWriter().println("getMaxInactiveInterval()= "+session.getMaxInactiveInterval());
        
    }
}

输出:

response headers token 如何获取_客户端_06