當前位置:首頁 » 網頁前端 » 設立一個web框架
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

設立一個web框架

發布時間: 2023-01-19 05:40:29

A. 如何設計一個JavaWeb MVC框架

首先要明白mvc框架的主要目的:把視圖和邏輯分開,就是降低界面和代碼的耦合度。不知道問的是java的mvc還是點net的mvc,總之目的都一樣。
1.重寫路由和定址,配置大於設計。MVC的C最重要,就是控制器最重要,尤其是自己的項目越來越大,模塊越來越獨立,更要注重路由和定址。可以高效的管理和開發在同一項目里的不同子系統。
2.動態可配。凡事頁面動態現實的信息,盡量抽取出來做成可配的數據,公共信息一般存在xml裡面,其他存資料庫。方便以後整體改版或升級。
3.分層開發,降低耦合度。把界面層,邏輯層,數據層的耦合度降到最低。例如: 想換一種資料庫,只需要修改數據層的代碼就行了,這樣對項目改動最小。千萬別資料庫查出來的數據直接送到UI層,這樣一改全改,一定要定義好每層之間的傳輸實體。
4.獨立成塊,可擴展。能獨立成模塊的盡量獨立出來,方便以後維護和擴展。比如想為android和ios提供api。不需要再重寫一遍相同的邏輯,直接把模塊拿來用就可以了。

B. 如何搭建web前端框架

搭建web前端框架步驟如下:
1、確定項目使用的技術
根據項目的需求等來選擇使用的技術(這里以angular4 + typsescript + nodejs+mongodb舉例)
2、新建一個項目的工作文件夾
使用npm init初始化項目,根據問題配置,一般是直接回車使用默認配置,生成package.json文件
3、新建一個index.html頁面
4、新建配置文件system.config.js
5、新建ts的配置文件tsconfig.json
npm install typescript

6、新建webApp目錄,這裡面放的是所有html頁面和js代碼,首先得有個入口文件,與system.config.js配置文件中的入口文件名一樣,app.mole.ts,裡面引入了所有js文件,不被引入的在載入時都不會被載入
7、打包(將代碼壓縮,使程序運行速度更快)

C. 誰可以教教我如何搭建一個java web框架

1,在MyEclipse新建出來的web project就是一個web項目,
2,假如你想使用別的開源框架,你開以下載相關jar包,比如可以下載Struts,hibernate和Spring的jar包,將jar包導入到項目中,最後配置xml文件,就是SSH項目了,

D. 如何用Python寫一個web框架

STEP.1

我們首先得選擇基於什麼協議來寫這種框架。我們可以選擇CGI協議,或者是WSGI介面。如果使用CGI,實際上我們只是按著CGI的規范寫了一個python程序,然後每次伺服器收到請求,就fork一個程序來執行它,然後返回一個http文檔,性能比較低下。對於WSGI,而是一個存在於伺服器和應用間的介面,在WSGI之前,web應用都是依賴於伺服器的,現在流行的python框架都支持WSGI介面。

STEP.2 PEP-333

這一段是PEP-333 所提供的樣例代碼。

def simple_app(environ, start_response):
"""Simplest possible application object"""
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return ['Hello world! ']

