002 web基础之手动实现简易web服务框架

目录

  • 一、软件开发架构
  • 二、实现一个简单的web服务
    • 2.1 S端修正版本
    • 2.2 S端将html标签返回
    • 2.3 浏览器携带参数访问S端时的处理
    • 2.4 S端返回html页面给浏览器
    • 2.5 减少代码冗余的server端
  • 三、基于wsgrief模块实现简易web服务框架
    • 3.1 通过后端获取当前时间展示到前端
    • 3.2 后端通过获取数据库的信息,展示到前端页面

一、软件开发架构

C/S 客户端 服务端

B/S 浏览器和服务端

注意:B/S 的本质也是C/S架构

二、实现一个简单的web服务

我们无需开发浏览器(本质即套接字客户端),只需要开发S端即可,S端的本质就是用套接字实现的,如下

# server 端
import socket

server = socket.socket() # 实例化一个server对象
server.bind(('127.0.0.1', 8080))# server对象绑定端口号
'''
特别提示:
1. 127.0.0.1 是本机的回环地址,只有本机可以访问
2.端口是唯一标识计算机的某一个应用程序
3. 端口号在用的时候尽量用8000以上的
4. 1-1024 是操作系统自己用的
5.还有一些特殊的是代表其他的应用软件的
'''

# TCP半开连接是指发送了TCP连接请求,等待对方应答的状态,此时连接并没有完全建立起来,双方还无法进行通信交互的状态,此时就称为半连接。由于一个完整的TCP连接需要经过三次握手才能完成,这里把三次握手之前的连接都称之为半连接。
server.listen(5) 

while True:
   # 客户端/浏览器 连接服务端的时候,会产生客户端/浏览器 的地址和连接对象
    conn,addr = server.accept()

    # 由于是基于B/S 架构,所以接收浏览器的请求信息
    data = conn.recv(1024)

    # 接收了请求以后,给浏览器发送响应信息
    conn.send(b'hello world!')
    conn.close()

## 这个时候当浏览器访问服务器的地址时就会出现服务器和浏览器响应信息
127.0.0.1:8080 (尽量用谷歌浏览器)

注意:以上的S端已经可以正常接收浏览器发来的请求信息了,但是浏览器在接收到S端回复的响应消息b‘hello world’时却不能正常的解析,此处是因为浏览器和S端之间收发消息默认使用的应用层协议是Http协议,浏览器默认以http协议规定的格式发消息,而s端也必须按照http协议的格式回消息才行

2.1 S端修正版本

处理HTTP协议的请求信息,并按照HTTP协议的格式响应回复信息

# server端修正版
import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
'''
特别提示:
1. 127.0.0.1 是本机的回环地址,只有本机可以访问
2.端口是唯一标识计算机的某一个应用程序
3. 端口号在用的时候尽量用8000以上的
4. 1-1024 是操作系统自己用的
5.还有一些特殊的是代表其他的应用软件的
'''

server.listen(5) 

while True:

    conn,addr = server.accept()

    data = conn.recv(1024)

    conn.send(b'http://1.1 200 ok\r\n\r\n')# 此处是服务端给浏览器发送的协议
    conn.send(b'hello world!')
    conn.close()

## 这个时候当浏览器访问服务器的地址时就会出现服务器给浏览器正确响应信息
127.0.0.1:8080 (尽量用谷歌浏览器)

## 此时重新启动S端就可以看到解析正确的hello world了

2.2 S端将html标签返回

# server端返回html标签
import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
'''
特别提示:
1. 127.0.0.1 是本机的回环地址,只有本机可以访问
2.端口是唯一标识计算机的某一个应用程序
3. 端口号在用的时候尽量用8000以上的
4. 1-1024 是操作系统自己用的
5.还有一些特殊的是代表其他的应用软件的
'''

server.listen(5) 

while True:
    conn,addr = server.accept()
    data = conn.recv(1024)

    conn.send(b'http://1.1 200 ok\r\n\r\n')
    # 返回html标签
    conn.send(b'<p>hello world!</p>')
    conn.close()

