问题描述
我的是微服务项目,common包为公共包抽离通用的功能比如:提供全局异常处理等。
所以我在gateway网关服务引用common包
但是启动时出现了警告
gateway的api能访问,但是通过网关其他微服务就访问404失效了 。
其他微服务通过自己的端口号能访问成功,说明不是其他微服务出了问题,是webflux和web冲突导致gateway网关失效。
原因
common包有web依赖引入。
gateway包需要webflux依赖引入
当gateway包引入了common包,gateway使用了webflux而common用传统的web,两者会发生冲突导致gateway失效。
解决方法
方案一:common包引入的web依赖改为webfluex依赖,但是其他微服务使用的是传统的web,导致其他微服务引入common包报错,故本人不用此方法。
方案二:把common包下gateway需要的功能复制拷贝到gateway包下, 比如全局异常处理。
import com.gjs.springcloudgateway.util.HttpCodeEnum;
import com.gjs.springcloudgateway.util.ResponseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.support.WebExchangeBindException;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.MethodNotAllowedException;
import org.springframework.web.server.ServerWebExchange;
import javax.annotation.Resource;
import java.util.InputMismatchException;
import java.util.List;
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
private final String sysError="系统出错";
/*
* @Description: 捕获请求方法异常,比如post接口使用了get
*/
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(MethodNotAllowedException.class)
public ResponseResult methodNotAllowedHandler(MethodNotAllowedException e, ServerWebExchange exchange) {
String requestURI = exchange.getRequest().getURI().toString();
log.error("请求地址'{}',请求方法不被允许'{}'", requestURI, e.getMessage());
return ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(), sysError);
}
// 参数校验异常
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler({WebExchangeBindException.class})
public ResponseResult bindExceptionHandler(WebExchangeBindException e, ServerWebExchange exchange) {
String requestURI = exchange.getRequest().getURI().toString();
log.error("请求地址'{}',参数校验异常:'{}'", requestURI, e.getMessage());
return ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(), sysError);
}
// 业务类异常
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(BusinessException.class)
public ResponseResult businessExceptionHandler(BusinessException e, ServerWebExchange exchange) {
String requestURI = exchange.getRequest().getURI().toString();
log.error("请求地址'{}',捕获业务类异常'{}'", requestURI,e.getMessage());
return ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(), e.getMessage());
}
// 运行时异常
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(RuntimeException.class)
public ResponseResult runtimeExceptionHandler(RuntimeException e,ServerWebExchange exchange) {
String requestURI = exchange.getRequest().getURI().toString();
log.error("请求地址'{}',捕获运行时异常'{}'", requestURI, e.getClass());
return ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(), e.getMessage());
}
// 系统级别异常
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Throwable.class)
public ResponseResult throwableExceptionHandler(Throwable e,ServerWebExchange exchange) {
String requestURI = exchange.getRequest().getURI().toString();
log.error("请求地址'{}',捕获系统级别异常'{}'", requestURI,e.getMessage());
return ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(), e.getMessage());
}
// 其他级别异常
@ExceptionHandler(value = Exception.class)
public ResponseResult exceptionHandler(Exception e,ServerWebExchange exchange) {
String requestURI = exchange.getRequest().getURI().toString();
log.error("请求地址'{}',捕获其他级别异常'{}'", requestURI,e.getClass());
return ResponseResult.errorResult(HttpCodeEnum.SYSTEM_ERROR.getCode(), e.getMessage());
}
private String getValidExceptionMsg(List<ObjectError> errors) {
if(!CollectionUtils.isEmpty(errors)){
StringBuilder sb = new StringBuilder();
errors.forEach(error -> {
if (error instanceof FieldError) {
sb.append(((FieldError)error).getField()).append(":");
}
sb.append(error.getDefaultMessage()).append(";");
});
String msg = sb.toString();
msg = msg.substring(0, msg.length() -1);
return msg;
}
return null;
}
}
并且要将传统命令式web的api改成编程式webfluex的api。
HttpServletRequest类改成webfluex的ServerWebExchange
之后完美启动也能通过网关访问其他微服务了