springgateway,统一返回

来源:4-4 Spring Cloud Alibaba使用场景

锅锅_java

2022-02-22

统一返回json格式集成这个接口,DefaultErrorWebExceptionHandler,获取异常时,无法获取请求body数据,因为body里面有交易流水号,需要返回去。请帮忙看下,加下QQ可以吗?914178928

package com.yitong.gateway.handler;

import cn.hutool.core.convert.Convert;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.yitong.common.data.MsgResp;
import com.yitong.common.enums.YtReturnInfoEnum;
import com.yitong.common.exception.BusinessException;
import com.yitong.common.exception.GatewayException;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.reactive.function.server.*;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Flux;

import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**

  •         统一返回
    
  • @update-date: 2020-11-24 08:48
    */
    public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {

    public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
    ErrorProperties errorProperties, ApplicationContext applicationContext) {
    super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }

    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {

     //TODO 根据请求body获取交易流水号并返回
     Flux<DataBuffer> body =   request.exchange().getRequest().getBody();
     AtomicReference<String> bodyRef = new AtomicReference<>();
     body.subscribe(buffer -> {
         CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
         DataBufferUtils.release(buffer);
         bodyRef.set(charBuffer.toString());
     });
     System.out.println(bodyRef.get());
     //TODO 无法获取为null
    
     Throwable error = super.getError(request);
    
     GatewayException gatewayException = new GatewayException();
    
     if ( error instanceof GatewayException) {
    
         gatewayException = (GatewayException) error;
    
     } else if (error instanceof FlowException) {
    
         gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_SENTINEL_FlOW);
    
    
     } else if (error instanceof DegradeException) {
    
         gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_SENTINEL_DEGRADE);
    
     } else if (error instanceof ParamFlowException) {
    
         gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_SENTINEL_PARAMFLOW);
    
    
     } else if (error instanceof SystemBlockException) {
    
         gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_SENTINEL_SYSTEMBLOCK);
    
     } else if (error instanceof AuthorityException) {
    
         gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_SENTINEL_AUTHORITY);
    
     } else if (error instanceof ResponseStatusException){
    
         ResponseStatusException responseStatusException = (ResponseStatusException)error;
    
         HttpStatus httpStatus = responseStatusException.getStatus();
    
         if (HttpStatus.NOT_FOUND.equals(httpStatus) || HttpStatus.SERVICE_UNAVAILABLE.equals(httpStatus)) {
    
             gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_NOT_FOUND);
    
         } else {
    
             gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_FAIL);
         }
    
     } else if (error instanceof BusinessException) {
    
         BusinessException businessException = (BusinessException)error;
    
         gatewayException = new GatewayException(businessException.getCode(),businessException.getMsg());
    
     }  else {
    
         gatewayException = new GatewayException(YtReturnInfoEnum.GATEWAY_FAIL);
    
     }
    
     return response(gatewayException.getCode(),gatewayException.getMsg());
    

    }

    /**

    • 指定响应处理方法为JSON处理的方法

    • @param errorAttributes
      */
      @Override
      protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) {

      return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);

    }

    /**

    • 根据code获取对应的HttpStatus

    • @param errorAttributes
      /
      @Override
      protected int getHttpStatus(Map<String, Object> errorAttributes) {
      /
      * 此代码不对,因为code在 HttpStatus中找不到 锅锅 start /
      // String statusCode = (String) errorAttributes.get(“retCode”);
      /
      此代码不对,因为code在 HttpStatus中找不到 锅锅 end **/

      int code = Convert.toInt(errorAttributes.get(“code”), 9000);
      //onenet平台验证错误
      if (code == 9000 ) {

       return HttpStatus.OK.value();
      

      }

      return HttpStatus.BAD_REQUEST.value();
      }

    /**

    • 构建返回的JSON数据格式

    • @param status 状态码

    • @param errorMessage 异常信息

    • @return
      */
      public static Map<String, Object> response(Integer status, String errorMessage) {

      MsgResp msgResp = MsgResp.fail(status,errorMessage);

      Map<String,Object> map = Convert.convert(Map.class, msgResp);

      return map;
      }

}

写回答

1回答

大目

2022-02-22

// String statusCode = (String) errorAttributes.get(“retCode”); 


有在上游设置名为retCoded的属性吗?

0
2
锅锅_java
项目架构,一个跨域java,一个覆盖默认异常返回的handler配置,一个body不能重读的java全局过滤器,一个JWT校验过滤器,一个json统一返回handler
2022-02-25
共2条回复

Spring Cloud Alibaba微服务从入门到进阶

面向未来微服务:熟练掌握Spring Cloud Alibaba

3085 学习 · 1324 问题

查看课程