項(xiàng)目響應(yīng)參照http定義的響應(yīng)碼,成功條件下直接返回請求內(nèi)容.無內(nèi)容返回204.所有失敗直接拋出異常,系統(tǒng)在使用統(tǒng)一的異常處理,對于json請求返回json,非json返回對應(yīng)的錯(cuò)誤頁面.
在項(xiàng)目中,發(fā)生的任何需要返回非200開頭的響應(yīng)的時(shí)候,均直接拋出一個(gè)http異常.項(xiàng)目中有統(tǒng)一的異常處理中心,異常處理中心作統(tǒng)一化處理,比如最基本的,json請求響應(yīng)json,非json請求響應(yīng)頁面.需要根據(jù)自己的業(yè)務(wù)定制各種異常,比如資源類錯(cuò)誤ResourceException(繼承自HttpException).然后StoreResourceFailedException繼承自ResourceException.設(shè)計(jì)各種異常,在業(yè)務(wù)代碼中需要返回錯(cuò)誤的時(shí)候,直接throw一個(gè)異常就好了,十分方便清晰.
響應(yīng)
響應(yīng)使用json,遵照http標(biāo)準(zhǔn).
成功
200(包括其他200開頭的響應(yīng)碼)時(shí)直接返回請求結(jié)果;
204,表示無內(nèi)容的成功響應(yīng),會執(zhí)行success回調(diào),但是沒有data數(shù)據(jù).
失敗
發(fā)生錯(cuò)誤全部使用http異常響應(yīng).
錯(cuò)誤信息包含在響應(yīng)體中的error字段中.
(如ajax請求獲取:XMLHttpRequest.responseJSON.error).
關(guān)于 422 響應(yīng)碼
對于422驗(yàn)證失敗的錯(cuò)誤,在一些情況下響應(yīng)體中是不返回error字段的.
響應(yīng)返回的是key-value形式的鍵值對,key表示錯(cuò)誤字段,value表示錯(cuò)誤原因.比如返回:"["name"=>"名稱 不能為空","mobile"=>"手機(jī)號 不能為空"]"
例子
在ajax請求中的error中處理錯(cuò)誤:
error: function (XMLHttpRequest, textStatus, errorThrown) {
var msg="";
if(XMLHttpRequest.status == 401){
//未授權(quán),刨除編碼錯(cuò)誤導(dǎo)致的401.
//對于微信端可能是token失效,需要通過授權(quán)中心重新獲得token
}
if (XMLHttpRequest.responseJSON && XMLHttpRequest.responseJSON.error) {
//后臺有專門返回的錯(cuò)誤信息的情況
msg += XMLHttpRequest.responseJSON.error;
} else {
//如果沒有響應(yīng)中沒有error
if (XMLHttpRequest.status == 422) {
//422 響應(yīng)可能返回?cái)?shù)組形式錯(cuò)誤信息.如:["name"=>"名稱 不能為空","mobile"=>"手機(jī)號 不能為空"]
var erroMsg = JSON.parse(XMLHttpRequest.responseText);
$.each(erroMsg, function (k, v) {
msg += v[0] + "\\n";
});
} else {
//其他
msg += XMLHttpRequest.statusText + ":" + XMLHttpRequest.status;
}
}
//拿著msg做出提示
}
詳細(xì)介紹
響應(yīng)碼由三位十進(jìn)制數(shù)字組成,它們出現(xiàn)在由HTTP服務(wù)器發(fā)送的響應(yīng)的第一行。
響應(yīng)碼分五種類型,由它們的第一位數(shù)字表示:
1xx:信息,請求收到,繼續(xù)處理
2xx:成功,行為被成功地接受、理解和采納
3xx:重定向,為了完成請求,必須進(jìn)一步執(zhí)行的動(dòng)作
4xx:客戶端錯(cuò)誤,請求包含語法錯(cuò)誤或者請求無法實(shí)現(xiàn)
5xx:服務(wù)器錯(cuò)誤,服務(wù)器不能實(shí)現(xiàn)一種明顯無效的請求
100 => 'Continue', //繼續(xù)
101 => 'Switching Protocols', //分組交換協(xié)議
102 => 'Processing', // RFC2518
200 => 'OK',
201 => 'Created', //被創(chuàng)建
202 => 'Accepted', //被采納
203 => 'Non-Authoritative Information', //非授權(quán)信息
204 => 'No Content', //無內(nèi)容
205 => 'Reset Content', //重置內(nèi)容
206 => 'Partial Content', //部分內(nèi)容
207 => 'Multi-Status', // RFC4918
208 => 'Already Reported', // RFC5842
226 => 'IM Used', // RFC3229
300 => 'Multiple Choices', //多選項(xiàng)
301 => 'Moved Permanently', //永久地傳送
302 => 'Found', //找到
303 => 'See Other', //參見其他
304 => 'Not Modified', //未改動(dòng)
305 => 'Use Proxy', //使用代理
307 => 'Temporary Redirect', //暫時(shí)重定向
308 => 'Permanent Redirect', // RFC7238
400 => 'Bad Request', //錯(cuò)誤請求
401 => 'Unauthorized', //未授權(quán)
402 => 'Payment Required', //要求付費(fèi)
403 => 'Forbidden', //禁止
404 => 'Not Found', //未找到
405 => 'Method Not Allowed', //不允許的方法
406 => 'Not Acceptable', //不被采納
407 => 'Proxy Authentication Required', //要求代理授權(quán)
408 => 'Request Timeout', //請求超時(shí)
409 => 'Conflict', //沖突
410 => 'Gone', //過期的
411 => 'Length Required', //要求的長度
412 => 'Precondition Failed', //前提不成立
413 => 'Payload Too Large', //請求實(shí)例太大
414 => 'URI Too Long', //請求URI太大
415 => 'Unsupported Media Type', //不支持的媒體類型
416 => 'Range Not Satisfiable', //無法滿足的請求范圍
417 => 'Expectation Failed', //失敗的預(yù)期
418 => 'I\'m a teapot', // RFC2324
421 => 'Misdirected Request', // RFC7540
422 => 'Unprocessable Entity', // RFC4918,資源錯(cuò)誤
423 => 'Locked', // RFC4918
424 => 'Failed Dependency', // RFC4918
425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
426 => 'Upgrade Required', // RFC2817
428 => 'Precondition Required', // RFC6585
429 => 'Too Many Requests', // RFC6585
431 => 'Request Header Fields Too Large', // RFC6585
451 => 'Unavailable For Legal Reasons', // RFC7725
500 => 'Internal Server Error', //內(nèi)部服務(wù)器錯(cuò)誤
501 => 'Not Implemented', //未被使用
502 => 'Bad Gateway', //網(wǎng)關(guān)錯(cuò)誤
503 => 'Service Unavailable', //不可用的服務(wù)/維護(hù)
504 => 'Gateway Timeout', //網(wǎng)關(guān)超時(shí)
505 => 'HTTP Version Not Supported', //HTTP版本未被支持
506 => 'Variant Also Negotiates (Experimental)', // RFC2295
507 => 'Insufficient Storage', // RFC4918
508 => 'Loop Detected', // RFC5842
510 => 'Not Extended', // RFC2774
511 => 'Network Authentication Required', // RFC6585
部分響應(yīng)碼詳細(xì)介紹
- 100 Continue 初始的請求已經(jīng)接受,客戶應(yīng)當(dāng)繼續(xù)發(fā)送請求的其余部分。(HTTP 1.1新)
- 101 Switching Protocols 服務(wù)器將遵從客戶的請求轉(zhuǎn)換到另外一種協(xié)議(HTTP 1.1新)
- 200 OK 一切正常,對GET和POST請求的應(yīng)答文檔跟在后面。
- 201 Created 服務(wù)器已經(jīng)創(chuàng)建了文檔,Location頭給出了它的URL。
- 202 Accepted 已經(jīng)接受請求,但處理尚未完成。
- 203 Non-Authoritative Information 文檔已經(jīng)正常地返回,但一些應(yīng)答頭可能不正確,因?yàn)槭褂玫氖俏臋n的拷貝(HTTP 1.1新)。
- 204 No Content 沒有新文檔,瀏覽器應(yīng)該繼續(xù)顯示原來的文檔。如果用戶定期地刷新頁面,而Servlet可以確定用戶文檔足夠新,這個(gè)狀態(tài)代碼是很有用的。
- 205 Reset Content 沒有新的內(nèi)容,但瀏覽器應(yīng)該重置它所顯示的內(nèi)容。用來強(qiáng)制瀏覽器清除表單輸入內(nèi)容(HTTP 1.1新)。
- 206 Partial Content 客戶發(fā)送了一個(gè)帶有Range頭的GET請求,服務(wù)器完成了它(HTTP 1.1新)。
- 300 Multiple Choices 客戶請求的文檔可以在多個(gè)位置找到,這些位置已經(jīng)在返回的文檔內(nèi)列出。如果服務(wù)器要提出優(yōu)先選擇,則應(yīng)該在Location應(yīng)答頭指明。
- 301 Moved Permanently 客戶請求的文檔在其他地方,新的URL在Location頭中給出,瀏覽器應(yīng)該自動(dòng)地訪問新的URL。
-
302 Found 類似于301,但新的URL應(yīng)該被視為臨時(shí)性的替代,而不是永久性的。
注意,在HTTP1.0中對應(yīng)的狀態(tài)信息是“Moved Temporatily”. 出現(xiàn)該狀態(tài)代碼時(shí),瀏覽器能夠自動(dòng)訪問新的URL,因此它是一個(gè)很有用的狀態(tài)代碼。 注意這個(gè)狀態(tài)代碼有時(shí)候可以和301替換使用。例如,如果瀏覽器錯(cuò)誤地請求http://host/~user(缺少了后面的斜杠),有的服務(wù)器返回301,有的則返回302。嚴(yán)格地說,我們只能假定只有當(dāng)原來的請求是GET時(shí)瀏覽器才會自動(dòng)重定向。請參見307。
- 303 See Other 類似于301/302,不同之處在于,如果原來的請求是POST,Location頭指定的重定向目標(biāo)文檔應(yīng)該通過GET提取(HTTP 1.1新)。
- 304 Not Modified 客戶端有緩沖的文檔并發(fā)出了一個(gè)條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務(wù)器告訴客戶,原來緩沖的文檔還可以繼續(xù)使用。
- 305 Use Proxy 客戶請求的文檔應(yīng)該通過Location頭所指明的代理服務(wù)器提取(HTTP 1.1新)。
-
307 Temporary Redirect 和302(Found)相同。
許多瀏覽器會錯(cuò)誤地響應(yīng)302應(yīng)答進(jìn)行重定向,即使原來的請求是POST,即使它實(shí)際上只能在POST請求的應(yīng)答是303時(shí) 才能重定向。由于這個(gè)原因,HTTP 1.1新增了307,以便更加清除地區(qū)分幾個(gè)狀態(tài)代碼:當(dāng)出現(xiàn)303應(yīng)答時(shí),瀏覽器可以跟隨重定向的GET和POST請求;如果是307應(yīng)答,則瀏覽器只 能跟隨對GET請求的重定向。(HTTP 1.1新)
- 400 Bad Request 請求出現(xiàn)語法錯(cuò)誤。
- 401 Unauthorized 客戶試圖未經(jīng)授權(quán)訪問受密碼保護(hù)的頁面。應(yīng)答中會包含一個(gè)WWW-Authenticate頭,瀏覽器據(jù)此顯示用戶名字/密碼對話框,然后在填寫合適的Authorization頭后再次發(fā)出請求。
- 403 Forbidden 資源不可用。服務(wù)器理解客戶的請求,但拒絕處理它。通常由于服務(wù)器上文件或目錄的權(quán)限設(shè)置導(dǎo)致。
- 404 Not Found 無法找到指定位置的資源。這也是一個(gè)常用的應(yīng)答。
- 405 Method Not Allowed 請求方法(GET、POST、HEAD、Delete、PUT、TRACE等)對指定的資源不適用。(HTTP 1.1新)
- 406 Not Acceptable 指定的資源已經(jīng)找到,但它的MIME類型和客戶在Accpet頭中所指定的不兼容(HTTP 1.1新)。
- 407 Proxy Authentication Required 類似于401,表示客戶必須先經(jīng)過代理服務(wù)器的授權(quán)。(HTTP 1.1新)
- 408 Request Timeout 在服務(wù)器許可的等待時(shí)間內(nèi),客戶一直沒有發(fā)出任何請求。客戶可以在以后重復(fù)同一請求。(HTTP 1.1新)
- 409 Conflict 通常和PUT請求有關(guān)。由于請求和資源的當(dāng)前狀態(tài)相沖突,因此請求不能成功。(HTTP 1.1新)
- 410 Gone 所請求的文檔已經(jīng)不再可用,而且服務(wù)器不知道應(yīng)該重定向到哪一個(gè)地址。它和404的不同在于,返回407表示文檔永久地離開了指定的位置,而404表示由于未知的原因文檔不可用。(HTTP 1.1新)
- 411 Length Required 服務(wù)器不能處理請求,除非客戶發(fā)送一個(gè)Content-Length頭。(HTTP 1.1新)
- 412 Precondition Failed 請求頭中指定的一些前提條件失敗(HTTP 1.1新)。
- 413 Request Entity Too Large 目標(biāo)文檔的大小超過服務(wù)器當(dāng)前愿意處理的大小。如果服務(wù)器認(rèn)為自己能夠稍后再處理該請求,則應(yīng)該提供一個(gè)Retry-After頭(HTTP 1.1新)。
- 414 Request URI Too Long URI太長(HTTP 1.1新)。
- 416 Requested Range Not Satisfiable 服務(wù)器不能滿足客戶在請求中指定的Range頭。(HTTP 1.1新)
- 500 Internal Server Error 服務(wù)器遇到了意料不到的情況,不能完成客戶的請求。
- 501 Not Implemented 服務(wù)器不支持實(shí)現(xiàn)請求所需要的功能。例如,客戶發(fā)出了一個(gè)服務(wù)器不支持的PUT請求。
- 502 Bad Gateway 服務(wù)器作為網(wǎng)關(guān)或者代理時(shí),為了完成請求訪問下一個(gè)服務(wù)器,但該服務(wù)器返回了非法的應(yīng)答。
- 503 Service Unavailable 服務(wù)器由于維護(hù)或者負(fù)載過重未能應(yīng)答。例如,Servlet可能在數(shù)據(jù)庫連接池已滿的情況下返回503。服務(wù)器返回503時(shí)可以提供一個(gè)Retry-After頭。
- 504 Gateway Timeout 由作為代理或網(wǎng)關(guān)的服務(wù)器使用,表示不能及時(shí)地從遠(yuǎn)程服務(wù)器獲得應(yīng)答。(HTTP 1.1新)
- 505 HTTP Version Not Supported 服務(wù)器不支持請求中所指明的HTTP版本。(HTTP 1.1新)