濮阳杆衣贸易有限公司

主頁 > 知識(shí)庫 > Laravel如何實(shí)現(xiàn)適合Api的異常處理響應(yīng)格式

Laravel如何實(shí)現(xiàn)適合Api的異常處理響應(yīng)格式

熱門標(biāo)簽:臨沂crm外呼系統(tǒng)平臺(tái) 如何在世界地圖標(biāo)注 梧州市機(jī)器人外呼系統(tǒng)怎么樣 廈門400電話辦理選易號(hào)網(wǎng) 地圖標(biāo)注符號(hào)樣式有 天客通地圖標(biāo)注 電子地圖標(biāo)注怎么修改 菏澤語音外呼系統(tǒng)運(yùn)營(yíng)商 公司外呼系統(tǒng)中心

前言

Laravel全局捕獲異常后,會(huì)把異常轉(zhuǎn)為相應(yīng)的數(shù)據(jù)格式返回給用戶。如果想要規(guī)定的數(shù)據(jù)格式相應(yīng),那我們只需重寫異常捕獲后的處理方法即可。

異常處理流程

Illuminate\Foundation\Exception\Handler 中的 render 方法用來將異常轉(zhuǎn)化為響應(yīng)。

public function render($request, Exception $e)
{
 if (method_exists($e, 'render')  $response = $e->render($request)) {
 return Router::toResponse($request, $response);
 } elseif ($e instanceof Responsable) {
 return $e->toResponse($request);
 }

 $e = $this->prepareException($e);

 if ($e instanceof HttpResponseException) {
 return $e->getResponse();
 } elseif ($e instanceof AuthenticationException) {
 return $this->unauthenticated($request, $e);
 } elseif ($e instanceof ValidationException) {
 return $this->convertValidationExceptionToResponse($e, $request);
 }

 return $request->expectsJson()
   ? $this->prepareJsonResponse($request, $e)
   : $this->prepareResponse($request, $e);
}

render() 中又調(diào)用了 prepareException() 對(duì)部分異常進(jìn)行預(yù)處理,但并未執(zhí)行轉(zhuǎn)化為響應(yīng)的操作。

ModelNotFoundException 一般在模型查找不到拋出,prepareException() 中它被轉(zhuǎn)為 Symfony 包中NotFoundHttpException,默認(rèn)狀態(tài)碼404;

AuthorizationException 在 Policy 權(quán)限未通過時(shí)拋出,prepareException() 中它被轉(zhuǎn)為 Symfony 包中 AccessDeniedHttpException,默認(rèn)狀態(tài)碼403;

TokenMismatchException 在 CSRF 驗(yàn)證未通過時(shí)拋出,prepareException() 中它被轉(zhuǎn)為 Symfony 包中 HttpException,給定狀態(tài)碼419;

其他異常直接返回。

protected function prepareException(Exception $e)
{
 if ($e instanceof ModelNotFoundException) {
 $e = new NotFoundHttpException($e->getMessage(), $e);
 } elseif ($e instanceof AuthorizationException) {
 $e = new AccessDeniedHttpException($e->getMessage(), $e);
 } elseif ($e instanceof TokenMismatchException) {
 $e = new HttpException(419, $e->getMessage(), $e);
 }

 return $e;
}

在回到 render() ,預(yù)處理異常之后,又分別對(duì) HttpResponseException、AuthenticationException 和 ValidationException 單獨(dú)處理,并轉(zhuǎn)為響應(yīng)返回。

除此以外的異常,都在 prepareJsonResponse() 或 prepareResponse() 處理 ,expectsJson() 用來判斷返回 json 響應(yīng)還是普通響應(yīng)。

修改異常響應(yīng)格式

了解了異常處理流程,接下來就處理異常響應(yīng)格式。

修改登錄認(rèn)證異常格式

由上文可知,AuthenticationException 被捕獲后,調(diào)用 unauthenticated() 來處理。

protected function unauthenticated($request, AuthenticationException $exception)
{
 return $request->expectsJson()
    ? response()->json(['message' => $exception->getMessage()], 401)
    : redirect()->guest($exception->redirectTo() ?? route('login'));
}

在 appExceptionsHandler.php 中重寫 unauthenticated() 使其返回我們想要的數(shù)據(jù)格式。

protected function unauthenticated($request, AuthenticationException $exception)
{
 return $request->expectsJson()
  ? response()->json([
   'code' => 0,
   'data' => $exception->getMessage(),
  ], 401)
  : redirect()->guest($exception->redirectTo() ?? route('login'));
}

修改驗(yàn)證異常格式

同樣由上文可知,ValidationException 被捕獲后交由 convertValidationExceptionToResponse() 處理,進(jìn)入此方法后我們需要繼續(xù)追蹤,若是需要 json 響應(yīng),最終交由 invalidJson() 處理。

protected function convertValidationExceptionToResponse(ValidationException $e, $request)
{
 if ($e->response) {
  return $e->response;
 }

 return $request->expectsJson()
    ? $this->invalidJson($request, $e)
    : $this->invalid($request, $e);
}
protected function invalidJson($request, ValidationException $exception)
{
 return response()->json([
  'message' => $exception->getMessage(),
  'errors' => $exception->errors(),
 ], $exception->status);
}

我們繼續(xù)在 appExceptionsHandler.php 重寫 invalidJson() 即可自定義返回格式。

