创建新 user 服务项目

pull/2/MERGE
YunaiV 2020-04-20 22:58:12 +08:00
parent bdff67b7b3
commit cc9696938a
39 changed files with 595 additions and 362 deletions

View File

@ -12,6 +12,8 @@
<artifactId>mall-spring-boot-starter-swagger</artifactId> <artifactId>mall-spring-boot-starter-swagger</artifactId>
<dependencies> <dependencies>
<!-- Spring 核心 --> <!-- Spring 核心 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -12,6 +12,13 @@
<artifactId>mall-spring-boot-starter-web</artifactId> <artifactId>mall-spring-boot-starter-web</artifactId>
<dependencies> <dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-rpc-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Spring 核心 --> <!-- Spring 核心 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -24,6 +31,12 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -0,0 +1,23 @@
package cn.iocoder.mall.web.config;
import cn.iocoder.mall.web.interceptor.AccessLogInterceptor;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) // TODO 芋艿,未来可能考虑 REACTIVE
public class CommonWebAutoConfiguration implements WebMvcConfigurer {
@Reference(validation = "true", version = "${dubbo.consumer.AdminAccessLogService.version:1.0.0}")
// @Reference(validation = "true", version = "1.0.0")
// private SystemLogRPC systemLogRPC;
@Bean
public AccessLogInterceptor accessLogInterceptor() {
return new AccessLogInterceptor();
}
}

View File