這里的application被傳入了兩個值。

  • environ

  • start_response。
    environ是一個字典,保存了http請求的信息。
    start_response是一個函數,發送http響應。她有兩個參數status 和 start_headers。

  • status必須是由狀態編號和具體信息組成的字元串,必須符合RFC 2616。

  • start_headers是一個(header_name,header_value) 元組的列表元組列表。其中的hearder_name必須是合法的http header欄位名。在RFC 2616, Section 4.2中有詳細定義。
    當然官方還給出了類的實現。

  • def __init__(self, environ, start_response):


  • self.environ = environ


  • self.start = start_response

  • def __iter__(self):


  • status = '200 OK'


  • response_headers = [('Content-type','text/plain')]


  • self.start(status, response_headers)


  • yield "Hello world! "

  • 了解了如上信息後,基本上可以開始了。我們就到官方給的代碼上進行修改吧。

    STEP.3 將路徑鏈接到函數

    首先我們得把用戶請求的路徑,鏈接到函數。我們可以實現一個getPage方法,專門做這件事。我們所擁有的信息,只有environ['PATH_INFO']。

  • urls = [('^/index/$','func_index'),

  • ('^/comment/$','func_comment'),

  • ('^/environ/$','get_environ'),

  • ('^/post/$','post_test')]#urls是提供給app開發者來做鏈接的。

  • def getPage(self):

  • path = self.environ['PATH_INFO']

  • for pattern in self.urls:

  • m = re.match(pattern[0],path)#將urls元素的第0項和path進行比對,如果匹配上了,返回函數名

  • if m:

  • function = getattr(self,pattern[1])#getattr方法來得到函數

  • return function()

  • return '404 not found'#沒匹配上任何東西

  • 寫到這里之後,每次添加頁面,就只需要在urls列表中添加一個元祖就行了。

    STEP.4 獲取模版

    既然是寫web app,模版肯定是得有的。這里我提供了一種getTemplate方法來做這件事。不過我只提供了變數的替換。

  • def getTemplate(self,tem_name,rep=0):

  • #這個函數返回內容,tem_name是文件名字

  • #參數rep是一個字典,默認為0

  • f = open('template/'+tem_name)

  • html = f.read()

  • if(rep!=0):

  • for to_replace in rep:

  • strinfo = re.compile('{\%s*'+str(to_replace)+'s*\%}')

  • html = strinfo.sub(rep[to_replace],html)

  • return html

  • STEP.5 POST數據的處理

    要想獲取POST數據,我們得通過environ['wsgi.input']來處理。而他實際上就是系統的標准輸入。

  • environ['wsgi.input'] = sys.stdin

  • 知道這點後就很好寫了。

  • def getPost(self):

  • if(self.environ['REQUEST_METHOD'] == 'POST'):

  • try:

  • request_body_size = int(self.environ.get('CONTENT_LENGTH', 0))#讀出content_length的值

  • except:

  • request_body_size = 0

  • request_body = self.environ['wsgi.input'].read(request_body_size) #請求的body

  • post_data = parse_qs(request_body)#parse_qs是cgi提供的方法,幫助我們處理請求

  • return post_data

  • 資料庫的鏈接

  • import Mysqldb

  • class Model(object):

  • def __init__(self):

  • self.host = 'localhost'

  • self.port = 3306

  • self.user = 'admin'

  • self.passwd = 'admin'

  • self.db = 'xieyi'

  • def build_connect(self):

  • self.conn = MySQLdb.connect(

  • host = self.host,

  • port = self.port,

  • user = self.user,

  • passwd = self.passwd,

  • db = self.db

  • )

  • def exec_ins(self,ins):

  • cur = self.conn.cursor()

  • num = cur.execute(ins)

  • info = {}

  • if(num>0):

  • info = cur.fetchmany(num)

  • cur.close()

  • self.conn.commit()

  • return info

  • def close(self):

  • self.conn.close()

  • STEP.6 清理工作

    很多配置如果放到代碼中,會增加閱讀負擔。於是把urls,model抽取出來。
    使得配置更加方便。



E. 如何開發一個Python web框架

首先你需要知道一個Web應用基本的請求處理流程。以最簡單最原始的動態網頁為例,你點擊鏈接(GET),提交表單(POST),就是與伺服器端建立了連接之後發送了一個HTTP請求(RFC2616 5.1節,之後都以HTTP 1.1為例),裡面至少有方法(動詞,就是GET啦POST什麼的,詳見RFC2616第9節),地址(URL),HTTP版本,還可能帶上Cookie(會話的一般實現機制),緩存相關的信息(RFC2616 13節),User-Agent串等等一堆信息。對於POST請求我們還有表單內容作為請求實體(RFC2616 7.2節),裡面是你填寫的表單內容。