2.3 浏览器携带参数访问S端时的处理

# 浏览器访问 127.0.0.1:8080/index
import socket

server = socket.socket()
server.bind(("127.0.0.1", 8080))
server.listen(5)
while True:
    conn, addr = server.accept()

    # 接收浏览器的请求
    data = conn.recv(1024)
    current_path = data.decode('utf8')
    # print(current_path)

    # 在这里我们会发现用户访问服务端的一些信息
    '''
    请求头\r\n
    请求首行\r\n
    \r\n
    请求体
    '''
    # 通过接收到的信息进行字符串切割的方法去到用户访问服务端时携带的参数
    path_info = current_path.split(' ')[1]
    print(path_info)

    # 规定和浏览器使用的传输协议,我们都要遵守
    # tcp连接时传输时通过二进制的形式
    conn.send(b'http://1.1 200 ok \r\n\r\n')

    # 判断用户携带的参数是否有我服务端的权限,是否可以正确的与服务端之间进行通信
    if path_info=="/index":
        conn.send(b'hello index')
        conn.close()

    elif path_info=="/login":
        conn.send(b'<p>hello world!</p>')
        conn.close()

    else:
        conn.send(b'404')
        conn.close()

2.4 S端返回html页面给浏览器

# index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="python folder/bootstrap/js/bootstrap.min.js"></script>
    <link href="python folder/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1 ">
    <title>index</title>
</head>
<body>
<p>hello 我是index</p>
</body>
</html>
# login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="python folder/bootstrap/js/bootstrap.min.js"></script>
    <link href="python folder/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1 ">
    <title>lgoin</title>
</head>
<body>
<p>hello 我是login</p>
</body>
</html>
# server 端返回html文件渲染浏览器页面
import socket

server = socket.socket()
server.bind(("127.0.0.1", 8080))
server.listen(5)

while True:

    conn, addr = server.accept()

    # 接收浏览器的请求
    data = conn.recv(1024)
    current_path = data.decode('utf8')
    # print(current_path)
    # 在这里我们会发现用户访问服务端的一些信息
    '''
    请求头\r\n
    请求首行\r\n
    \r\n
    请求体
    '''
    # 通过接收到的信息进行字符串切割的方法去到用户访问服务端时携带的参数
    path_info = current_path.split(' ')[1]
    print(path_info)

    conn.send(b'http://1.1 200 ok \r\n\r\n')
    # 判断用户携带的参数是否有我服务端的权限,是否可以正确的与服务端之间进行通信
    if path_info=="/index": # 如果浏览器携带的参数是可以访问服务器的就打开html文件,以rb读取内容,响应给浏览器,此时浏览器矿口会看到相应的html页面
        with open('index.html','rb') as fr:
            data = fr.read()
        conn.send(data)
        conn.close()

    elif path_info=="/login":
        with open('login.html','rb') as fr:
            data = fr.read()
        conn.send(data)
        conn.close()

    else:
        conn.send(b'404')
        conn.close()

2.5 减少代码冗余的server端

# index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="python folder/bootstrap/js/bootstrap.min.js"></script>
    <link href="python folder/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1 ">
    <title>index</title>
</head>
<body>
<p>hello my index</p>
</body>
</html>
# login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="python folder/bootstrap/js/bootstrap.min.js"></script>
    <link href="python folder/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1 ">
    <title>lgoin</title>
</head>
<body>
<p>hello my login</p>
</body>
</html>
# server减少代码冗余

import socket

server = socket.socket()

server.bind(("127.0.0.1", 8080))
server.listen(5)  # 相当于半连接池,只能一次接受5个客户端的访问,这个时候服务端处于监听的状态,等待客户端的连接

# 通过进行判断,执行任务的接口函数
def index():
    with open('index.html','r') as fr:
        data = fr.read()
    return data

def login():
    with open('login.html','r') as fr:
        data = fr.read()
    return data

