前言

Laravel全局捕获异常后,会把异常转为相应的数据格式返回给用户。如果想要规定的数据格式相应,那我们只需重写异常捕获后的处理方法即可。

异常处理流程

Illuminate\Foundation\Exception\Handler 中的 render 方法用来将异常转化为响应。

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() 中又调用了 prepareException() 对部分异常进行预处理,但并未执行转化为响应的操作。

ModelNotFoundException 一般在模型查找不到抛出,prepareException() 中它被转为 Symfony 包中NotFoundHttpException,默认状态码404;

AuthorizationException 在 Policy 权限未通过时抛出,prepareException() 中它被转为 Symfony 包中 AccessDeniedHttpException,默认状态码403;

TokenMismatchException 在 CSRF 验证未通过时抛出,prepareException() 中它被转为 Symfony 包中 HttpException,给定状态码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() ,预处理异常之后,又分别对 HttpResponseException、AuthenticationException 和 ValidationException 单独处理,并转为响应返回。

除此以外的异常,都在 prepareJsonResponse() 或 prepareResponse() 处理 ,expectsJson() 用来判断返回 json 响应还是普通响应。

修改异常响应格式

了解了异常处理流程,接下来就处理异常响应格式。

修改登录认证异常格式

由上文可知,AuthenticationException 被捕获后,调用 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() 使其返回我们想要的数据格式。

protected function unauthenticated($request, AuthenticationException $exception)

{

return $request->expectsJson()

? response()->json([

'code' => 0,

'data' => $exception->getMessage(),

], 401)

: redirect()->guest($exception->redirectTo() ?? route('login'));

}

修改验证异常格式

同样由上文可知,ValidationException 被捕获后交由 convertValidationExceptionToResponse() 处理,进入此方法后我们需要继续追踪,若是需要 json 响应,最终交由 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);

}

我们继续在 appExceptionsHandler.php 重写 invalidJson() 即可自定义返回格式。

protected function invalidJson($request, ValidationException $exception)

{

return response()->json([

'code' => 0,

'data' => $exception->errors(),

], $exception->status);

}

修改其他异常格式

其他异常是调用 prepareJsonResponse() 来处理,此方法又调用 convertExceptionToArray() 来处理响应格式。

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() 来自定义其他异常响应格式。

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',

];

}

强制 json 响应

代码中多次出现了 expectsJson() ,此方法是用来判断返回 json 响应还是普通响应。

public function expectsJson()

{

return ($this->ajax() && ! $this->pjax() && $this->acceptsAnyContentType()) || $this->wantsJson();

}

以下两种条件下,会返回json响应。

非XML请求、非pjax并且 Headers 中 Accept 设置为接收所有格式响应;

Headers Accept 设置为 /json、+json。如:Accept:application/json。

除此之外的情况,将不会响应json。我们可以利用中间件强制追加 Accept:application/json,使异常响应时都返回json。(参考教程 L03 6.0 中提到的方法)

创建中间件 AcceptHeader

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',

],

];

大功告成。

总结

到此这篇关于Laravel如何实现适合Api的异常处理响应格式的文章就介绍到这了,更多相关Laravel适合Api的异常处理响应格式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