@ -1,131 +1,103 @@
package cn.iocoder.mall.web.handler; package cn.iocoder.mall.web.handler;
import cn.iocoder.common.framework.constant.SysErrorCodeEnum; //@ControllerAdvice
import cn.iocoder.common.framework.exception.ServiceException; //public class GlobalExceptionHandler {
import cn.iocoder.common.framework.util.ExceptionUtil; //
import cn.iocoder.common.framework.util.HttpUtil; //// /**
import cn.iocoder.common.framework.util.MallUtil; //// * 异常总数 Metrics
import cn.iocoder.common.framework.vo.CommonResult; //// */
import cn.iocoder.mall.system.api.SystemLogService; //// private static final Counter EXCEPTION_COUNTER = Metrics.counter("mall.exception.total");
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogAddDTO; //
import cn.iocoder.mall.system.api.dto.systemlog.ExceptionLogAddDTO; // private Logger logger = LoggerFactory.getLogger(getClass());
import com.alibaba.fastjson.JSON; //
import io.micrometer.core.instrument.Counter; // @Value("${spring.application.name}")
import io.micrometer.core.instrument.Metrics; // private String applicationName;
import org.apache.commons.lang3.exception.ExceptionUtils; //
import org.apache.dubbo.config.annotation.Reference; // @Reference(validation = "true", version = "${dubbo.consumer.AdminAccessLogService.version:1.0.0}")
import org.slf4j.Logger; // private SystemLogService systemLogService;
import org.slf4j.LoggerFactory; //
import org.springframework.beans.factory.annotation.Value; // // 逻辑异常
import org.springframework.scheduling.annotation.Async; // @ResponseBody
import org.springframework.util.Assert; // @ExceptionHandler(value = ServiceException.class)
import org.springframework.web.bind.MissingServletRequestParameterException; // public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) {
import org.springframework.web.bind.annotation.ControllerAdvice; // logger.debug("[serviceExceptionHandler]", ex);
import org.springframework.web.bind.annotation.ExceptionHandler; // return CommonResult.error(ex.getCode(), ex.getMessage());
import org.springframework.web.bind.annotation.ResponseBody; // }
//
import javax.servlet.http.HttpServletRequest; // // Spring MVC 参数不正确
import javax.validation.ConstraintViolationException; // @ResponseBody
import java.util.Date; // @ExceptionHandler(value = MissingServletRequestParameterException.class)
// public CommonResult missingServletRequestParameterExceptionHandler(HttpServletRequest req, MissingServletRequestParameterException ex) {
@ControllerAdvice // logger.warn("[missingServletRequestParameterExceptionHandler]", ex);
public class GlobalExceptionHandler { // return CommonResult.error(SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getMessage() + ":" + ex.getMessage());
// }
// /** //
// * 异常总数 Metrics // @ResponseBody
// */ // @ExceptionHandler(value = ConstraintViolationException.class)
// private static final Counter EXCEPTION_COUNTER = Metrics.counter("mall.exception.total"); // public CommonResult constraintViolationExceptionHandler(HttpServletRequest req, ConstraintViolationException ex) {
// logger.info("[constraintViolationExceptionHandler]", ex);
private Logger logger = LoggerFactory.getLogger(getClass()); // // TODO 芋艿,后续要想一个更好的方式。
// // 拼接详细报错
@Value("${spring.application.name}") // StringBuilder detailMessage = new StringBuilder("\n\n详细错误如下");
private String applicationName; // ex.getConstraintViolations().forEach(constraintViolation -> detailMessage.append("\n").append(constraintViolation.getMessage()));
// return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getMessage()
@Reference(validation = "true", version = "${dubbo.consumer.AdminAccessLogService.version:1.0.0}") // + detailMessage.toString());
private SystemLogService systemLogService; // }
//
// 逻辑异常 // // TODO 芋艿,应该还有其它的异常,需要进行翻译
@ResponseBody // @ResponseBody
@ExceptionHandler(value = ServiceException.class) // @ExceptionHandler(value = Exception.class)
public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) { // public CommonResult exceptionHandler(HttpServletRequest req, Exception e) {
logger.debug("[serviceExceptionHandler]", ex); // logger.error("[exceptionHandler]", e);
return CommonResult.error(ex.getCode(), ex.getMessage()); // // 插入异常日志
} // ExceptionLogAddDTO exceptionLog = new ExceptionLogAddDTO();
// try {
// Spring MVC 参数不正确 // // 增加异常计数 metrics
@ResponseBody // EXCEPTION_COUNTER.increment();
@ExceptionHandler(value = MissingServletRequestParameterException.class) // // 初始化 exceptionLog
public CommonResult missingServletRequestParameterExceptionHandler(HttpServletRequest req, MissingServletRequestParameterException ex) { // initExceptionLog(exceptionLog, req, e);
logger.warn("[missingServletRequestParameterExceptionHandler]", ex); // // 执行插入 exceptionLog
return CommonResult.error(SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.MISSING_REQUEST_PARAM_ERROR.getMessage() + ":" + ex.getMessage()); // addExceptionLog(exceptionLog);
} // } catch (Throwable th) {
// logger.error("[exceptionHandler][插入访问日志({}) 发生异常({})", JSON.toJSONString(exceptionLog), ExceptionUtils.getRootCauseMessage(th));
@ResponseBody // }
@ExceptionHandler(value = ConstraintViolationException.class) // // 返回 ERROR CommonResult
public CommonResult constraintViolationExceptionHandler(HttpServletRequest req, ConstraintViolationException ex) { // return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage());
logger.info("[constraintViolationExceptionHandler]", ex); // }
// TODO 芋艿,后续要想一个更好的方式。 //
// 拼接详细报错 // private void initExceptionLog(ExceptionLogAddDTO exceptionLog, HttpServletRequest request, Exception e) {
StringBuilder detailMessage = new StringBuilder("\n\n详细错误如下"); // // 设置用户编号
ex.getConstraintViolations().forEach(constraintViolation -> detailMessage.append("\n").append(constraintViolation.getMessage())); // exceptionLog.setUserId(MallUtil.getUserId(request));
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getMessage() // if (exceptionLog.getUserId() == null) {
+ detailMessage.toString()); // exceptionLog.setUserId(AccessLogAddDTO.USER_ID_NULL);
} // }
// exceptionLog.setUserType(MallUtil.getUserType(request));
// TODO 芋艿,应该还有其它的异常,需要进行翻译 // // 设置异常字段
@ResponseBody // exceptionLog.setExceptionName(e.getClass().getName());
@ExceptionHandler(value = Exception.class) // exceptionLog.setExceptionMessage(ExceptionUtil.getMessage(e));
public CommonResult exceptionHandler(HttpServletRequest req, Exception e) { // exceptionLog.setExceptionRootCauseMessage(ExceptionUtil.getRootCauseMessage(e));
logger.error("[exceptionHandler]", e); // exceptionLog.setExceptionStackTrace(ExceptionUtil.getStackTrace(e));
// 插入异常日志 // StackTraceElement[] stackTraceElements = e.getStackTrace();
ExceptionLogAddDTO exceptionLog = new ExceptionLogAddDTO(); // Assert.notEmpty(stackTraceElements, "异常 stackTraceElements 不能为空");
try { // StackTraceElement stackTraceElement = stackTraceElements[0];
// 增加异常计数 metrics // exceptionLog.setExceptionClassName(stackTraceElement.getClassName());
EXCEPTION_COUNTER.increment(); // exceptionLog.setExceptionFileName(stackTraceElement.getFileName());
// 初始化 exceptionLog // exceptionLog.setExceptionMethodName(stackTraceElement.getMethodName());
initExceptionLog(exceptionLog, req, e); // exceptionLog.setExceptionLineNumber(stackTraceElement.getLineNumber());
// 执行插入 exceptionLog // // 设置其它字段
addExceptionLog(exceptionLog); // exceptionLog.setTraceId(MallUtil.getTraceId())
} catch (Throwable th) { // .setApplicationName(applicationName)
logger.error("[exceptionHandler][插入访问日志({}) 发生异常({})", JSON.toJSONString(exceptionLog), ExceptionUtils.getRootCauseMessage(th)); // .setUri(request.getRequestURI()) // TODO 提升:如果想要优化,可以使用 Swagger 的 @ApiOperation 注解。
} // .setQueryString(HttpUtil.buildQueryString(request))
// 返回 ERROR CommonResult // .setMethod(request.getMethod())
return CommonResult.error(SysErrorCodeEnum.SYS_ERROR.getCode(), SysErrorCodeEnum.SYS_ERROR.getMessage()); // .setUserAgent(HttpUtil.getUserAgent(request))
} // .setIp(HttpUtil.getIp(request))
// .setExceptionTime(new Date());
private void initExceptionLog(ExceptionLogAddDTO exceptionLog, HttpServletRequest request, Exception e) { // }
// 设置用户编号 //
exceptionLog.setUserId(MallUtil.getUserId(request)); // @Async
if (exceptionLog.getUserId() == null) { // public void addExceptionLog(ExceptionLogAddDTO exceptionLog) {
exceptionLog.setUserId(AccessLogAddDTO.USER_ID_NULL); // systemLogService.addExceptionLog(exceptionLog);
} // }
exceptionLog.setUserType(MallUtil.getUserType(request)); //
// 设置异常字段 //}
exceptionLog.setExceptionName(e.getClass().getName());
exceptionLog.setExceptionMessage(ExceptionUtil.getMessage(e));
exceptionLog.setExceptionRootCauseMessage(ExceptionUtil.getRootCauseMessage(e));
exceptionLog.setExceptionStackTrace(ExceptionUtil.getStackTrace(e));
StackTraceElement[] stackTraceElements = e.getStackTrace();
Assert.notEmpty(stackTraceElements, "异常 stackTraceElements 不能为空");
StackTraceElement stackTraceElement = stackTraceElements[0];
exceptionLog.setExceptionClassName(stackTraceElement.getClassName());
exceptionLog.setExceptionFileName(stackTraceElement.getFileName());
exceptionLog.setExceptionMethodName(stackTraceElement.getMethodName());
exceptionLog.setExceptionLineNumber(stackTraceElement.getLineNumber());
// 设置其它字段
exceptionLog.setTraceId(MallUtil.getTraceId())
.setApplicationName(applicationName)
.setUri(request.getRequestURI()) // TODO 提升:如果想要优化,可以使用 Swagger 的 @ApiOperation 注解。
.setQueryString(HttpUtil.buildQueryString(request))
.setMethod(request.getMethod())
.setUserAgent(HttpUtil.getUserAgent(request))
.setIp(HttpUtil.getIp(request))
.setExceptionTime(new Date());
}
@Async
public void addExceptionLog(ExceptionLogAddDTO exceptionLog) {
systemLogService.addExceptionLog(exceptionLog);
}
}