def earro():
    return '404'

# 这是为了减少代码的冗余,把用户携带的参数放在一个固定的列表里
# 通过进行判断,任务分发的方式去调用这些接口
urls_list = [
    ('/index',index),
    ('/login',login)
]

while True:
    conn, addr = server.accept()

    #接收浏览器的请求
    data = conn.recv(1024)
    current_path = data.decode('utf8')
    conn.send(b'http://1.1 200 ok\r\n\r\n')
    # print(current_path)
    # 在这里我们会发现用户访问服务端的一些信息
    '''
    请求头\r\n
    请求首行\r\n
    \r\n
    请求体
    '''
    # 通过接收到的信息进行字符串切割的方法去到用户访问服务端时携带的参数
    path_info = current_path.split(' ')[1]
    # print(path_info)

    func = None # 定义一个获取用户携带参数的
    for url in urls_list:
        if path_info == url[0]:
            func = url[1]
            break #只要一匹配到,我退出循环,减少消耗的资源

    # 这里是判断func用户请求我的时候,有没有参数,
    # 若有则取执行响应的功能
    if func:
        res = func()
    else:
       res = earro()

    # 执行对应的接口函数过后,我们会接收到函数返回给我们的字符串值
    # 发给用户的时候,我们要转换为二进制的形式去发送
    conn.send(res.encode('utf8'))
    conn.close()

三、基于wsgrief模块实现简易web服务框架

这个模块实现了上面的所有手动去写原生怠慢的过程

根据每个部分功能不同,将他们分成不同的py文件

urls.py:只用来存放路由与视图函数对应的关系的

View.py:用来存放视图函数(函数、类)

拆分完成后,如果想要给一个应用添加应用,仅仅只需要在urls.py和View.py两个文件里改就可以了

并且使用wsgrief模块的本质是将不用我们自己去写server部分,而且我们是通过任务分发的方式去实现每个浏览器请求信息的,以下就是一个完整的例子

# urls.py文件

from views import *
# 此处是路由和功能函数的关系

# 通过进行判断,任务分发的方式去调用这些接口
urls_list = [
    ('/index', index),
    ('/login', login),
]
# views.py

# 这里是用户视图的
# 通过进行判断,执行任务的接口函数
def index(env):
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\index.html', 'r') as fr:
        data = fr.read()
    return data

def login(env):
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\login.html', 'r') as fr:
        data = fr.read()
    return data

def error(env):
    return '404'
# server 端

from wsgiref.simple_server import make_server
from url_list import *

# 有客户端连接服务端的时候,服务端会将客户端进行的操作转给run函数来处理
def run(env, response):
    '''
    :param env: 客户端请求的相关数据
    :param response: 服务端响应的所有数据
    :return:
    '''

    response('200 ok', []) # 这里涉及到浏览器访问后台的一些状态码

    current_path = env.get('PATH_INFO') # wsgiref帮我们返回了用户所有的信息,以字典的形式返回的
    # 我们通过查找发现,用户请求服务端的时候,携带的参数是在PATH_INFo:values

    # 先定义一个变量名:用来从存储后续匹配到的用户请求我携带的参数
    func = None
    for url in urls_list:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就将匹配到的函数名赋值给func变量
            break  # 主动结束匹配
        # 判断func是否有值

    if func:
        res = func(env) # 这里把env传给每一个功能函数,方便日后可能会用到
    else:
        res = error(env)
    return [res.encode('utf-8')]

if __name__ == '__main__':
    # 实时监听该地址  只要有客户端来连接 统一交给run函数去处理
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()  # 启动服务端

3.1 通过后端获取当前时间展示到前端

# 这里是用户视图的
# 通过进行判断,执行任务的接口函数
def index(env):
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\index.html', 'r') as fr:
        data = fr.read()
    return data

def login(env):
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\login.html', 'r') as fr:
        data = fr.read()
    return data

def error(env):
    return '404'