於是我們有了一些關於請求的數據,不過現在一般來講這些數據還在前端伺服器(反向代理,比如nginx,暫且忽略掉負載均衡,反正是透明的,也不考慮裸WSGI容器直接扛請求的情況)的手上,還沒有傳進後端語言(這里是Python)。我們就針對每一種語言都有特定的機制,用來將HTTP的請求信息映射到相應的編程語言范疇,叫做Web伺服器界面(Web server interface),通用如CGI/FCGI/SCGI,特定於某一語言如WSGI/PSGI/Rack/...,特定於某一操作系統如ISAPI(這貨還活著?),一些已經不再使用的就不提了。總之在Python世界裡這就是WSGI(PEP 3333, Web Server Gateway Interface),它就定義了Python語言與Web伺服器之間的界面。在WSGI里,

請求的處理過程被映射為對應用callable的調用(application(environ, start_response),知乎不支持inline代碼塊?);
請求信息被映射到environ字典中的相應鍵值,比如請求方法被映射到environ['REQUEST_METHOD'],請求的「相對路徑」被映射到environ['PATH_INFO'](過度簡化;暫且不提WSGI應用掛載點,框架層一般也不用關心這個,掛載WSGI應用一般是WSGI容器如gunicorn、uWSGI之類組件的工作);
發送響應頭的動作被映射到調用start_response(status, response_headers)(不考慮可選的第三個參數異常信息);
返回響應數據被映射到application返回iterable的動作。
於是響應便從Python返回到Web伺服器,再被發送回瀏覽器,瀏覽器將響應內容渲染,一個請求就完成啦。

有了這樣的感性認識,那麼我們作為Python Web開發框架的作者,要做的事情就是在WSGI規范的基礎之上,提供盡可能便捷的開發手段和盡可能低的框架開銷,也即我們的代碼將要工作在WSGI與業務邏輯的中間層。架構上,Web開發框架或多或少都遵循MVC的設計模式(Django管它叫MTV,其實差不多)。同時,由於框架位於中間件的位置,加上其鼓勵模塊化與代碼復用的性質,自然需要為常見的HTTP操作提供抽象。這里就可以展開一些話題:
請求路徑到view/controller的映射,請求參數的解析(routing,也叫路由)。
正則匹配的方案,比如Django內置了一個簡單的正則表達式解析組件,能解析一般常見語法的正則表達式,把capturing groups解析成位置參數,named capturing groups解析成關鍵字參數。
也有DSL的方案,比如Werkzeug的路由組件。
請求實體的處理。表單解析,配合Web伺服器進行上傳文件處理。
正常的urlencoded表單,JSON表單,text/plain數據,multi-part表單
multi-part附件,附件操作API
大文件上傳(這個一般會被前端伺服器保存在磁碟上的臨時文件里,比方說nginx就是這么實現的)。
會話。HTTP是無狀態(stateless)的,這個特點非常重要。如果沒有會話,你連續做幾個請求,卻沒有手段證明你們是同一個人/同一台機器(你完全可能是代理伺服器)。
存儲會話數據的會話後端(內存數據結構?文件?RDBMS?Redis?Memcache?)
安全機制(HMAC什麼的,可以參考beaker的secure cookie實現)
請求處理流程中的會話中間件(從Cookie中提取會話,從query string中提取會話,從自定義頭中提取會話,等等)
View/Controller界面。發揮你的創造力,用上你的工程經驗。
Function-based or Class-based views? 參考:Django, Bottle, web.py, Tornado等一票框架的做法