View File

@ -1,31 +1,21 @@
package cn.iocoder.mall.web.handler; package cn.iocoder.mall.web.handler;
import cn.iocoder.common.framework.util.MallUtil; //@ControllerAdvice
import cn.iocoder.common.framework.vo.CommonResult; //public class GlobalResponseBodyHandler implements ResponseBodyAdvice {
import org.springframework.core.MethodParameter; //
import org.springframework.http.MediaType; // @Override
import org.springframework.http.server.ServerHttpRequest; // public boolean supports(MethodParameter returnType, Class converterType) {
import org.springframework.http.server.ServerHttpResponse; // if (returnType.getMethod() == null) {
import org.springframework.http.server.ServletServerHttpRequest; // return false;
import org.springframework.web.bind.annotation.ControllerAdvice; // }
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; // return returnType.getMethod().getReturnType() == CommonResult.class;
// }
@ControllerAdvice //
public class GlobalResponseBodyHandler implements ResponseBodyAdvice { // @Override
// public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
@Override // ServerHttpRequest request, ServerHttpResponse response) {
public boolean supports(MethodParameter returnType, Class converterType) { // MallUtil.setCommonResult(((ServletServerHttpRequest) request).getServletRequest(), (CommonResult) body);
if (returnType.getMethod() == null) { // return body;
return false; // }
} //
return returnType.getMethod().getReturnType() == CommonResult.class; //}
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
MallUtil.setCommonResult(((ServletServerHttpRequest) request).getServletRequest(), (CommonResult) body);
return body;
}
}