# 用于显示当前时间的
import datetime
def get_time(env):
    current_time = datetime.datetime.now()
    current_time = current_time.strftime('%Y-%m-%d %X')

    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\get_time.html','r') as fr:
        data = fr.read()
        data = data.replace('time',current_time)

        # 我们也可以通过特定的语法来帮我们实现,一般都是用规定的字符
        # data = data.replace('$$time$$',current_time)
    return data
# urls.py
from views import *
# 此出是路由和功能函数的关系

# 通过进行判断,任务分发的方式去调用这些接口
urls_list = [
    ('/index', index),
    ('/login', login),
    ('/get_time', get_time),
    ('/get_user', get_user),
]
# server 端

from wsgiref.simple_server import make_server
from url_list import *

# 有客户端连接服务端的时候,服务端会将客户端进行的操作转给run函数来处理
def run(env, response):
    '''
    :param env: 客户端请求的相关数据
    :param response: 服务端响应的所有数据
    :return:
    '''

    response('200 ok', []) # 这里涉及到浏览器访问后台的一些状态码

    current_path = env.get('PATH_INFO') # wsgiref帮我们返回了用户所有的信息,以字典的形式返回的
    # 我们通过查找发现,用户请求服务端的时候,携带的参数是在PATH_INFo:values

    # 先定义一个变量名:用来从存储后续匹配到的用户请求我携带的参数
    func = None
    for url in urls_list:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就将匹配到的函数名赋值给func变量
            break  # 主动结束匹配
        # 判断func是否有值

    if func:
        res = func(env) # 这里把env传给每一个功能函数,方便日后可能会用到
    else:
        res = error(env)
    return [res.encode('utf-8')]

if __name__ == '__main__':
    # 实时监听该地址  只要有客户端来连接 统一交给run函数去处理
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()  # 启动服务端

3.2 后端通过获取数据库的信息,展示到前端页面

此处提出一个概念:模板的渲染

模板的渲染:后端获取的数据 传递给前端页面就叫做模板的渲染

现在又有一个包可以帮我们实现这个任务了jinja2

安装方式:pip3 install jinja2

模板语法(极其贴近python后端语法)

# 这里是下面的一个例子可以将字典相应给前端页面,然后通过点取值的方式
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('hobby') }}</p>

?
? #通过获取数据库的数据,然后渲染到前端页面
? {% for user_dict in user_list %}
?

?

{{ user_dict.id }}

?

{{ user_dict.name }}

?

{{ user_dict.pwd }}

?

? {% endfor %}

# viess.py
# Author:Cecilia

# 这里是用户视图的
# 通过进行判断,执行任务的接口函数
def index(env):
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\index.html', 'r') as fr:
        data = fr.read()
    return data

def login(env):
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\login.html', 'r') as fr:
        data = fr.read()
    return data

def error(env):
    return '404'

# 用于显示当前时间的
import datetime
def get_time(env):
    current_time = datetime.datetime.now()
    current_time = current_time.strftime('%Y-%m-%d %X')

    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\get_time.html','r') as fr:
        data = fr.read()
        data = data.replace('time',current_time)

        # 我们也可以通过特定的语法来帮我们实现,一般都是用规定的字符
        # data = data.replace('$$time$$',current_time)
    return data

# 现在我们有一个需求,就是我后台有一个字典,我需要从后台去渲染前端的页面
# 并且让用户在浏览器通过输入字典的key九可以取值
# 这个时候我们需要导入一个jinja2的模块来帮助我们实现,这是封装好的方法,我们直接用就可以了
from jinja2 import Template
def get_user(env):
    d = {'name':'cecilia','age':18,'sex':'female','hobbies':['run','sing','play']}
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\get_user.html','r') as fr:
        data = fr.read()

    # 我们拿到get_userhtml文件的文本格式以后
    # 通过jinja2库的Template模块来帮我们完成
    temp = Template(data)
    res = temp.render(user=d)# 将字典d传递给前端页面 页面上通过变量名user就能够获取到该字典
    return res

