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));
}
}