框架的可選機制與服務如何暴露,
裝飾器?(比如@login_required 這種額外要求)
回調?(能想到的只有Tornado和Twisted這種非同步框架做事情的方式,還有整個JS生態系統都是回調(不考慮Promise什麼的)的思路)
傳入應用(業務邏輯)層的數據結構如何設計?(HttpRequest等價物,名字可能記不清了)
響應數據結構如何設計?(HttpResponse等價物,同上)
資料庫操作封裝。Web應用基本都是數據為中心,這個組件非常有必要,也是撰寫可復用代碼必須的一環,畢竟光是框架抽象了,資料庫操作還是裸SQL什麼的,到時候生產環境一換(比如MySQL變pgsql)還不是傻眼。
關系型資料庫。一站式解決方案參考:Django ORM、SQLAlchemy;輕量級解決方案參考各資料庫Python綁定。
非關系資料庫。各資料庫Python綁定(pymongo, riak, redis-py之類),這個沒什麼可替代方案了,因為本來各種NoSQL庫都是適應某一特殊需求設計的,沒什麼互相替換的必要,那意味著重新進行技術選型。

F. 如何開發一個Python web框架

在Python中,WSGI(Web Server Gateway Interface)定義了Web伺服器與Web應用(或Web框架)之間的標准介面。
在WSGI的規范下,各種各樣的Web伺服器和Web框架都可以很好的交互。
由於WSGI的存在,用Python寫一個簡單的Web框架也變得非常容易。然而,同很多其他的強大軟體一樣,要實現一個功能豐富、健壯高效的Web框架並非易事;如果您打算這么做,可能使用一個現成的Web框架(如 Django、Tornado、web.py 等)會是更合適的選擇。

G. 如何從零開始搭建一個javaweb企業級應用開發框架

關於JAVAweb的框架,現在大多數無非都是基於SSH(Spring,Struts2/SpringMVC和Hibernate)或者SSM(Spring,Struts2/SpringMVC和Mybatis)
這些現在大多網路都有教程和Demo,參照著多弄幾遍,就會用了,要理解還得反復推敲

建議:JAVA的基礎打牢,學的就快

