一、Http协议

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
·HTTP是基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
·HTTP协议工作于客户端-服务端架构(C/S)上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

常见服务器
Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。

1.1 HTTP 消息结构

HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
一个HTTP”客户端”是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。
一个HTTP”服务器”同样也是一个应用程序(通常是一个Web服务,如Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送HTTP响应数据。

1.2 客户端请求消息

image.png
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)请求头部(header)空行请求数据四个部分组成,下面给出了请求报文的一般格式。
请求方法 空格 URL 空格 协议版本 回车符 换行符 请求行
头部字段名:值 回车符 换行符
…… 请求头
头部字段名:值 回车符 换行符
回车符 换行符
data 请求数据

例如:
image.png
请求头
image.png


1.3 Http请求方法

根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

** ** **
1 GET 请求指定的页面信息,并返回实体主体
2 HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件),数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改
4 PUT 从客户端向服务器传送的数据取代指定的文档的内容
5 DELETE 请求服务器删除指定的页面
6 CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器
7 OPTIONS 允许客户端查看服务器的性能
8 TRACE 回显服务器收到的请求,主要用于测试或诊断

**

1.4 Get与Post的区别

·GET**方式提交**
a)地址栏(URI)会跟上参数数据。以?开头,多个参数之间以&分割。
b)GET提交参数数据有限制,不超过1KB。
c)GET方式不适合提交敏感密码。
d)注意: 浏览器直接访问的请求,默认提交方式是GET方式image.png
·POST**方式提交**
a)参数不会跟着URI后面。参数而是跟在请求的实体内容中。没有?开头,多个参数之间以&分割。
b)POST提交的参数数据没有限制。
c)POST方式提交敏感数据。
image.png

1.5 Http状态码

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

** **
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误


常见的HTTP状态码:
200 请求成功
301 资源(网页等)被永久转移到其它URL
404 请求的资源(网页等)不存在
500 内部服务器错误

** ** **
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
** ** **请求成功。一般用于GET与POST
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
** **_Found **临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
** ** 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
** ** **
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
** ** **服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”
** ** **
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
** ** **
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
** ** **
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

1.6 Http请求头

1.6.1 客户端http请求

以下是浏览器端的重要头信息

** **
Accept 指定浏览器或其他客户端可以处理的 MIME()类型。
值 image/png 或 image/jpeg 是最常见的两种可能值。
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
Accept-Charset 指定浏览器可以用来显示信息的字符集。例如 ISO-8859-1。
Accept-Encoding 指定浏览器知道如何处理的编码类型。值 gzip 或 compress 是最常见的两种可能值。
Accept-Language 指定客户端的首选语言,在这种情况下,Servlet 会产生多种语言的结果。例如,en、en-us、ru 等。
Authorization 用于客户端在访问受密码保护的网页时识别自己的身份。
Connection 指示客户端是否可以处理持久 HTTP 连接。持久连接允许客户端或其他浏览器通过单个请求来检索多个文件。值 Keep-Alive 意味着使用了持续连接。
Content-Length 只适用于 POST 请求,并给出 POST 数据的大小(以字节为单位)
Cookie 把之前发送到浏览器的 cookies 返回到服务器。
Host 指定原始的 URL 中的主机和端口。
If-Modified-Since 表示只有当页面在指定的日期后已更改时,客户端想要的页面。如果没有新的结果可以使用,服务器会发送一个 304 代码,表示 Not Modified 头信息。
If-Unmodified-Since 是 If-Modified-Since 的对立面,它指定只有当文档早于指定日期时,操作才会成功。
Referer 指示所指向的 Web 页的 URL。例如,如果您在网页 1,点击一个链接到网页 2,当浏览器请求网页 2 时,网页 1 的 URL 就会包含在 Referer 头信息中。
User-Agent 识别发出请求的浏览器或其他客户端,并可以向不同类型的浏览器返回不同的内容。

1.6.2 读取 HTTP 头的方法

这些方法通过HttpServletRequest 对象可用
Servlet 处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析:

** **
String getParameter(String name) 以字符串形式返回请求参数的值,或者如果参数不存在则返回null。
Enumeration getParameterNames() 返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
getParameterValues() 如果参数有多个,则调用该方法,并返回多个值,例如复选框。
getParameterNames() 如果想要得到当前请求中的所有参数的完整列表,则调用该方法。
Map<> getParameterMap() 将参数封装成 Map 类型。
Enumeration getAttributeNames() 返回一个枚举,包含提供给该请求可用的属性名称。
Enumeration getHeaderNames() 返回一个枚举,包含在该请求中包含的所有的头名。
HttpSession getSession() 返回与该请求关联的当前 session 会话,或者如果请求没有session 会话,则创建一个。
Object getAttribute(String name) 以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。
ServletInputStream getInputStream() 使用 ServletInputStream,以二进制数据形式检索请求的主体。
String getCharacterEncoding() 返回请求主体中使用的字符编码的名称。
String getContextPath() 返回指示请求上下文的请求 URI 部分。
String getHeader(String name) 以字符串形式返回指定的请求头的值。
String getMethod() 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String[] getParameterValues(String name) 返回一个字符串对象的数组,包含将参数封装成 Map 类型。

1.6.3 服务器端http请求

一下字段是servlet用来向浏览器传递信息

** **
Allow 指定服务器支持的请求方法(GET、POST 等)。
Cache-Control 指定响应文档在何种情况下可以安全地缓存。可能的值有:public、private 或no-cache等。Public 意味着文档是可缓存,Private 意味着文档是单个用户私用文档,且只能存储在私有(非共享)缓存中,no-cache 意味着文档不应被缓存。
Connection 指示浏览器是否使用持久 HTTP 连接。值 close 指示浏览器不使用持久 HTTP 连接,值 keep-alive 意味着使用持久连接。
Content-Disposition 可以让您请求浏览器要求用户以给定名称的文件把响应保存到磁盘。
Content-Encoding 在传输过程中,这个头信息指定页面的编码方式。
Content-Language 表示文档编写所使用的语言。例如,en、en-us、ru 等。
Content-Length 指示响应中的字节数。只有当浏览器使用持久(keep-alive)HTTP 连接时才需要这些信息。
Content-Type 提供了响应文档的 MIME(Multipurpose Internet Mail Extension)类型。
Expires:-1 指定内容过期的时间,在这之后内容不再被缓存。
Cache-Control:no-cache
Pragma:no-cache
Last-Modified
这三个经常合用
指示文档的最后修改时间。然后,客户端可以缓存文件,并在以后的请求中通过 If-Modified-Since 请求头信息提供一个日期。
Location 应被包含在所有的带有状态码的响应中。在 300s 内,这会通知浏览器文档的地址。浏览器会自动重新连接到这个位置,并获取新的文档。
Refresh 指定浏览器应该如何尽快请求更新的页面。您可以指定页面刷新的秒数。
Retry-After 可以与 503(Service Unavailable 服务不可用)响应配合使用,这会告诉客户端多久就可以重复它的请求。
Set-Cookie 指定一个与页面关联的 cookie。


设置消息头的方法

** **
boolean containsHeader(String name) 返回一个布尔值,指示是否已经设置已命名的响应报头。
boolean isCommitted() 返回一个布尔值,指示响应是否已经提交。
void addCookie(Cookie cookie) 把指定的 cookie 添加到响应。
void addDateHeader(String name, long date) 添加一个带有给定的名称和日期值的响应报头。
void addHeader(String name, String value) 添加一个带有给定的名称和值的响应报头。
void flushBuffer() 强制任何在缓冲区中的内容被写入到客户端。
void reset() 清除缓冲区中存在的任何数据,包括状态码和头。
void resetBuffer() 清除响应中基础缓冲区的内容,不清除状态码和头。
void sendError(int sc) 使用指定的状态码发送错误响应到客户端,并清除缓冲区。
void sendError(int sc, String msg) 使用指定的状态发送错误响应到客户端。
void setHeader(String name, String value) 设置一个带有给定的名称和值的响应报头。
void setStatus(int sc) 为该响应设置状态码。
void sendRedirect(String location) 使用指定的重定向位置 URL 发送临时重定向响应到客户端。

二、Dao三层架构

2.1 Dao三层架构

