文章目录
- 前言
- 一、异常处理
- 1. 响应实体类
- 2. 异常处理类
- 二、单元测试
- 1. 无可用路由
- 2. 服务不可用
- 总结
前言
网关作为我们对外服务的入口起着至关重要的作用,我们必须保证网关服务的稳定性,下面来为网关服务增加异常处理机制。
一、异常处理
1. 响应实体类
package org.example.common.model;import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;//统一响应结果
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {private Integer code;//业务状态码 0-成功 1-失败private String title;//标题private String message;//提示信息private T data;//响应数据public Result(Integer code, String title, String message) {this.code = code;this.title = title;this.message = message;}public Result(Integer code, String message, T data) {this.code = code;this.message = message;this.data = data;}//快速返回操作成功响应结果(带响应数据)public static <E> Result<E> success(E data) {return new Result<>(0, "操作成功", data);}public static <E> Result<E> success(String message,E data) {return new Result<>(0, message, data);}public static Result success(String message) {return new Result<>(0, message, null);}//快速返回操作成功响应结果public static Result success() {return new Result(0, "操作成功", null);}public static Result error(String message) {return new Result(1, message, null);}public static Result error(int code,String message) {return new Result(code, message, null);}public static Result error(int code,String title,String message) {return new Result(code,title , message);}
}
2. 异常处理类
这里针对性地处理了无可用路由和无可用服务两种场景异常,和一种铺地异常的处理,大家有自定义异常或其他异常可自行添加处理逻辑
package org.example.gateway.config;import org.example.common.model.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.reactive.resource.NoResourceFoundException;
import java.io.PrintWriter;
import java.io.StringWriter;/*** Create by zjg on 2024/7/27*/
@RestControllerAdvice
public class GlobalExceptionHandler {Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);@ExceptionHandler(NoResourceFoundException.class)//无可用路由public Result exception(ServerHttpResponse response,NoResourceFoundException ex){String detail = ex.getBody().getDetail();String mark="resource ";String message = detail.substring(detail.indexOf(mark) + mark.length());setStatusCode(response,ex.getStatusCode());return Result.error(ex.getStatusCode().value(),"无可用路由",String.format("没有可用的路由[%s]",message));}@ExceptionHandler(NotFoundException.class)//无可用服务public Result exception(ServerHttpResponse response,NotFoundException ex){logger.error(ex.getMessage());String detail = ex.getBody().getDetail();String mark="for ";String message = detail.substring(detail.indexOf(mark) + mark.length());setStatusCode(response,ex.getStatusCode());return Result.error(ex.getStatusCode().value(),"服务不可用",String.format("没有可用的服务实例[%s]",message));}@ExceptionHandler(Exception.class)//异常保底public Result exception(ServerHttpResponse response,Exception exception){StringWriter stringWriter = new StringWriter();PrintWriter writer=new PrintWriter(stringWriter);exception.printStackTrace(writer);logger.error(stringWriter.toString());setStatusCode(response,HttpStatus.INTERNAL_SERVER_ERROR);return Result.error(HttpStatus.INTERNAL_SERVER_ERROR.value(),exception.getMessage());}private void setStatusCode(ServerHttpResponse response,HttpStatusCode httpStatusCode){response.setStatusCode(httpStatusCode);}
}
二、单元测试
1. 无可用路由
curl 192.168.0.104:8888/provider/hello -H "Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGFpbXMiOnsidXNlcm5hbWUiOiJhZG1pbiJ9LCJpc3MiOiJhdXRoMCIsImV4cCI6MTcyMjE0NjE0MX0.IRlUZ5H_-PbPSbklqFGB1lOYquj0iifV2mhT-z68fhM"
2. 服务不可用
总结
回到顶部