protected function invalidJson($request, ValidationException $exception)
{
 return response()->json([
  'code' => 0,
  'data' => $exception->errors(),
 ], $exception->status);
}

修改其他異常格式

其他異常是調(diào)用 prepareJsonResponse() 來處理,此方法又調(diào)用 convertExceptionToArray() 來處理響應(yīng)格式。

protected function prepareJsonResponse($request, Exception $e)
{
 return new JsonResponse(
  $this->convertExceptionToArray($e),
  $this->isHttpException($e) ? $e->getStatusCode() : 500,
  $this->isHttpException($e) ? $e->getHeaders() : [],
  JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
 );
}
protected function convertExceptionToArray(Exception $e)
{
 return config('app.debug') ? [
  'message' => $e->getMessage(),
  'exception' => get_class($e),
  'file' => $e->getFile(),
  'line' => $e->getLine(),
  'trace' => collect($e->getTrace())->map(function ($trace) {
   return Arr::except($trace, ['args']);
  })->all(),
 ] : [
  'message' => $this->isHttpException($e) ? $e->getMessage() : 'Server Error',
 ];
}

在 appExceptionsHandler.php 中重寫 convertExceptionToArray() 來自定義其他異常響應(yīng)格式。

protected function convertExceptionToArray(Exception $e)
{
 return config('app.debug') ? [
  'code' => 0,
  'data' => $e->getMessage(),
  'exception' => get_class($e),
  'file' => $e->getFile(),
  'line' => $e->getLine(),
  'trace' => collect($e->getTrace())->map(function ($trace) {
   return Arr::except($trace, ['args']);
  })->all(),
 ] : [
  'code' => 0,
  'data' => $this->isHttpException($e) ? $e->getMessage() : 'Server Error',
 ];
}

強(qiáng)制 json 響應(yīng)

代碼中多次出現(xiàn)了 expectsJson() ,此方法是用來判斷返回 json 響應(yīng)還是普通響應(yīng)。

public function expectsJson()
{
 return ($this->ajax()  ! $this->pjax()  $this->acceptsAnyContentType()) || $this->wantsJson();
}

以下兩種條件下,會(huì)返回json響應(yīng)。

非XML請(qǐng)求、非pjax并且 Headers 中 Accept 設(shè)置為接收所有格式響應(yīng);

Headers Accept 設(shè)置為 /json、+json。如:Accept:application/json。

除此之外的情況,將不會(huì)響應(yīng)json。我們可以利用中間件強(qiáng)制追加 Accept:application/json,使異常響應(yīng)時(shí)都返回json。(參考教程 L03 6.0 中提到的方法)

創(chuàng)建中間件 AcceptHeader

?php

namespace App\Http\Middleware;

use Closure;

class AcceptHeader
{
 public function handle($request, Closure $next)
 {
  $request->headers->set('Accept', 'application/json');

  return $next($request);
 }
}

在 app/Http/Kernel.php 中,將中間件加入路由組即可。

protected $middlewareGroups = [
 'web' => [
  .
  .
  .
 'api' => [
  \App\Http\Middleware\AcceptHeader::class,
  'throttle:60,1',
  'bindings',
 ],
];

大功告成。

總結(jié)

到此這篇關(guān)于Laravel如何實(shí)現(xiàn)適合Api的異常處理響應(yīng)格式的文章就介紹到這了,更多相關(guān)Laravel適合Api的異常處理響應(yīng)格式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Laravel5.5+ 使用API Resources快速輸出自定義JSON方法詳解
  • laravel接管Dingo-api和默認(rèn)的錯(cuò)誤處理方式
  • 在Laravel中使用GuzzleHttp調(diào)用第三方服務(wù)的API接口代碼
  • Laravel實(shí)現(xiàn)ApiToken認(rèn)證請(qǐng)求
  • laravel框架 api自定義全局異常處理方法
  • laravel dingo API返回自定義錯(cuò)誤信息的實(shí)例
  • laravel 配置路由 api和web定義的路由的區(qū)別詳解
  • Laravel5.4簡(jiǎn)單實(shí)現(xiàn)app接口Api Token認(rèn)證方法
  • 詳解Laravel制作API接口

標(biāo)簽:白城 黃石 郴州 瀘州 迪慶 綿陽 貴陽 雞西

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Laravel如何實(shí)現(xiàn)適合Api的異常處理響應(yīng)格式》,本文關(guān)鍵詞  Laravel,如何,實(shí)現(xiàn),適合,Api,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Laravel如何實(shí)現(xiàn)適合Api的異常處理響應(yīng)格式》相關(guān)的同類信息!
  • 本頁收集關(guān)于Laravel如何實(shí)現(xiàn)適合Api的異常處理響應(yīng)格式的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    云和县| 台南市| 广灵县| 安徽省| 东海县| 南陵县| 黄山市| 定南县| 宁晋县| 德兴市| 方山县| 华宁县| 阜新| 宜都市| 寻甸| 泾源县| 漳平市| 怀集县| 凤山县| 砚山县| 库伦旗| 容城县| 惠东县| 肥城市| 长乐市| 当涂县| 龙海市| 托克逊县| 青海省| 兴安盟| 英吉沙县| 临城县| 龙川县| 全椒县| 蚌埠市| 吴旗县| 商河县| 崇信县| 黎城县| 株洲县| 额敏县|