DAO层:操作数据库(mapper
service层:服务层,编写一些复杂的业务逻辑
表示层:Servlet,提出需求,控制流程

案例: 顾客去饭店吃饭
顾客:表示层 提需求 菜单
服务员:服务层
厨师:DAO
image.png

2.2 MVC与DAO之间的关系

image.png
37 - Http协议、Dao三层架构、MVC三层架构、Ajax - 图8

三、Dao三层架构代码实现

ServletMapper之间增加了一层中间层Service
37 - Http协议、Dao三层架构、MVC三层架构、Ajax - 图9
代码举例:
image.png

3.1 UserMapper接口与xml

UserMapper接口:

  1. package com.woniuxy.mapper;
  2. import com.woniuxy.entity.User;
  3. public interface UserMapper {
  4. User findUserByAccount(String account);
  5. }

UserMapper.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.woniuxy.mapper.UserMapper">
  6. <select id="findUserByAccount" resultType="User">
  7. select * from mall_user where account = #{account}
  8. </select>
  9. </mapper>

3.2 UserService接口和实现类

UserService接口:

package com.woniuxy.service;

import com.woniuxy.entity.User;

public interface UserService {
    User findUserByAccount(String account);
}

UserServiceImpl:

package com.woniuxy.service.impl;

import com.woniuxy.entity.User;
import com.woniuxy.mapper.UserMapper;
import com.woniuxy.service.UserService;
import com.woniuxy.utils.MybatisUtil;

public class UserServiceImpl implements UserService{
    // 将mapper作为service实现类的属性
    private UserMapper userMapper = MybatisUtil.getSqlSesson().getMapper(UserMapper.class);

    @Override
    public User findUserByAccount(String account) {
        return userMapper.findUserByAccount(account);
    }
}

3.3 UserServlet

package com.woniuxy.servlet;

import java.io.IOException;

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

import com.woniuxy.entity.User;
import com.woniuxy.service.UserService;
import com.woniuxy.service.impl.UserServiceImpl;

public class UserServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    public UserServlet() {
        super();
    }

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

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String uri = request.getRequestURI();
        if(uri.endsWith("/login")) {
            // 登录 执行登录的业务代码
            login(request, response);
        }else if(uri.endsWith("/regist")) {
            // 注册业务
        }
    }

    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取前端输入的数据
        String account = request.getParameter("account");
        String password = request.getParameter("password");

        // 调用service接口的方法获取想要的数据
        UserService userService = new UserServiceImpl();
        User user = userService.findUserByAccount(account);

        // 设置字符编码
//        response.setCharacterEncoding("UTF-8");
        // 同时设置返回数据类型和编码
        response.setContentType("text/html;charset=utf-8");

        // 判断账号密码
        if(user == null || !user.getPassword().equals(password)) {
            // 账号或密码有误
            response.getWriter().write("账号或密码有误");// 会自动将字符串放到页面中返回
        }else {
            // 账号密码无误
            response.getWriter().write("登录成功");
        }
    }
}

3.4 用于创建SqlSession对象的工具类

MybatisUtil:

package com.woniuxy.utils;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisUtil {
    private static InputStream inputStream=null;
    private static SqlSessionFactory factory=null;

    // 利用静态代码块只执行一次的原理,创建一次工厂
    static {
        try {
            inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            factory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSesson() {
        if(factory!=null) {
            return factory.openSession();
        }
        return null;
    }

}

四、AJAX

AJAX = Asynchronous JavaScript and XML(异步 JavaScript XML)。
AJAX不是新的编程语言,而是一种使用现有标准的新方法。
AJAX最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

什么是AJAX ?
·AJAX = 异步 JavaScript 和 XML。
·AJAX是一种用于创建快速动态网页的技术。
·通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
·传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
·有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。
image.png
js代码:

<script>
function loadXMLDoc()
{
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            document.getElementById("data_div").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET","URL",true);
    xmlhttp.send();
}
</script>

服务端响应onreadystatechange事件可以传递一个函数的名称,当XMLHttpRequest 对象的状态发生改变时,会触发此函数。状态从 0 (uninitialized) 到 4 (complete) 进行变化. 事件使代码复杂化了。但是这是在没有得到服务器响应的情况下,防止代码停止的最安全的方法。
readyState状态表示XMLHttpRequest对象的状态

状态 解释
0 未初始化。对象已创建,未调用open
1 open方法成功调用,但send方法未调用
2 send方法已调用,尚未开始接收数据
3 正在接收数据,http响应头信息以及接收,单位接收完成
4 完成,数据接收完成


每当 readyState 改变时,就会触发 onreadystatechange 事件

·responseText信息服务器响应的文本内容.
·responseXML对象服务器响应的XML内容对应的DOM对象.
·statusText服务器返回状态的文本信息。
setRequestHeader(name,value)自定义HTTP头部信息。需在open()方法之后和send()之前调用,才能成功发送请求头部信息。