#我们需要从数据库里面取值
import pymysql
def get_db(env):
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        database = 'mydb',
        user = 'root',
        password = '123',
        charset = 'utf8',
        autocommit = True
    )

    # 获取游标对象
    curser = conn.cursor(pymysql.cursors.DictCursor)
    sql = 'select * from userinfo'
    curser.execute(sql)
    res = curser.fetchall()
    with open(r'E:\python folder\GjanGO框架\01 server_bs_web 基础\04 基于wsgire 的server\04 web推导框架\templates\get_db.html','r',encoding='utf8') as fr:
        data = fr.read()

    temp = Template(data)
    ret = temp.render(user_list = res) # 将从数据库里取出来的值,放进我们get_db html页面种
    return ret
# urls.py
from views import *

# 通过进行判断,任务分发的方式去调用这些接口
urls_list = [
    ('/index', index),
    ('/login', login),
    ('/get_time', get_time),
    ('/get_user', get_user),
    ('/get_db', get_db),
]
# server 端

from wsgiref.simple_server import make_server
from url_list import *

# 有客户端连接服务端的时候,服务端会将客户端进行的操作转给run函数来处理
def run(env, response):
    '''
    :param env: 客户端请求的相关数据
    :param response: 服务端响应的所有数据
    :return:
    '''

    response('200 ok', []) # 这里涉及到浏览器访问后台的一些状态码

    current_path = env.get('PATH_INFO') # wsgiref帮我们返回了用户所有的信息,以字典的形式返回的
    # 我们通过查找发现,用户请求服务端的时候,携带的参数是在PATH_INFo:values

    # 先定义一个变量名:用来从存储后续匹配到的用户请求我携带的参数
    func = None
    for url in urls_list:
        if current_path == url[0]:
            func = url[1]  # 一旦匹配成功 就将匹配到的函数名赋值给func变量
            break  # 主动结束匹配
        # 判断func是否有值

    if func:
        res = func(env) # 这里把env传给每一个功能函数,方便日后可能会用到
    else:
        res = error(env)
    return [res.encode('utf-8')]

if __name__ == '__main__':
    # 实时监听该地址  只要有客户端来连接 统一交给run函数去处理
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()  # 启动服务端

注意:在这里我们发现,不管我们添加多少个功能,我们的server页面都没有变过,所以这就是我们的web框架

注意2:在我们的功能逐渐变多时,我们此时可能要写很多个html页面,这样会影响到我们调式代码,所以在这里,我们把这些html页面单独拿出来放在一个文件夹里(templates文件夹)

原文地址:https://www.cnblogs.com/XuChengNotes/p/11717306.html

时间: 2024-10-08 23:38:51

002 web基础之手动实现简易web服务框架的相关文章

Java web基础总结三之—— java web 服务器

Java web基础总结三之-- java web 服务器 一.什么是java web服务器 首先来看一下什么是web服务器,它一般指网站服务器,是指一个再互联网一个主机上的一个程序.它可以解析客户端发送来的遵循http协议的请求,并且经过逻辑业务处理后,以http协议向浏览器等Web客户端提供文档. 互联网上供外界访问的Web资源可以分为两种:一个是静态web资源(如html 页面),指web页面中供人们浏览的数据始终是不变.另一个动态web资源,指web页面中供人们浏览的数据是由程序动态产生

Golang友团无闻Go语言Web基础视频教程

教程内容:GO语言资料Golang友团无闻Go语言编程基础Golang友团无闻Go语言Web基础教程 Go语言Web基础教程列表:[Go Web基础]12Go Web 扩展学习.mp4[Go Web基础]11简易的 RPC 实现.mp4[Go Web基础]10自建 HTTP 中间件.mp4[Go Web基础]09国际化支持.mp4[Go Web基础]08文章附件上传.mp4[Go Web基础]07为文章添加标签.mp4[Go Web基础]06评论与分类显示.mp4[Go Web基础]05文章的添

