Java 【dubbo rpc改feign调用】feign接口异常统一处理

dubbo rpc改feign调用,feign调用接口异常统一处理

【框架改造问题点记录,dubbo改为spring cloud alibaba】
【第一篇】feign接口异常统一处理

服务提供方

示例代码中【ApplicationException 】、【Payload 】为自定义异常类和通用结果返回实体类:

java 复制代码
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import java.util.List;
import java.util.Set;

@Slf4j
@RestControllerAdvice
public class MyExceptionHandler {
    /**
     * 自定义业务异常
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(ApplicationException.class)
    public Payload handleApplicationException(ApplicationException e) {
        log.warn("业务提示", e);
        return new Payload<>(null, e.getCode(),
                e.getMessage());
    }

    /**
     * 未授权
     */
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(UnauthorizedException.class)
    public Payload handleUnauthorizedException(UnauthorizedException e) {
        log.warn("token验证失败", e);
        return new Payload<>(null, String.valueOf(HttpStatus.UNAUTHORIZED.value()),
                e.getMessage());
    }

    /**
     * 服务未知异常
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Payload handleUnknownException(Exception e) {
        log.error("服务运行异常", e);
        return new Payload<>(null, String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()),
                e.getMessage());
    }


    /**
     * 参数校验异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(org.springframework.web.bind.MethodArgumentNotValidException.class)
    public Payload handleMethodArgumentNotValidException(org.springframework.web.bind.MethodArgumentNotValidException e) {
        log.warn("参数错误", e);
        String warnMsg = "参数错误";
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> allErrorList = bindingResult.getAllErrors();
        if (!CollectionUtils.isEmpty(allErrorList)) {
            String defaultMessage = allErrorList.get(0).getDefaultMessage();
            if (StrUtil.isNotBlank(defaultMessage)) {
                warnMsg = defaultMessage;
            }
        }
        return new Payload<>(null, String.valueOf(HttpStatus.BAD_REQUEST.value()),
                warnMsg);
    }

    /**
     * 参数校验异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(javax.validation.ConstraintViolationException.class)
    public Payload handleConstraintViolationException(javax.validation.ConstraintViolationException e) {
        log.warn("参数错误", e);
        String warnMsg = "参数错误";
        Set<ConstraintViolation<?>> violationSet = e.getConstraintViolations();
        if (!CollectionUtils.isEmpty(violationSet)) {
            for (ConstraintViolation<?> violation : violationSet) {
                String message = violation.getMessage();
                if (StrUtil.isNotBlank(message)) {
                    warnMsg = message;
                    break;
                }
            }
        }
        return new Payload<>(null, String.valueOf(HttpStatus.BAD_REQUEST.value()),
                warnMsg);
    }

    /**
     * 参数校验异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(org.springframework.validation.BindException.class)
    public Payload handleBindException(org.springframework.validation.BindException e) {
        log.warn("参数错误", e);
        String warnMsg = "参数错误";
        List<ObjectError> allErrorList = e.getAllErrors();
        if (!CollectionUtils.isEmpty(allErrorList)) {
            String defaultMessage = allErrorList.get(0).getDefaultMessage();
            if (StrUtil.isNotBlank(defaultMessage)) {
                warnMsg = defaultMessage;
            }
        }
        return new Payload<>(null, String.valueOf(HttpStatus.BAD_REQUEST.value()),
                warnMsg);
    }

    /**
     * 参数缺失异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(org.springframework.web.bind.MissingServletRequestParameterException.class)
    public Payload handleMissingServletRequestParameterException(org.springframework.web.bind.MissingServletRequestParameterException e) {
        log.warn("请求参数缺失", e);
        return new Payload<>(null, String.valueOf(HttpStatus.BAD_REQUEST.value()),
                e.getParameterName() + "不能为空");
    }
}
java 复制代码
package com.xxx;

public class UnauthorizedException extends RuntimeException {

    /**
     * 编码
     */
    private final String code;

    /**
     * 描述
     */
    private final String message;


    public UnauthorizedException(String message) {
        super(message);
        this.code = "401";
        this.message = message;
    }


    public String getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return this.message;
    }
}

服务调用方

示例代码中【ApplicationException 】、【StringUtil】为自定义异常类和自定义工具,自己平替即可:

java 复制代码
package com.xxx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Response;
import feign.Util;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.lang.reflect.Type;

@Configuration
@Slf4j
public class MyResponseEntityDecoder implements Decoder {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Object decode(Response response, Type type) throws IOException {
        JSONObject responseJson = null;
        String responseBody =null;
        try {
            responseBody = Util.toString(response.body().asReader());
            responseJson = JSON.parseObject(responseBody);
        } catch (IOException e) {
            log.error("feign.IOException", e);
            throw new ApplicationException("feign.IOException,response:"+response);
        }
        if (response.status() >= 400 && response.status() < 500) {
            throw new ApplicationException(responseJson.getString("msg"));
        }

        if (response.status() >= 500) {
            throw new ApplicationException(responseJson.getString("msg"));
        }
        if(StringUtil.isNotBlank(responseJson.getString("msg"))){
            throw new ApplicationException(responseJson.getString("msg"));
        }
        return objectMapper.readValue(responseBody, objectMapper.constructType(type));
    }
}
相关推荐
无限的鲜花8 小时前
反射(原创推荐)
java·开发语言
IT二叔9 小时前
Java项目部署-03-teamcity-cicd-docker镜像流水线方式部署
java·ci/cd·持续部署
一路向北he9 小时前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端
超级数据查看器9 小时前
超级数据查看器 v10.0 发布
java·大数据·数据库·sqlite·安卓
折哥的程序人生 · 物流技术专研11 小时前
《Java 100 天进阶之路》第50篇:阻塞队列与并发容器(2026版)
java·面试题·java进阶·blockingqueue·并发容器·集合源码·java100天进阶
ai_coder_ai11 小时前
编写自动化脚本,在自己后端服务中使用Open Api进行设备相关操作
java·运维·自动化
硕风和炜11 小时前
【LeetCode: 2492. 两个城市间路径的最小分数 + DFS】
java·算法·leetcode·深度优先·dfs·bfs·并查集
格子软件12 小时前
2026年GEO贴牌代理:分布式多级分账状态机源码深度解构
java·vue.js·分布式·vue·geo
我是一颗柠檬12 小时前
【Java项目技术亮点】加权轮询负载均衡算法
java·算法·负载均衡
灯厂码农12 小时前
C语言动态内存分配完全指南(malloc、calloc、realloc、free)
java·c语言·算法