第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
3.3 Content-Type 頭

Spring Security 默認包含了 Content-Type 頭。如果需要禁用它,可以通過如下方式:@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) { http.headers(headers -> headers.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())); }}

3.1 布局文件編寫

首先修改布局文件,將 ListView 替換成 GridView 并添加一些 GridView 特有的屬性,如下:<?xml version="1.0" encoding="utf-8"?><GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="match_parent" android:layout_height="match_parent" android:columnWidth="110dp" android:numColumns="auto_fit" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" android:stretchMode="columnWidth" android:gravity="center" />

1.1 常用指令

在官方文檔地址中有關(guān)于 Nginx 的所有模塊,打開模塊我們就能看到模塊中支持的指令。最常用的指令,如 http、server、listen 等都在 ngx_http_core_modul 模塊中,這個是 Nginx 的核心模塊。

2. 部署java后臺服務(wù)

Nginx 部署 Java Web 服務(wù)時,主要用到是 Nginx 的代理轉(zhuǎn)發(fā)功能,對于不同類型的接口而言,可能會有不同的轉(zhuǎn)發(fā)邏輯。如果是使用 spring cloud 這樣的微服務(wù)框架,每個服務(wù)可能會部署多個會這分開部署在不同機器,在 Nginx 同樣只需要使用 proxy_pass 指令將 http 請求轉(zhuǎn)發(fā)到對應(yīng)的上游服務(wù)上即可,同時負載均衡模塊也在 java web 后臺服務(wù)中用到的比較多。最后是在java web 的開發(fā)中,也常常會涉及到 websocket 協(xié)議,因此 Nginx 在部署 java web 服務(wù)時也會用到 websocket 代理轉(zhuǎn)發(fā)。所以 Nginx 在部署 Java Web 服務(wù)時的基本配置大概如下:...http{ server { # 監(jiān)聽8080端口 listen 8080; # 指定域名,不指定也可以 server_name www.xxx.com; # 參數(shù)調(diào)優(yōu) client_max_body_size 20m; client_body_buffer_size 128k ... # 如果使用多個后臺服務(wù),可以配置負載均衡 ... # 訪前端的 vue 頁面 location / { ... } # vue 頁面中向后臺 java 服務(wù)發(fā)送請求 location /xxxx { proxy_pass http://xxxx:xx/xxx; } # 配置多種方向代理,不同類型接口有不同的轉(zhuǎn)發(fā)方式 ... # 如果有,則配置websocket代理 location /xxxy { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://xxxxx:xx/yyy; } } }...如果涉及的服務(wù)較多, Nginx 的配置往往會拆成多個文件進行編寫,這樣就用到了前面提到的 include 指令。

3.4 調(diào)用 redirect 函數(shù)

實現(xiàn)重定向功能,它的常用形式如下:from django.shortcuts import redirect# 指定完整的網(wǎng)址def redirect_view1(request): # 忽略其他 return redirect("http://www.baidu.com")# 指定內(nèi)部path路徑def redirect_view2(request): # 忽略其他 return redirect("/index/")def redirect_view3(request): # 忽略其他 return redirect(reverse('blog:article_list'))def redirect_view4(request): # 忽略其他 return redirect('some-view-name', foo='bar')

4. 小結(jié)

本小節(jié)主要學習了 URI 的概念,并且區(qū)分出了大家容易誤解的 URI 和 URL 的區(qū)別。在新版的 Http/2.0 文檔中已經(jīng)將 URL 修改成了 URI,可能也是怕大家混淆,不過在詳細地了解清楚后,改不改問題都不大了。

3. 模板方式

Spring MVC 提供有一種所謂的模板方法,和前面的以查詢字符串方法進行附加沒有多大區(qū)別。如下面的代碼,數(shù)據(jù)模型中的 data 對應(yīng)數(shù)據(jù)會以 URL 變量方式傳遞。數(shù)據(jù)模型中其它數(shù)據(jù)則以查詢字符串方式進行傳遞。@RequestMapping("/response04") public String response04(ModelMap model) throws IOException { // 發(fā)送給客戶端的響應(yīng)數(shù)據(jù) String hello = "Hello"; model.addAttribute("data", hello); model.addAttribute("id", 1); return "redirect:/test/{data}"; } ? @RequestMapping("/test/{data}") public String response05(@PathVariable("data") String data,@RequestParam("id") int id) throws IOException { System.out.println(data); System.out.println(id); return null; }當在瀏覽器中請求 http://localhost:8888/sm-demo/response04 后,瀏覽器的地址欄中會變成 :http://localhost:8888/sm-demo/test/Hello?id=1。模板方式其本質(zhì)和查詢字符串沒有太多區(qū)別。

2.2 請求流程

瀏覽器發(fā)起請求;Tomcat 響應(yīng)請求,然后封裝成統(tǒng)一的對象交給 Engine 處理。圖片顯示的是 Http 協(xié)議的處理,但是 Tomcat 的設(shè)計并不只是為了 Http 這個協(xié)議,還可以有其它的如 Ajp 協(xié)議。從 Engine 的角度它對這些處理是透明的(可以不關(guān)心的);Engine 將請求分配給一臺Host機器去處理;一臺機器上面可能同時部署了多個 Java Web 應(yīng)用,這時候通過 Context 這個上下文可以定位到具體的哪個 Web 應(yīng)用;交給應(yīng)用中具體的某個 Servlet 處理;原路一個個返回,將處理的響應(yīng)結(jié)果傳輸給瀏覽器。

5.1 配置

首先在 MyBatis 的全局配置文件中添加如下配置:<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <databaseIdProvider type="DB_VENDOR" /></configuration>在 configuration 中加入 databaseIdProvider 后,還需要在 databaseIdProvider 標簽中添加上需要使用到的數(shù)據(jù)庫名稱,如:SQL Server。每一個 property 屬性都代表了一個數(shù)據(jù)庫,name 表示數(shù)據(jù)庫廠商名稱,value 用來設(shè)置別名。<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <databaseIdProvider type="DB_VENDOR"> <property name="SQL Server" value="sqlserver"/> <property name="MySQL" value="mysql"/> <property name="PostgreSQL" value="postgre"/> </databaseIdProvider></configuration>

2. 預(yù)先認證概述

預(yù)先認證的使用場景如:已使用x.509 認證、J2EE 容器等方式通過認證。預(yù)認證有兩個主要步驟:識別發(fā)起請求的用戶身份;為該用戶返回權(quán)限。具體的運行機制與外部認證環(huán)境有關(guān)。當使用 x.509 證書認證時,用戶的識別信息從證書中獲取并添加在 Http 請求頭中。如果是 J2EE 容器認證,用戶的身份信息通過 Http 請求對象的 getUserPrincipal() 方法獲得。有時,外部認證系統(tǒng)可以提供用戶的身份信息、權(quán)限信息,但有時,權(quán)限信息要從其他數(shù)據(jù)源中獲取,例如通過 UserDetailsService。

3.1 將異常映射成狀態(tài)碼

Spring MVC 內(nèi)部提供了很多優(yōu)雅的異常處理機制。其中之一就是把不同的異常映射成 HTTP 狀態(tài)碼。如下面實例:首先定義一個異常類:@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "數(shù)字范圍不符合要求?。ú荒苁?20)")public class NumberException extends RuntimeException { }如果在方法中拋出的異常已經(jīng)被映射成了狀態(tài)嗎。則在瀏覽器中顯示出來的異常信息會明確很多。@RequestMapping("/exception")public String test(@RequestParam("num") int num) { if (num == 20) { throw new NumberException(); } return "success";}在瀏覽器中輸入 http://localhost:8888/sm-demo/exception?num=13 。可以看到:定制化的信息已經(jīng)有所改善,但是,還是不夠友好。

1.2 Django 中使用 Mixin

首先需要了解一下 Mixin 的概念,這里有一篇介紹 Python 中 Mixin 的文章:<<多重繼承>> ,可以認真看下,加深對 Mixin 的理解。在我的理解中,Mixin 其實就是單獨的一塊功能類。假設(shè) Django 中提供了 A、B、C 三個視圖類,又有 X、Y、Z三個 Mixin 類。如果我們想要視圖 A,同時需要額外的 X、Y功能,那么使用 Python 中的多重繼承即可達到目的:class NewView(A, X, Y): """ 定義新的視圖 """ pass我們來看看 Django 的官方文檔是如何引出 Mixin 的:Django’s built-in class-based views provide a lot of functionality, but some of it you may want to use separately. For instance, you may want to write a view that renders a template to make the HTTP response, but you can’t use TemplateView;perhaps you need to render a template only on POST, with GET doing something else entirely. While you could use TemplateResponse directly, this will likely result in duplicate code.For this reason, Django also provides a number of mixins that provide more discrete functionality. Template rendering, for instance, is encapsulated in the TemplateResponseMixin.翻譯過來就是: Django 內(nèi)置的類視圖提供了許多功能,但是我們可能只需要其中的一部分功能。例如我想寫一個視圖,該視圖使用由模板文件渲染后的 HTML 來響應(yīng)客戶端的 HTTP 請求,但是我們又不能使用 TemplateView 來實現(xiàn),因為我只想在 POST 請求上使用這個模板渲染的功能,而在 GET 請求時做其他事情。當然,可以直接使用 TemplateResponse 來完成,這樣就會導(dǎo)致代碼重復(fù)。基于這個原因, Django 內(nèi)部提供了許多離散功能的 mixins??梢钥吹?,這里的 mixins 就是一些單獨功能的類,配合視圖類一起使用,用于組合出各種功能的視圖。接下來,我們結(jié)合前面的 Member 表來使用下 mixin 功能。具體的步驟如下:改造原來的視圖類-TestView。我們給原來的視圖類多繼承一個 mixin,用于實現(xiàn)單個對象查找查找功能;from django.shortcuts import renderfrom django.http import HttpResponsefrom django.views.decorators.csrf import csrf_exemptfrom django.views.generic import Viewfrom django.views.generic.detail import SingleObjectMixinfrom .models import Member# Create your views here.class TestView(SingleObjectMixin, View): model = Member def get(self, request, *args, **kwargs): return HttpResponse('hello, get\n') def post(self, request, *args, **kwargs): self.object = self.get_object() return HttpResponse('hello, {}\n'.format(self.object.name)) def put(self, request, *args, **kwargs): return HttpResponse('hello, put\n') def delete(self, request, *args, **kwargs): return HttpResponse('hello, delete\n') @csrf_exempt def dispatch(self, request, *args, **kwargs): return super(TestView, self).dispatch(request, *args, **kwargs)修改 URLConf 配置,傳遞一個動態(tài)參數(shù),用于查找表中記錄:urlpatterns = [ path('test-cbv/<int:pk>/', views.TestView.as_view(), name="test-cbv")]啟動服務(wù)器,然后進行測試:[root@server first_django_app]# curl -XPOST http://127.0.0.1:8888/hello/test-cbv/2/hello, 會員2[root@server first_django_app]# curl -XPOST http://127.0.0.1:8888/hello/test-cbv/4/hello, spyinx-0[root@server first_django_app]# curl -XPOST http://127.0.0.1:8888/hello/test-cbv/9/hello, spyinx-5[root@server first_django_app]# curl -XGET http://127.0.0.1:8888/hello/test-cbv/9/hello, get[root@server first_django_app]# curl -XPUT http://127.0.0.1:8888/hello/test-cbv/9/hello, put[root@server first_django_app]# curl -XDELETE http://127.0.0.1:8888/hello/test-cbv/9/hello, delete可以看到在 POST 請求中,我們通過傳遞主鍵值,就能返回 Member 表中對應(yīng)記錄中的 name 字段值,這一功能正是由SingleObjectMixin 中的 get_object() 方法提供的。通過繼承這個查詢功能,我們就不用再使用 ORM 模型進行查找了,這簡化了我們的代碼。當然,這只能滿足一小部分的場景,對于更多復(fù)雜的場景,我們還是需要實現(xiàn)自己的邏輯,我們也可以把復(fù)雜的功能拆成各種 mixin,然后相關(guān)組合繼承,這樣可以很好的復(fù)用代碼,這是一種良好的編碼方式。

2. 一個最小的 Flask 應(yīng)用

確定安裝成功后我們創(chuàng)建一個 minimal.py 文件,并寫入下面的代碼:from flask import Flaskapp = Flask(__name__)首先,導(dǎo)入類 flask.Flask,實例化創(chuàng)建一個 Flask 應(yīng)用,第一個參數(shù)是 Flask 應(yīng)用的名稱。__name__ 是一個標識 Python 模塊的名字的變量:如果當前模塊是主模塊,那么此模塊名字就是 __main__;如果當前模塊是被 import 的,則此模塊名字為文件名。@app.route('/')def hello_world(): return '<b>Hello World</b>'然后,定義函數(shù) hello_world,它返回一段 html 文本。app.route(’/’) 返回一個裝飾器,裝飾器來為函數(shù) hello_world 綁定對應(yīng)的 URL,當用戶在瀏覽器訪問這個 URL 的時候,就會觸發(fā)這個函數(shù),獲取返回值。if __name__ == '__main__': app.run()如果當前模塊是主模塊,則變量 __name__ 為 '__main__,此時調(diào)用 run() 方法啟動 Flask 應(yīng)用。運行該程序,在瀏覽器中輸入 localhost:5000,瀏覽器顯示如下:在控制臺中,F(xiàn)lask 應(yīng)用輸出如下:$ python3 hello.py * Serving Flask app "hello" (lazy loading) * Environment: production Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)127.0.0.1 - - [20/Jul/2020 08:26:47] "GET / HTTP/1.1" 200 -127.0.0.1 - - [20/Jul/2020 08:26:47] "GET /favicon.ico HTTP/1.1" 404 -這樣,我們就已經(jīng)搭建好了一個最簡單的 Flask 應(yīng)用。

3.3 爬蟲相關(guān)的庫和框架

實現(xiàn) HTTP 請求操作urllib:提供操作 URL 的功能requests:基于 urllib 的 HTTP 請求庫,發(fā)出一個 HTTP 請求,等待服務(wù)器響應(yīng)的網(wǎng)頁selenium:自動化測試工具,通過這個庫調(diào)用瀏覽器完成某些操作,比如輸入驗證碼從網(wǎng)頁中提取信息beautifulsoup:對 html 和 XML 進行解析,從網(wǎng)頁中提取信息pyquery:jQuery 的 Python 實現(xiàn),能夠以 jQuery 的語法來操作解析 HTML 文檔lxml:對 html 和 XML 進行解析,支持 XPath 解析方式tesserocr:一個 OCR 庫,在遇到驗證碼的時候,可使用該庫進行識別爬蟲框架Scrapy:Scrapy 是用 python 實現(xiàn)的一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。用這個框架可以輕松爬下來如亞馬遜商品信息之類的數(shù)據(jù)PySpider: pyspider 是用 python 實現(xiàn)的功能強大的網(wǎng)絡(luò)爬蟲系統(tǒng),能在瀏覽器界面上進行腳本的編寫和爬取結(jié)果的實時查看,后端使用常用的數(shù)據(jù)庫進行爬取結(jié)果的存儲,還能定時設(shè)置任務(wù)與任務(wù)優(yōu)先級等Newpaper: Newspaper可以用來提取新聞、文章和內(nèi)容分析

4.4 protocols() 和 hidden() 屬性

定義:protocols() 屬性就是對接口類中,所有的接口所使用的網(wǎng)絡(luò)協(xié)議進行一個約定,常用的網(wǎng)絡(luò)協(xié)議有:http、https。hidden() 屬性就是控制接口類在 Swagger 界面中的顯隱性。使用方法:protocols() 屬性默認值為空,但是 Swagger 在處理時,會默認獲取項目所采用的網(wǎng)絡(luò)協(xié)議,我們可以不用專門設(shè)置,如果一定要設(shè)置該屬性,則只允許設(shè)置http協(xié)議規(guī)定的屬性,不能隨意設(shè)置,http, https 這些都是被允許的。hidden() 屬性允許我們在 Swagger 生成的接口列表界面上,控制接口類是否需要顯示,默認值為 false,即接口類顯示,為true時則接口類不顯示,如下代碼段所示。@Api(hidden = true)public class UserController{ // do something...}代碼解釋:第1行,我們在 UserController 接口類的上方使用了 @Api 注解的 hidden 屬性來隱藏我們的用戶接口類。Tips :接口類的顯隱控制應(yīng)該根據(jù)特定安全策略和特定客戶需求來決定顯隱,不能無故隱藏接口,更不能頻繁的切換接口的顯隱。在實際工作中,如果需要隱藏接口類則需要和項目組報備情況,說明原因。

4.1 CORS

首先展開一下 CORS 的全稱:Cross-origin resource sharing意思是跨域資源共享,這是一個 W3C 標準,從字面意思來看不難理解,它允許瀏覽器向跨域的資源發(fā)送請求,并且獲得結(jié)果數(shù)據(jù)。4.1.1 CORS 原理跨域資源共享標準新增了一組 HTTP 首部的字段,使得我們能夠通過這些字段來跨域獲取到我們所需要的資源。而要實現(xiàn)這一功能,我們需要前后端的配合,只有當后端實現(xiàn)了 CORS 功能,我們才能夠通過瀏覽器直接訪問資源。為此,我們先來看看接下來的幾個首部字段:Access-Control-Allow-Origin :表示服務(wù)端允許的請求源的域,如果是 * 表示允許所有域訪問,一般我們不建議使用 *;Access-Control-Allow-Headers: 表示預(yù)檢測中,列出了將會在正式請求的 Access-Control-Request-Headers 字段中出現(xiàn)的首部信息;Access-Control-Allow-Methods: 表示服務(wù)端允許的請求方法;Access-Control-Allow-Credentials: 表示服務(wù)端是否允許發(fā)送cookie。當然前端也需要設(shè)置對應(yīng)的 xhr.withCredentials 來進行配合;Access-Control-Expose-Headers: 列出了可以作為響應(yīng)的一部分暴露在外的頭部信息。其中,我們更為重要的當屬 Access-Control-Allow-Origin 字段,因為這個字段直接關(guān)系到你是否能夠跨域訪問資源的權(quán)限了。通常情況下,為了解決跨域問題,后端同學會設(shè)置 Access-Control-Allow-Origin 指定為我們的請求源的域,而前端代碼基本無感。4.1.2 簡單請求和非簡單請求關(guān)于 CORS ,HTTP 請求上會有一些小小區(qū)別,最直觀的區(qū)別就是會不會觸發(fā)多一次 OPTIONS 預(yù)檢測請求。我們把一些不會觸發(fā)預(yù)檢測請求的請求,稱為簡單請求,而相反,會觸發(fā)預(yù)檢測的請求則是非簡單請求。而關(guān)于如何區(qū)分簡單請求和非簡單請求,這里我就不再累贅,有興趣的同學可以讀一下 HTTP 控制訪問 。在實際的工作過程中,使用到 CORS 來解決跨域限制是非常常見的,這里我們注意一下簡單請求和非簡單請求的直觀區(qū)別即可,并在以后的工作中留意一下,而不至于懵逼于為什么多了一次 OPTIONS 請求。4.1.3 具體例子4.1.3.1 服務(wù)端核心代碼// 全局設(shè)置請求過濾app.all('*',function (req, res, next) { res.header('Access-Control-Allow-Origin', 'http://localhost:8080'); // 設(shè)置 Access-Control-Allow-Origin res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With'); // 設(shè)置 Access-Control-Allow-Headers res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS'); // 設(shè)置 Access-Control-Allow-Methods next()});// 注冊一個簡單的路由router.get("/simple/get", function(req, res) { const {a} = req.query res.send(`參數(shù)值是${a}`)});后端要做的工作就是實現(xiàn) CORS 功能。正如上方代碼,我們規(guī)定了一系列 HTTP 請求頭首部字段,使得 http://localhost:8080 這個域的前端腳本擁有向服務(wù)端發(fā)起請求并取得資源的權(quán)限。4.1.3.2 前端核心代碼$.ajax({ url: 'http://localhost:8083/simple/get', method: 'GET', data : { a: 1 }}).done(data => { console.log(data)})4.1.3.3 效果可見,通過 CORS ,前端成功拿到了不同域的服務(wù)端的返回內(nèi)容。4.1.4 CORS 小結(jié)CORS 是一個 W3C 的標準。使用 CORS ,我們可以使用使用常規(guī)的方式來解決前后端跨域訪問的問題。并且,大多數(shù)的工作其實也是放在了服務(wù)端上,對于前端而言,基本上可以說是無感的。當然, CORS 也是存在著一些弊端。正因為它是 W3C 中一個比較新的方案,導(dǎo)致了各大瀏覽器引擎沒有對其做嚴格規(guī)格的實現(xiàn),由此可能產(chǎn)生一些不一致的情況。

2. 編寫路由

服務(wù)已經(jīng)可以運行了,接下來就是要編寫能被外部訪問的路由接口,http 請求分為兩種,POST 請求和 GET 請求。我們首先想實現(xiàn)的是一個網(wǎng)站登錄頁面打開的路由 /index,需要編寫一個能響應(yīng) GET 請求的路由。代碼示例:package mainimport ( "net/http")func main() { //設(shè)置訪問的路由 http.HandleFunc("/index", func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { w.Write([]byte("<h1>Hello Codey!<h1>")) } }) http.ListenAndServe("127.0.0.1:9300", nil) //設(shè)置監(jiān)聽的端口}在瀏覽器中輸入127.0.0.1:9300/index:此處可以結(jié)合函數(shù)式編程的思想,將 index 的處理函數(shù)拿出來作為一個變量,代碼修改后如下所示package mainimport ( "net/http")func main() { http.HandleFunc("/index", index) //設(shè)置訪問的路由 http.ListenAndServe("127.0.0.1:9300", nil) //設(shè)置監(jiān)聽的端口}func index(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { w.Write([]byte("<h1>Hello Codey!<h1>")) }} 然后修改一下輸出字符串,使其輸出一個頁面,代碼修改后如下package mainimport ( "net/http")func main() { http.HandleFunc("/index", index) //設(shè)置訪問的路由 http.ListenAndServe("127.0.0.1:9300", nil) //設(shè)置監(jiān)聽的端口}func index(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { w.Write([]byte(`<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Go語言實戰(zhàn)1</title> </head> <body> <div> <h3>登錄</h3> <form> <div> <div> <input type="text" id="username" name="username" placeholder="請輸入賬號"> </div> </div> <div> <div> <input type="password" class="form-control" id="password" name="password" placeholder="請輸入密碼"> </div> </div> <div > <div > <button id="loginbtn" type="button" >登錄</button> </div> </div> </form> </div> </body> </html>`)) }}運行上述代碼,然后再次在瀏覽器中輸入127.0.0.1:9300/index。

5. 小結(jié)

本節(jié)主要是了解了 Netty 如何開發(fā)一個 Web 服務(wù)器,并且和瀏覽器進行通信,需要注意的地方有幾點,具體如下:格式要求,無論是解碼和編碼都需要嚴格按照 Http 協(xié)議格式要求,否則給瀏覽器響應(yīng)數(shù)據(jù)時,瀏覽器不能識別;可以跟進 Http 格式,獲取和設(shè)置相關(guān)信息,比如:請求 IP 地址、請求 uri 地址、請求方式、請求頭內(nèi)容、請求體內(nèi)容等;響應(yīng)頭、響應(yīng)體等;靜態(tài)資源的過濾,一般情況下需要過濾掉,否則消耗服務(wù)器資源。

1.1 作者

Restful 是由 Roy Thomas Fielding 博士在 2000 年所著的博士論文提起的,系統(tǒng)全面地闡述了 REST 的架構(gòu)風格和設(shè)計思想,這位作者同時是 HTTP、URI等 Web 架構(gòu)標準的主要設(shè)計者,因此他提出的 REST 概念得到很多人的關(guān)注和響應(yīng)。

4.1 引入相關(guān)模塊

#!/usr/bin/python3from flask import Flask, request, Response, render_templateapp = Flask(__name__)從 flask 模塊中引入 request 對象,request.cookies 存儲了客戶端發(fā)送的 Cookie。從 flask 模塊中引入 Response 類,頁面處理函數(shù)返回 Response 對象,而不是字符串。Response 對象提供了 set_cookie 和 delete_cookie 等方法用于設(shè)置 Cookie 相關(guān)的 HTTP 消息頭。

1. 前言

Spring MVC 為了解決 HTTP 協(xié)議的無狀態(tài)性,提供了很多能適用于不同作用域需求的模型對象,從而保證程序中的數(shù)據(jù)能在開發(fā)者需要的地方出現(xiàn)。本節(jié)課繼續(xù)和大家聊聊 Spring MVC 中的數(shù)據(jù)模型組件。Model;ModelMap;ModelAndView。

6. 藍圖 <a href="http://todos.py">todos.py</a>

藍圖 todos 包含有 3 個頁面:/todos/add、/todos/update、/todos/delete,代碼由如下部分構(gòu)成:

2.2 Numpy <a href="http://www.numpy.org">官網(wǎng)</a>

Numpy(Numerical Python)是一個開源的Python科學計算庫,用于快速處理任意維度的數(shù)組。Numpy支持常見的數(shù)組和矩陣操作。Numpy 使用 ndarray 對象來處理多維數(shù)組,該對象是一個快速而靈活的大數(shù)據(jù)容器。使用 Python 列表可以存儲一維數(shù)組,通過列表的嵌套可以實現(xiàn)多維數(shù)組,那么為什么還需要使用Numpy 的 ndarray呢?這是因為對于同樣的數(shù)值計算任務(wù),ndarray的計算速度比直接使用Python快很多,節(jié)約了時間。機器學習的最大特點就是大量的數(shù)據(jù)運算,效率高是一個主要要求。簡單說一下 ndarray 為什么快?ndarray 在存儲數(shù)據(jù)的時候,數(shù)據(jù)與數(shù)據(jù)的地址都是連續(xù)的,這樣就給使得批量操作數(shù)組元素時速度更快。這是因為ndarray中的所有元素的類型都是相同的,而 Python 列表中的元素類型是任意的,所以ndarray 在存儲元素時內(nèi)存可以連續(xù),而 python 原生 lis 就只能通過尋址方式找到下一個元素;ndarray支持并行化運算;Numpy 底層使用 C 語言編寫,內(nèi)部解除了GIL(全局解釋器鎖),其對數(shù)組的操作速度不受 Python解釋器的限制 ,所以,其效率遠高于純 Python 代碼。關(guān)于 numpy 使用,請參考

2. 常用的鉤子

Flask 框架中常用的鉤子總結(jié)如下:1. before_first_request在應(yīng)用程序?qū)嵗牡谝粋€請求之前要運行的函數(shù),只會運行一次。2. before_request在每個請求之前要運行的函數(shù),對每一次請求都會執(zhí)行一次。3. after_request在每個請求之后要運行的函數(shù),對每一次請求都會執(zhí)行一次。在 after_request 注冊的鉤子函數(shù)的第一個參數(shù)是 response 對象。4. teardown_request在每個請求之后要運行的函數(shù),對每一次請求都會執(zhí)行一次。在 teardown_request 注冊的鉤子函數(shù)的第一個參數(shù)是 exception 對象,指向執(zhí)行請求時發(fā)生的錯誤。5. errorhandler發(fā)生一些異常時,比如 HTTP 404、HTTP 500 錯誤,或者拋出異常,就會自動調(diào)用該鉤子函數(shù)。

3.3. 靜態(tài)資源

如果瀏覽器中請求的是一個靜態(tài)資源(瀏覽器能解釋的資源,如 Html、Css、Js、圖片……),有必要經(jīng)過前端控制器嗎?當然不需要。但是,你可以試著在 WEB 項目的 根目錄下創(chuàng)建名為 static.html 的靜態(tài)資源,然后在瀏覽器直接請求一下(http://localhost:8888/sm-demo/static.html)。會發(fā)現(xiàn)請求不到,那是因為你的請求還是經(jīng)過了前端控制器。所以,咱們要告訴 Spring MVC 靜態(tài)資源還是交回給 Servlet 容器處理吧, 就不勞您大駕了。打開 WebConfig 配置類,讓其實現(xiàn) WebMvcConfigurer 接口;public class WebConfig implements WebMvcConfigurer{ }重寫 configureDefaultServletHandling() 方法,啟動 Servlet 的 default Servlet 來處理靜態(tài)資源;public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable();}再次請求 http://localhost:8888/sm-demo/static.html ,你應(yīng)該能看到靜態(tài)頁面的內(nèi)容。

5. 小結(jié)

本文主要介紹了 Go 語言官方提供的 http 服務(wù),以及如何使用這個包來搭建一個 web 應(yīng)用。其中需要注意區(qū)分前端發(fā)送過來的請求類型,POST 和 GET 兩個請求各自有各自的處理。

2.1 案例1

準備好靜態(tài)資源文件,我們就在 /root/test/ 下新建一個 index.html,并新建目錄 web,同時繼續(xù)在 web 目錄下分別新建 web1.html 和 web2.html 文件,具體的目錄結(jié)構(gòu)如下所示:[root@server ~]# cd /root/test[root@server test]# tree ..├── index.html└── web ├── web1.html └── web2.html1 directory, 3 filesNginx 的配置如下:user root;worker_processes 2;#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 8080; # 靜態(tài)資源根理解 root /root/test; # 打開目錄瀏覽功能 autoindex on; # 指定網(wǎng)站初始頁,找index.html或者index.htm頁面 index index.html index.htm; } server { listen 8081; location /web { root /root/test/; } } server { listen 8082; location /web { alias /root/test/; } }}測試結(jié)果對于監(jiān)聽的 8080 端口,我們直接使用 root 指令,指定資源的根路徑。這樣子,當我們在瀏覽器上直接訪問 http:// 服務(wù)器的 ip:8080/web/web1.html 或者 http://服務(wù)器ip:8080/web/web2.html 時,就能訪問對應(yīng)的 web1.html 和 web2.html 頁面;若沒有指定靜態(tài)資源地址(即/路徑),默認會找由 index 指令指定的文件,即 index.html 或者 index.htm 文件;訪問 8080 的/地址訪問web1.html文件訪問web2.html文件對于監(jiān)聽的 8081 端口,我們直接使用 root 指令,指定資源的根路徑。當請求 http://服務(wù)器ip:8081/web/xxxx 地址時,等價于訪問服務(wù)器上的靜態(tài)資源文件 /root/test/[匹配到的web]/xxxx,也即/root/test/web/xxxx,訪問 web2.html 類似;通過 8081 端口訪問 web1.html 資源通過 8081 端口訪問靜態(tài)資源 web2.html對于監(jiān)聽的 8082 端口,我們使用的是 alias 指令,指定資源路徑的別名,它與 root 指令略有不同。當請求 http://服務(wù)器ip:8082/web/xxxx 地址時,等價于訪問服務(wù)器上的靜態(tài)資源文件 /root/test/xxxx,并不會將匹配到的web添加到靜態(tài)資源的路徑上,所有為了能訪問到 web1.html,我們需要使用如下的url:http://服務(wù)器ip:8082/web/web/web1.html, 訪問 web2.html 類似。結(jié)果如下:通過alias指令訪問web1.html通過alias指令訪問web2.html

1.5 無連接

連接是又控制層控制的,無連接并不是指 HTTP 不需要控制層的連接,而是指每次連接指處理一次請求,請求結(jié)束,即端口連接。這樣設(shè)計的目的,是減少開銷,提高效率。因為,TCP 控制層的連接會消耗大量的系統(tǒng)資源。

5. 藍圖 <a href="http://users.py">users.py</a>

藍圖 users 包含有 3 個頁面:/users/login、/users/register、/users/logout,代碼由如下部分構(gòu)成:

直播
查看課程詳情
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號