增加属性控制生产环境feign不注入token

This commit is contained in:
ajaxfan
2021-03-25 18:59:52 +08:00
parent aa37c3e536
commit e93330b51a
3 changed files with 301 additions and 4 deletions

View File

@ -1,15 +1,16 @@
package com.chinaunicom.mall.ebtp.common.config; package com.chinaunicom.mall.ebtp.common.config;
import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.AUTHORIZATION_HEADER; import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.AUTHORIZATION_HEADER;
import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.COOKIE_TOKEN_CODE;
import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.CURRENT_ROLE_CODE; import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.CURRENT_ROLE_CODE;
import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.TOKEN_PREFIX; import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.TOKEN_PREFIX;
import static com.chinaunicom.mall.ebtp.cloud.security.starter.common.Constants.COOKIE_TOKEN_CODE;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
@ -21,6 +22,7 @@ import feign.RequestTemplate;
* 通过拦截器来为header注入token * 通过拦截器来为header注入token
*/ */
@Configuration @Configuration
@ConditionalOnProperty(name = "ebtp.universal.feign.token.interceptor", havingValue = "true", matchIfMissing = true)
public class FeignConfig implements RequestInterceptor { public class FeignConfig implements RequestInterceptor {
/** /**
@ -42,7 +44,8 @@ public class FeignConfig implements RequestInterceptor {
Optional.ofNullable(attributes.getRequest().getCookies()).ifPresent(cookies -> { Optional.ofNullable(attributes.getRequest().getCookies()).ifPresent(cookies -> {
Stream.of(cookies).filter(item -> StringUtils.equals(item.getName(), COOKIE_TOKEN_CODE)).findFirst() Stream.of(cookies).filter(item -> StringUtils.equals(item.getName(), COOKIE_TOKEN_CODE)).findFirst()
.ifPresent(token -> { .ifPresent(token -> {
template.header(AUTHORIZATION_HEADER, String.format("%s%s", TOKEN_PREFIX, token.getValue())); template.header(AUTHORIZATION_HEADER,
String.format("%s%s", TOKEN_PREFIX, token.getValue()));
}); });
}); });
} }

View File

@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Profile;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
@ -34,7 +35,6 @@ import com.chinaunicom.mall.ebtp.common.util.JsonUtils;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.exceptions.ExceptionUtil;
import io.seata.core.context.RootContext; import io.seata.core.context.RootContext;
import io.seata.core.exception.RmTransactionException;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -51,7 +51,8 @@ import lombok.extern.slf4j.Slf4j;
@ControllerAdvice @ControllerAdvice
@ResponseBody @ResponseBody
@ConditionalOnProperty(name = "mconfig.exception-handle-enabled", matchIfMissing = true) @ConditionalOnProperty(name = "mconfig.exception-handle-enabled", matchIfMissing = true)
public class BusinessExceptionHandlerAdvice { @Profile({"test", "local", "uat"})
public class BusinessExceptionHandlerAdviceDefault {
/** /**
* 业务异常处理 * 业务异常处理

View File

@ -0,0 +1,293 @@
package com.chinaunicom.mall.ebtp.common.exception.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Profile;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.exception.entity.BusinessException;
import com.chinaunicom.mall.ebtp.common.util.JsonUtils;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.ExceptionUtil;
import io.seata.core.context.RootContext;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
/**
* 异常处理 拦截BindException异常返回HttpStatus是400的绑定错误信息
* 拦截FrameException异常返回HttpStatus是406的业务处理错误信息(支持自定义状态码)
* 拦截Exception异常返回HttpStatus是500服务器内部异常
*
* @author fqj
* @date 2020年9月3日 11:42:25
*/
@Slf4j
@ControllerAdvice
@ResponseBody
@Profile({ "pro" })
@ConditionalOnProperty(name = "mconfig.exception-handle-enabled", matchIfMissing = true)
public class BusinessExceptionHandlerAdvicePro {
/**
* 业务异常处理
*
* @param request 请求
* @param exception ServiceErrorException异常对象
* @return 响应
*/
@ExceptionHandler(value = BusinessException.class)
@ResponseStatus(HttpStatus.OK)
public BaseResponse<String> serviceErrorException(HttpServletRequest request, BusinessException exception) {
log.info(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>();
return BaseResponse.fail(exception.getCode(), exception.getMessage(), Convert.toStr(body));
}
/**
* hibernate valid 验证异常拦截
*
* @param request 请求
* @param exception ServiceErrorException异常对象
* @return 响应
*/
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleInvalidMethodArgException(HttpServletRequest request,
MethodArgumentNotValidException exception) {
// 堆栈信息转为字符串
log.info(ExceptionUtil.stacktraceToString(exception));
// 按需重新封装需要返回的错误信息
List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
// 解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
BindingResult bindingResult = exception.getBindingResult();
for (FieldError error : bindingResult.getFieldErrors()) {
ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
invalidArgument.setDefaultMessage(error.getDefaultMessage());
invalidArgument.setField(error.getField());
invalidArgument.setRejectedValue(error.getRejectedValue());
invalidArguments.add(invalidArgument);
}
Map<String, Object> body = new HashMap<>();
body.put("errors", JsonUtils.objectToJson(invalidArguments));
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数验证错误", Convert.toStr(body));
}
/**
* 参数绑定异常
*
* @param request 请求
* @param exception BindException异常对象
* @return 响应
*/
@ExceptionHandler(value = BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> methodArgumentNotValidHandler(HttpServletRequest request, BindException exception) {
// 按需重新封装需要返回的错误信息
List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
// 解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
for (FieldError error : exception.getBindingResult().getFieldErrors()) {
ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
invalidArgument.setDefaultMessage(error.getDefaultMessage());
invalidArgument.setField(error.getField());
invalidArgument.setRejectedValue(error.getRejectedValue());
invalidArguments.add(invalidArgument);
}
Map<String, Object> body = new HashMap<>();
body.put("errors", JsonUtils.objectToJson(invalidArguments));
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数错误", Convert.toStr(body));
}
/**
* 请求方式异常
*
* @param request 请求
* @param exception HttpRequestMethodNotSupportedException异常对象
* @return 响应
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public BaseResponse<String> handleMethodNotSupportedException(HttpServletRequest request,
HttpRequestMethodNotSupportedException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
return BaseResponse.fail(HttpStatus.METHOD_NOT_ALLOWED.value(), "错误的请求方式", Convert.toStr(body));
}
/**
* 参数缺失
*
* @param request 请求
* @param exception MissingServletRequestParameterException异常对象
* @return 响应
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleMissingParameterException(HttpServletRequest request,
MissingServletRequestParameterException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数缺失" + exception.getMessage(), Convert.toStr(body));
}
// ----------------------------data--------------------------------------
/**
* 数据库异常
*
* @param request 请求
* @param exception DataAccessException异常对象
* @return 响应
*/
@ExceptionHandler(DataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handlerDataAccessException(HttpServletRequest request, DataAccessException exception) {
log.error(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据库异常" + exception.getMessage(), Convert.toStr(body));
}
/**
* 数据不存在
*
* @param request 请求
* @param exception EmptyResultDataAccessException异常对象
* @return 响应
*/
@ExceptionHandler(EmptyResultDataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleDataEmptyException(HttpServletRequest request,
EmptyResultDataAccessException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据不存在", Convert.toStr(body));
}
/**
* 请求方式异常
*
* @param request 请求
* @param exception DuplicateKeyException异常对象
* @return 响应
*/
@ExceptionHandler(DuplicateKeyException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleDataDualException(HttpServletRequest request, DuplicateKeyException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据重复插入", Convert.toStr(body));
}
/**
* 方法参数类型不匹配异常
*
* @param request 请求
* @param exception MethodArgumentTypeMismatchException异常对象
* @return 响应
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleMethodArgumentTypeException(HttpServletRequest request,
MethodArgumentTypeMismatchException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数类型不匹配", Convert.toStr(body));
}
/**
* 全局异常处理
*
* @param request 请求
* @param exception Exception异常对象
* @return 响应
*/
@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleException(HttpServletRequest request, Exception exception) {
// 堆栈信息转为字符串
log.info(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
return BaseResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常" + exception.getMessage(),
Convert.toStr(body));
}
@ExceptionHandler({ TransactionSystemException.class })
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleTransactionSystemException(HttpServletRequest request,
TransactionSystemException exception) {
log.info(ExceptionUtil.stacktraceToString(exception));
if (((String) Objects.requireNonNull(exception.getMessage())).contains("may be has finished")) {
String xid = RootContext.getXID();
if (StringUtils.isNotEmpty(xid)) {
RootContext.unbind();
log.debug("TransactionSystemException ----- suspending current transaction,xid = {}", xid);
}
}
return BaseResponse.fail("系统繁忙,请重试", exception.getMessage());
}
/**
* 参数异常
*/
@Getter
@Setter
class ArgumentInvalidResult {
/**
* 字段名
*/
private String field;
/**
* 输入的错误值
*/
private Object rejectedValue;
/**
* 错误信息
*/
private String defaultMessage;
}
}