设置响应主体格式php,Laravel如何实现适合Api的异常处理响应格式相关推荐

  1. laravel ajax login,设置在ajax上记住laravel登录

    使用laravel重建我的系统5.4. 我做了一个可以工作的ajax登录,但是我想将记住选项添加到auth. 文档说这有关设置记住:设置在ajax上记住laravel登录 if (Auth::atte ...

  2. java后置过滤器_java - 如何使用zuul将响应主体提取到后置过滤器中

    我正在使用POC,我需要使用zuul作为服务器来首先路由2条路由,它将正常运行,但它具有自定义的后置过滤器,它将使用第一个命令响应的一些数据将另一个请求发送到其他api, 因此需要将第一个请求的响应主 ...

  3. python处理csv文件将字符串格式XXXX年XX月XX日转化为datetime64XXXX-XX-XX格式,可以进行索引设置和日期计算

    python处理csv文件将字符串格式XXXX年XX月XX日转化为datetime64XXXX-XX-XX格式,可以进行索引设置和日期计算 python读取csv文件中,某列卫XXXX年XX月XX日, ...

  4. AutoWrapper:通过有意义的响应来美化您的ASP.NET Core API

    目录 介绍 默认的ASP.NET Core API响应 AutoWrapper.Core的救援 主要特点: TL,DR 给我看代码 定义自己的自定义消息 定义自己的Api异常 选项 版本1.0.0 1 ...

  5. 浏览器跨域服务器响应了吗,浏览器跨域问题之HTTP跨域响应头 | kTWO-个人博客

    摘要 本篇文章主要讲解HTTP中的几种响应头,解决web开发中常见的浏览器跨域问题CORS,主要包括了四个HTTP响应报文中的四个字段,同时讲解了如何携带cookie进行跨域. 0x01 浏览器跨域 ...

  6. Laravel 使用 Passport 进行API认证

    曾经使用过Dingo + JWT来做API系统,工作起来还好,就是配置比较麻烦.现在使用官方扩展包来尝试下. 首先安装 Laravel/Passport,这里不再重复,直接参考官方文档. https: ...

  7. symfony api 错误响应_如何设计一个牛逼的 API 接口

    在日常开发中,总会接触到各种接口.前后端数据传输接口,第三方业务平台接口.一个平台的前后端数据传输接口一般都会在内网环境下通信,而且会使用安全框架,所以安全性可以得到很好的保护.这篇文章重点讨论一下提 ...

  8. java发送post请求json格式_Linux QT 4G发送HTTP POST请求发送JSON格式的数据

    一.在PC Window(QT5版本) 1.1.构建URL 1.2.构建HTTP请求头 1.3.连接信号与操作,接收服务器回复的消息 槽函数这里我们要在头文件定义,然后把处理过程实现. void Ma ...

  9. api php jwt,Laravel使用JWT实现API用户授权的详细步骤

    本篇文章给大家带来的内容是关于Laravel使用JWT实现API用户授权的详细步骤,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 第一部分 安装JWT 第一步. 使用Composer ...

最新文章

  1. 字符串面试题(一)字符串逆序
  2. Django 实现分库
  3. 关于Oracle数据库19c中的关键字和保留字的说明
  4. CentOS 6.7 RPM安装MySQL
  5. 新建notebook时发现在notebook里的sys.path与电脑上不一样
  6. vs 不能自动 析构函数_深入理解C++虚函数的override、overload与hide以及虚析构函数...
  7. docker ubuntu16.04镜像下安装cowrie蜜罐记录
  8. 3. PowerShell --基本操作,Alias,输出
  9. Windows Mobile 中怎样获得当前应用程序所在路径
  10. java包含_【Java】判断字符串是否包含子字符串
  11. [Ubuntu18.04]美化
  12. python闭包函数的必要条件_Python闭包函数
  13. CCS12.0 安装并设置中文
  14. 背景建模算法比较与ViBe算法论文解读与python代码
  15. 勒索病毒自救在线工具
  16. c语言里面temp是什么文件夹,Temp文件夹是什么?Windows下Temp文件夹可以删除吗?...
  17. HTML5的结构元素
  18. python 批量读取csv_Python Pandas批量读取csv文件到dataframe的方法
  19. python2.7安装教程windowsxp_怎么在windows xp 下安装python 2.7
  20. 安卓巴士总结了近百个Android优秀开源项

热门文章

  1. python提取pdf表格数据导出到mongodb_python读取mongoDB数据并存入本地excel表格
  2. 过程或函数的副作用是_Python函数和函数式编程(两万字长文警告!一文彻底搞定函数,建议收藏!)...
  3. cudnn7.6.5下载 solitairetheme8_.NET Framework 3.5 开启方法及微软官方原版下载
  4. qpython编写爬虫_Python - 用 PyQt 写爬虫界面
  5. python文本菜单程序_python3.x Day1 菜单程序练习
  6. matlab如何创建table,MATLAB table数据结构 首篇
  7. ajax得到session,Ajax如何使用Session
  8. PostgreSQL(一)PostgreSQL一主二从集群部署
  9. Leetcode-121. 买卖股票的最佳时机
  10. 使用Powerdesigner的逆向工程生成PDM(主要是注释可以放进去)