20145311 王亦徐 《网络对抗技术》 Web基础

20145311 王亦徐 <网络对抗技术> Web基础 实验内容 简单的web前端页面(HTML.CSS等) 简单的web后台数据处理(PHP) Mysql数据库 一个简单的web登陆页面例子 SQL注入.XSS攻击 基础问题回答 (1)什么是表单 表单我觉得主要是用来在网页中采集数据用的,提供了填写数据.选择数据,收集数据并提交给后台的功能,包括很多种表单元素,例如文本框.下拉框.单选复选框等 百度上说一个表单有三个基本组成部分:表单标签(form).表单域(填写数据).表单按钮(提交) (

从Java Web 基础看SSH架构

Java Web开发现在已然成为大型Wed项目的标准,之前一直盲目的使用框架,往往知其然不知其所以然.在经过一段时间的学习与开发,大概掌握了其脉络的基础上,对其做一定总结. 一.Java Web 基础 一个典型的Java Web项目往往包含这些元素:Jsp页面.Servlet.Listener.Filter,以及配置文件web.xml.其中: Jsp和Servlet基本是一回事,主要用来响应客户端的请求.当然Jsp中可以直接嵌入HTML标签,主要还是负责展现. Listener则是负责监听Web

Python全栈开发之17、tornado和web基础知识

一.web基础知识 学习web框架之前,先来看一下web基础知识,首先要明白其本质就是socket,用户对应一个socket客户端,但是如果从socket开始开发web应用程序那么效率太了,正确的做法是底层socket处理代码由专门的服务器软件实现,而对于真实开发中的python web程序来说也是一般会分为两部分:服务器程序和应用程序.服务器程序负责对socket服务器进行封装,并在请求到来时,先经过web服务器,对请求的各种数据进行整理封装.之后web服务器将封装好的数据传递给应用程序,应用

Java Web基础小结之Jsp JavaBean

Java Web基础小结In computing, Java Web Start (also known as JavaWS, javaws or JAWS) is a framework developed by Sun Microsystems (now Oracle) that allows users to start application software for the Java Pl... http://bbs.chinaacc.com/forum-2-3/offset-1/to

20155201 网络攻防技术 实验八 Web基础

20155201 网络攻防技术 实验八 Web基础 一.实践内容 Web前端HTML,能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. Web前端javascipt,理解JavaScript的基本功能,理解DOM.编写JavaScript验证用户名.密码的规则. Web后端:MySQL基础:正常安装.启动MySQL,建库.创建用户.修改密码.建表. Web后端:编写PHP网页,连接数据库,进行用户认证. 最简单的SQL注入,XSS攻击测

Java Web 基础 --- Filter 综述

摘要: 伴随J2EE一起发布的Servlet规范中还包括一个重要的组件--过滤器(Filter).过滤器可以认为是Servlet的一种加强版,它主要用于对用户请求进行预处理以及对服务器响应进行后处理,是个典型的处理链.Servlet规范使用了三个接口对过滤器进行了抽象,即Filter是对具体过滤器的抽象,FilterChain是基于AOP理念对责任链方面的抽象,FilterConfig则是对Filter配置的抽象.本文概述了Filter的提出动机.工作原理.使用流程和应用实例,并指出Java W

十倍效能提升——Web 基础研发体系的建立

1 导读 web 基础研发体系指的是, web 研发中一线工程师所直接操作的技术.工具,以及所属组织架构的总和.在过去提升企业研发效能的讨论中,围绕的主题基本都是——”通过云计算.云存储等方式将底层核心技术封装成基础设施“.而我们在实践中发现,在 互联网渗入到各行各业,业务爆发 企业竞争白热化,对速度和品质要求越来越高 一线工程师队伍越来越庞大,管理成本增高 这样的多重背景下,除了底层核心技术外,一线 web 研发效能的问题也逐渐成为决胜战场的重要因素. 然而在现实中我们看到,因为一线的研发工作