View File

@ -1,102 +1,102 @@
package cn.iocoder.mall.web.interceptor; package cn.iocoder.mall.web.interceptor;
import cn.iocoder.common.framework.util.HttpUtil; import org.springframework.beans.BeansException;
import cn.iocoder.common.framework.util.MallUtil; import org.springframework.beans.factory.InitializingBean;
import cn.iocoder.common.framework.vo.CommonResult; import org.springframework.context.ApplicationContext;
import cn.iocoder.mall.system.api.SystemLogService; import org.springframework.context.ApplicationContextAware;
import cn.iocoder.mall.system.api.dto.systemlog.AccessLogAddDTO;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
/** /**
* 访 * 访
*/ */
@Component public class AccessLogInterceptor extends HandlerInterceptorAdapter implements InitializingBean, ApplicationContextAware {
public class AccessLogInterceptor extends HandlerInterceptorAdapter {
private Logger logger = LoggerFactory.getLogger(getClass()); private ApplicationContext context;
/** //
* // private Logger logger = LoggerFactory.getLogger(getClass());
*/ //
private static final ThreadLocal<Date> START_TIME = new ThreadLocal<>(); // /**
// * 开始时间
@Reference(validation = "true", version = "${dubbo.consumer.AdminAccessLogService.version:1.0.0}") // */
private SystemLogService systemAccessLogService; // private static final ThreadLocal<Date> START_TIME = new ThreadLocal<>();
//
@Value("${spring.application.name}") // @Reference(validation = "true", version = "${dubbo.consumer.AdminAccessLogService.version:1.0.0}")
private String applicationName; // private SystemLogService systemAccessLogService;
//
// @Value("${spring.application.name}")
// private String applicationName;
//
// @Override
// public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// // 记录当前时间
// START_TIME.set(new Date());
// return true;
// }
//
// @Override
// public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// AccessLogAddDTO accessLog = new AccessLogAddDTO();
// try {
// // 初始化 accessLog
// initAccessLog(accessLog, request);
// // 执行插入 accessLog
// addAccessLog(accessLog);
// // TODO 提升:暂时不考虑 ELK 的方案。而是基于 MySQL 存储。如果访问日志比较多,需要定期归档。
// } catch (Throwable th) {
// logger.error("[afterCompletion][插入访问日志({}) 发生异常({})", JSON.toJSONString(accessLog), ExceptionUtils.getRootCauseMessage(th));
// } finally {
// clear();
// }
// }
//
// private void initAccessLog(AccessLogAddDTO accessLog, HttpServletRequest request) {
// // 设置用户编号
// accessLog.setUserId(MallUtil.getUserId(request));
// if (accessLog.getUserId() == null) {
// accessLog.setUserId(AccessLogAddDTO.USER_ID_NULL);
// }
// accessLog.setUserType(MallUtil.getUserType(request));
// // 设置访问结果
// CommonResult result = MallUtil.getCommonResult(request);
// Assert.isTrue(result != null, "result 必须非空");
// accessLog.setErrorCode(result.getCode())
// .setErrorMessage(result.getMessage());
// // 设置其它字段
// accessLog.setTraceId(MallUtil.getTraceId())
// .setApplicationName(applicationName)
// .setUri(request.getRequestURI()) // TODO 提升:如果想要优化,可以使用 Swagger 的 @ApiOperation 注解。
// .setQueryString(HttpUtil.buildQueryString(request))
// .setMethod(request.getMethod())
// .setUserAgent(HttpUtil.getUserAgent(request))
// .setIp(HttpUtil.getIp(request))
// .setStartTime(START_TIME.get())
// .setResponseTime((int) (System.currentTimeMillis() - accessLog.getStartTime().getTime())); // 默认响应时间设为 0
// }
//
// @Async // 异步入库
// public void addAccessLog(AccessLogAddDTO accessLog) {
// try {
// systemAccessLogService.addAccessLog(accessLog);
// } catch (Throwable th) {
// logger.error("[addAccessLog][插入访问日志({}) 发生异常({})", JSON.toJSONString(accessLog), ExceptionUtils.getRootCauseMessage(th));
// }
// }
//
// private static void clear() {
// START_TIME.remove();
// }
//
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { public void setApplicationContext(ApplicationContext context) throws BeansException {
// 记录当前时间 this.context = context;
START_TIME.set(new Date());
return true;
} }
@Override @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { public void afterPropertiesSet() throws Exception {
AccessLogAddDTO accessLog = new AccessLogAddDTO(); System.out.println();
try {
// 初始化 accessLog
initAccessLog(accessLog, request);
// 执行插入 accessLog
addAccessLog(accessLog);
// TODO 提升:暂时不考虑 ELK 的方案。而是基于 MySQL 存储。如果访问日志比较多,需要定期归档。
} catch (Throwable th) {
logger.error("[afterCompletion][插入访问日志({}) 发生异常({})", JSON.toJSONString(accessLog), ExceptionUtils.getRootCauseMessage(th));
} finally {
clear();
}
} }
private void initAccessLog(AccessLogAddDTO accessLog, HttpServletRequest request) {
// 设置用户编号
accessLog.setUserId(MallUtil.getUserId(request));
if (accessLog.getUserId() == null) {
accessLog.setUserId(AccessLogAddDTO.USER_ID_NULL);
}
accessLog.setUserType(MallUtil.getUserType(request));
// 设置访问结果
CommonResult result = MallUtil.getCommonResult(request);
Assert.isTrue(result != null, "result 必须非空");
accessLog.setErrorCode(result.getCode())
.setErrorMessage(result.getMessage());
// 设置其它字段
accessLog.setTraceId(MallUtil.getTraceId())
.setApplicationName(applicationName)
.setUri(request.getRequestURI()) // TODO 提升:如果想要优化,可以使用 Swagger 的 @ApiOperation 注解。
.setQueryString(HttpUtil.buildQueryString(request))
.setMethod(request.getMethod())
.setUserAgent(HttpUtil.getUserAgent(request))
.setIp(HttpUtil.getIp(request))
.setStartTime(START_TIME.get())
.setResponseTime((int) (System.currentTimeMillis() - accessLog.getStartTime().getTime())); // 默认响应时间设为 0
}
@Async // 异步入库
public void addAccessLog(AccessLogAddDTO accessLog) {
try {
systemAccessLogService.addAccessLog(accessLog);
} catch (Throwable th) {
logger.error("[addAccessLog][插入访问日志({}) 发生异常({})", JSON.toJSONString(accessLog), ExceptionUtils.getRootCauseMessage(th));
}
}
private static void clear() {
START_TIME.remove();
}
} }

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.mall.web.config.CommonWebAutoConfiguration