H. 如何開發一個Python web框架

  • 預備知識

    web框架主要是實現web伺服器和web應用之間的交互。底層的網路協議主要有web伺服器完成。譬如監聽埠,填充報文等等。

  • Python內建函數__iter__和__call__和WSGI

  1. 迭代器iterator

    為類序列對象提供了類序列的介面,也就是說類序列對象可以通過迭代器像序列一樣進行迭代。

  2. __call__

    在類定義的時候實現了__call__方法,那麼該類的對象就是可調有的,即可以將對象當做函數來使用。

  3. WSGI

    用可調用的對象實現的:一個函數,一個方法或者一個可調用的實例。

  4. I. 搭建一個web框架需要哪些技術

    這需要看你的框架要達到什麼樣的標准:
    如果是靜態HTML,那麼需要掌握Html、css以及JS
    如果是動態的,那麼除了上述的要求,還需要掌握相關的腳本語言,如PHP、C#等。
    如果是利用某些CMS二次開發,則需要掌握底層CMS標簽或介面。

    J. 純 Python 寫一個 Web 框架,就是這么簡單

    造輪子是最好的一種學習方式,本文嘗試從0開始造個Python Web框架的輪子,我稱它為 ToyWebF 。

    本文操作環境為:MacOS,文中涉及的命令,請根據自己的系統進行替換。

    ToyWebF的簡單特性:

    下面我們來實現這些特性。

    首先,我們需要安裝gunicorn,回憶一下Flask框架,該框架有內置的Web伺服器,但不穩定,所以上線時通常會替換成uWSGI或gunicorn,這里不搞這個內置Web服務,直接使用gunicorn。

    我們創建新的目錄與Python虛擬環境,在該虛擬環境中安裝gunicorn

    在啥都沒有的情況下,構建最簡單的Web服務,在ToyWebF目錄下,創建app.py與api.py文件,寫入下面代碼。

    運行 gunicorn app:app 訪問 http://127.0.0.1:8000 ,可以看見 Hello, World! ,但現在請求體中的參數在environ變數中,難以解析,我們返回的response也是bytes形式。

    我們可以使用webob庫,將environ中的數據轉為Request對象,將需要返回的數據轉為Response對象,處理起來更加直觀方便,直接通過pip安裝一下。

    然後修改一下API類的 __call__方法 ,代碼如下。

    上述代碼中,通過webob庫的Request類將environ對象(請求的環境信息)轉為容易處理的request,隨後調用handle_request方法對request進行處理,處理的結果,通過response對象返回。

    handle_request方法在ToyWebF中非常重要,它會匹配出某個路由對應的處理方法,然後調用該方法處理請求並將處理的結果返回,在解析handle_request前,需要先討論路由注冊實現,代碼如下。

    其實就是將路由和方法存到self.routes字典中,可以通過route裝飾器的形式將路由和方法關聯,也可以通過add_route方法關聯,在app.py中使用一下。

    因為url中可以存在變數,如 @app.route("/hello/{name}") ,所以在匹配時,需要進行解析,可以使用正則匹配的方式進行匹配,parse這個第三方庫已經幫我們實現了相應的正則匹配邏輯,pip安裝使用一下則可。

    這里定義find_handler方法來實現對self.routes的遍歷。

    了解了路由與方法關聯的原理後,就可以實現handle_request方法,該方法主要的路徑就是根據路由調度對應的方法,代碼如下。

    在該方法中,首先實例化webob庫的Response對象,然後通過self.find_handler方法獲取此次請求路由對應的方法和對應的參數,比如。

    它將返回hello方法對象和name參數,如果是 /hello/二兩 ,那麼name就是二兩。

    因為route裝飾器可能裝飾器的類對象,比如。

    此時self.find_handler方法返回的hanler就是個類,但我們希望調用的是類中的get、post、delete等方法,所以需要一個簡單的判斷邏輯,通過inspect.isclass方法判斷handler如果是類對象,那麼就通過getattr方法獲取類對象實例的中對應的請求方法。

    如果類對象中沒有該方法屬性,則拋出該請求類型不被允許的錯誤,如果不是類對象或類對象中存在該方法屬性,則直接調用則可。

    此外,如果方法的路由並沒有注冊到self.routes中,即404的情況,定義了defalut_response方法返回其中內容,代碼如下。

    如果handle_request方法中調度的過程出現問題,則直接raise將錯誤拋出。

    至此,一個最簡單的web服務就編寫完成了。

    回顧Flask,Flask可以支持HTML、CSS、JavaScript等靜態文件,利用模板語言,可以構建出簡單但美觀的Web應用,我們讓TopWebF也支持這一功能,最終實現圖中的網站,完美兼容靜態文件。

    Flask使用了jinja2作為其html模板引擎,ToyWebF同樣使用jinja2,jinja2其實實現一種簡單的DSL(領域內語言),讓我們可以在HTML中通過特殊的語法改變HTML的結構,該項目非常值得研究學習。

    首先 pip install jinja2 ,然後就可以使用它了,在ToyWebF項目目錄中創建templates目錄,以該目錄作為默認的HTML文件根目錄,代碼如下。

    首先利用jinja2的FileSystemLoader類將file system中的某個文件夾作為loader,然後初始化Environment。

    在使用的過程中(即調用template方法),通過get_template方法獲得具體的某個模板並通過render方法將對應的內容傳遞給模板中的變數。

    這里我們不寫前端代碼,直接去互聯網中下載模板,這里下載了Bootstrap提供的免費模板,可以自行去 https://startbootstrap.com/themes/freelancer/ 下載,下載完後,你會獲得index.html以及對應的css、jss、img等文件,將index.html移動到ToyWebF/templates中並簡單修改了一下,添加一些變數。

    然後在app.py文件中為index.html定義路由以及需要的參數。

    至此html文件的支持就完成了,但此時的html無法正常載入css和js,導致頁面布局非常醜陋且交互無法使用。

    接著就讓ToyWebF支持css、js,首先在ToyWebF目錄下創建static文件夾用於存放css、js或img等靜態文件,隨後直接將前面下載的模板,其中的靜態文件復制到static中則可。

    通過whitenoise第三方庫,可以通過簡單的幾行代碼讓web框架支持css和js,不需要依賴nginx等服務,首先 pip install whitenoise ,隨後修改API類的 __init__ 方法,代碼如下。

    其實就是通過WhiteNoise將self.wsgi_app方法包裹起來,在調用API的 __call__ 方法時,直接調用self.whitenoise。

    此時,如果請求web服務獲取css、js等靜態資源,WhiteNoise會獲取其內容並返回給client,它在背後會匹配靜態資源在系統中對應的文件並將其讀取返回。

    至此,一開始的網頁效果就實現好了。

    web服務如果出現500時,默認會返回 internal server error ,這顯得比較丑,為了讓框架使用者可以自定義500時返回的錯誤,需要添加一些代碼。

    首先API初始化時,初始self.exception_handler對象並定義對應的方法添加自定義的錯誤

    在handler_request方法進行請求調度時,調度的方法執行邏輯時報500,此時不再默認將錯誤拋出,而是先判斷是否有自定義錯誤處理。

    在app.py中,自定義錯誤返回方法,如下。

    custom_exception_handler方法只返回自定義的一段話,你完全可以替換成美觀的template。

    我們可以實驗性定義一個路由來看效果。

    Web服務的中間件也可以理解成鉤子,即在請求前可以對請求做一些處理或者返回Response前對Response做一下處理。

    為了支持中間件,在TopWebF目錄下創建middleware.py文件,在編寫代碼前,思考一下如何實現?

    回顧一下現在請求的調度邏輯。

    1.通過routes裝飾器關聯路由和方法 2.通過API.whitenoise處理 3.如果是請求API介面,那麼會將參數傳遞給API.wsgi_app 4.API.wsgi_app最終會調用API.handle_request方法獲取路由對應的方法並調用該方法執行相應的邏輯

    如果希望在request前以及response後做相應的操作,那麼其實就需要讓邏輯在API.handle_request前後執行,看一下代碼。

    其中add方法會實例化Middleware對象,該對象會將當前的API類實例包裹起來。

    Middleware.handle_request方法其實就是在self.app.handle_request前調用self.process_request方法處理request前的數據以及調用self.process_response處理response後的數據,而核心的調度邏輯,依舊交由API.handle_request方法進行處理。

    這里的代碼可能會讓人感到疑惑, __call__ 方法和handle_request方法中都有self.app.handle_request(request),但其調用對象似乎不同?這個問題暫時放一下,先繼續完善代碼,然後再回來解釋。

    接著在api.py中為API創建middleware屬性以及添加新中間件的方法。

    隨後,在app.py中,自定義一個簡單的中間件,然後調用add_middleware方法將其添加。

    定義好中間件後,在請求調度時,就需要使用中間件,為了兼容靜態文件的情況,需要對css、js、ing文件的請求路徑做一下兼容,在其路徑中加上/static前綴

    緊接著,修改API的 __call__ ,兼容中間件和靜態文件,代碼如下。

    至此,中間件的邏輯就完成了。

    但代碼中依舊有疑惑,Middleware類中的 __call__ 方法和handle_request方法其調用的self.app到底是誰?

    為了方便理解,這里一步步拆解。

    如果沒有添加新的中間件,那麼請求的調度邏輯如下。

    在沒有添加中間件的情況下,self.app其實就是API本身,所以 middleware.__call__ 中的self.app.handle_request就是調用API.handle_request。

    如果添加了新的中間件,如上述代碼中添加了名為SimpleCustomMiddleware的中間件,此時的請求調度邏輯如下。

    因為注冊中間件時,Middleware.add方法替換了原始Middleware實例中的app對象,將其替換成了SimpleCustomMiddleware,而SimpleCustomMiddleware也有app對象,SimpleCustomMiddleware中的app對象,才是API類實例。

    在請求調度的過程中,就會觸發Middleware類的handle_request方法,該方法就會執行中間件相應的邏輯去處理request和response中的數據。

    當然,你可以通過Middleware.add方法添加多個中間件,這就會構成棧式調用的效果,代碼如下。

    啟動web服務後,其執行效果如下。