View File

@ -4,4 +4,4 @@ spring:
name: admin-application name: admin-application
# Profile 的配置项 # Profile 的配置项
profiles: profiles:
active: test active: local

View File

@ -22,14 +22,17 @@
<!-- Web 相关 --> <!-- Web 相关 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>cn.iocoder.mall</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>mall-spring-boot-starter-web</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.iocoder.mall</groupId> <groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-swagger</artifactId> <artifactId>mall-spring-boot-starter-swagger</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<!-- TODO 云服务 -->
<dependency> <dependency>
<groupId>com.qiniu</groupId> <groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId> <artifactId>qiniu-java-sdk</artifactId>

View File

@ -9,7 +9,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** /**
* (Admins API) * (Admins API)
@ -17,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
* author: sin * author: sin
* time: 2020/4/20 9:41 * time: 2020/4/20 9:41
*/ */
@RestController //@RestController
@RequestMapping("admins/file") @RequestMapping("admins/file")
@Api(tags = "文件模块") @Api(tags = "文件模块")
public class AdminsFileController { public class AdminsFileController {

View File

@ -12,17 +12,21 @@
<artifactId>user</artifactId> <artifactId>user</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<!-- <module>user-application</module>-->
<!-- <module>user-service-api</module>-->
<!-- <module>user-sdk</module>-->
<!-- <module>user-service-impl</module>-->
<module>user-application</module> <module>user-application</module>
<module>user-service-api</module> <module>user-rest</module>
<module>user-sdk</module> <module>user-rpc</module>
<module>user-service-impl</module> <module>user-rpc-api</module>
</modules> </modules>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>cn.iocoder.mall</groupId> <groupId>cn.iocoder.mall</groupId>
<artifactId>common-dependencies</artifactId> <artifactId>mall-dependencies</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>

View File

@ -11,97 +11,20 @@
<artifactId>user-application</artifactId> <artifactId>user-application</artifactId>
<properties>
</properties>
<dependencies> <dependencies>
<!-- Mall 相关 --> <!-- Mall 相关 -->
<dependency> <dependency>
<groupId>cn.iocoder.mall</groupId> <groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId> <artifactId>user-rest</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.iocoder.mall</groupId> <groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot</artifactId> <artifactId>user-rpc</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-impl</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-sdk</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
<!-- 服务保障相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -2,13 +2,22 @@ package cn.iocoder.mall.user.application;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.boot.context.config.ConfigFileApplicationListener;
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.user"}) @SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.system"})
@EnableAsync(proxyTargetClass = true)
public class UserApplication { public class UserApplication {
/**
*
* {@link org.springframework.boot.context.config.ConfigFileApplicationListener#CONFIG_NAME_PROPERTY}
*/
private static final String CONFIG_NAME_VALUE = "biz,rest,rpc,application";
public static void main(String[] args) { public static void main(String[] args) {
// 设置环境变量
System.setProperty(ConfigFileApplicationListener.CONFIG_NAME_PROPERTY, CONFIG_NAME_VALUE);
// 启动 Spring Boot 应用
SpringApplication.run(UserApplication.class, args); SpringApplication.run(UserApplication.class, args);
} }

View File

@ -1,32 +1,8 @@
spring: spring:
# Application 的配置项
application: application:
name: user-application name: user-application
# Profile 的配置项
profiles:
active: local
# Spring Cloud 配置项
cloud:
# Spring Cloud Sentinel 配置项
sentinel:
transport:
dashboard: s1.iocoder.cn:12088 # Sentinel Dashboard 服务地址
eager: true # 项目启动时,直接连接到 Sentinel
# server
server:
port: 18082
servlet:
context-path: /user-api/
swagger:
enable: true # 暂时不去掉
title: 用户子系统
description: 用户子系统
version: 1.0.0
base-package: cn.iocoder.mall.user.application.controller
management:
endpoints:
web:
exposure:
include: health,info,env,metrics,prometheus
metrics:
enabled: true

32
user/user-rest/pom.xml Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>user</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>user-rest</artifactId>
<dependencies>
<!-- Mall 相关 -->
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.mall</groupId>-->
<!-- <artifactId>system-biz</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-web</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- TODO 云服务 -->
</dependencies>
</project>

View File

@ -0,0 +1,12 @@
# 服务器的配置项
server:
port: 18082
servlet:
context-path: /user-api/
# Swagger 配置项
swagger:
title: 用户子系统
description: 用户子系统
version: 1.0.0
base-package: cn.iocoder.mall.user.rest.controller

30
user/user-rpc-api/pom.xml Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>user</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>user-rpc-api</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
</dependencies>
</project>

45
user/user-rpc/pom.xml Normal file
View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>user</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>user-rpc</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-rpc-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-rpc-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.mall</groupId>-->
<!-- <artifactId>user-biz</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- RPC 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Registry 和 Config 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
spring:
# Spring Cloud 配置项
cloud:
nacos:
# Spring Cloud Nacos Discovery 配置项
discovery:
server-addr: s1.iocoder.cn:8848 # Nacos 服务器地址
namespace: local # Nacos 命名空间
# Dubbo 配置项
dubbo:
# Dubbo 注册中心
registry:
address: spring-cloud://s1.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址

View File

@ -0,0 +1,14 @@
spring:
# Spring Cloud 配置项
cloud:
nacos:
# Spring Cloud Nacos Discovery 配置项
discovery:
server-addr: s1.iocoder.cn:8848 # Nacos 服务器地址
namespace: test # Nacos 命名空间
# Dubbo 配置项
dubbo:
# Dubbo 注册中心
registry:
address: spring-cloud://s1.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址

View File

@ -0,0 +1,17 @@
# Dubbo 配置项
dubbo:
# Spring Cloud Alibaba Dubbo 专属配置
cloud:
subscribed-services: system-application # 设置订阅的应用列表,默认为 * 订阅所有应用
# Dubbo 提供者的协议
protocol:
name: dubbo
port: -1
# Dubbo 提供服务的扫描基础包
scan:
base-packages: cn.iocoder.mall.user.rpc.rpc
# Dubbo 服务提供者的配置
provider:
filter: -exception
SystemLogRPC:
version: 1.0.0

107
user/user-start/pom.xml Normal file
View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>user</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>user-application</artifactId>
<properties>
</properties>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-impl</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
<!-- 服务保障相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package cn.iocoder.mall.user.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.user"})
@EnableAsync(proxyTargetClass = true)
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}

View File

@ -0,0 +1,32 @@
spring:
application:
name: user-application
# Spring Cloud 配置项
cloud:
# Spring Cloud Sentinel 配置项
sentinel:
transport:
dashboard: s1.iocoder.cn:12088 # Sentinel Dashboard 服务地址
eager: true # 项目启动时,直接连接到 Sentinel
# server
server:
port: 18082
servlet:
context-path: /user-api/
swagger:
enable: true # 暂时不去掉
title: 用户子系统
description: 用户子系统
version: 1.0.0
base-package: cn.iocoder.mall.user.application.controller
management:
endpoints:
web:
exposure:
include: health,info,env,metrics,prometheus
metrics:
enabled: true