Skip to content

Commit

Permalink
添加pro-proto项目
Browse files Browse the repository at this point in the history
  • Loading branch information
deepraining committed Sep 23, 2022
1 parent e050f60 commit 427433d
Show file tree
Hide file tree
Showing 59 changed files with 3,740 additions and 1 deletion.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
## 子项目

- `pro-common`: 通用代码
- `pro-mbg`: Mybatis Generator
- `pro-mbg`: Mybatis Generator,用于自动生成 MyBatis 数据库模型与字段映射
- `pro-admin`: 使用 JWT 保持登陆状态的后台管理应用,包括基于角色的访问控制(RBAC),示例前端项目 [sbs-admin-web](https://github.com/deepraining/sbs-admin-web)
- `pro-front`: 使用 Session-Cookie 保持登陆状态的前端应用
- `pro-search`: 使用 [ElasticSearch](https://www.elastic.co/) 来做文本搜索引擎
- `pro-wx`: 微信登录相关示例项目
- `pro-rws`: 数据库读写分离示例项目
- `pro-mdb`: 多数据库、跨库读写示例项目
- `pro-amqp`: 异步消息队列(`RabbitMQ`)示例项目
- `pro-proto`: 使用 [protobuf](https://github.com/protocolbuffers/protobuf) 作为API数据交互格式,替代常用的 `json`
- `pro-protogen`: 从 MySql 数据库中的生成表对应的 `proto` 文件

## 扩展 Gradle Tasks

Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import java.nio.file.Paths;
plugins {
id 'java'
id 'application'
id 'idea'
id 'checkstyle'
id 'com.github.sherter.google-java-format' version '0.8'
id 'org.springframework.boot' version '2.1.4.RELEASE'
Expand All @@ -38,6 +39,7 @@ allprojects {
subprojects {
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'idea'
apply plugin: 'io.freefair.lombok'

dependencies {
Expand Down
46 changes: 46 additions & 0 deletions pro-proto/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
buildscript {
repositories {
mavenLocal()
// https://maven.aliyun.com/mvn/view
maven { url 'https://maven.aliyun.com/repository/public' }
jcenter()
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.17'
}
}

plugins {
id 'org.springframework.boot'
id "io.spring.dependency-management"
}

group = 'dr.sbs'
// version should not have '-'
version = new Date().format("yyyy.MMdd.HHmm", TimeZone.getTimeZone("GMT+08:00"))
archivesBaseName = 'sbs-proto'
sourceCompatibility = 1.8
description = 'Spring Boot Starter Protobuf Application.'

mainClassName = 'dr.sbs.proto.App'

apply plugin: 'com.google.protobuf'

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security:2.1.4.RELEASE'
implementation 'org.springframework.session:spring-session-data-redis:2.1.4.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.1.4.RELEASE'

implementation 'net.logstash.logback:logstash-logback-encoder:6.0'

implementation 'com.google.protobuf:protobuf-java:3.19.1'
implementation 'com.google.protobuf:protobuf-java-util:3.19.1'

// projects
implementation project(':pro-mbg')
implementation project(':pro-common')
implementation project(':pro-protogen')
}
2 changes: 2 additions & 0 deletions pro-proto/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# This file is generated by the 'io.freefair.lombok' Gradle plugin
config.stopBubbling = true
31 changes: 31 additions & 0 deletions pro-proto/src/main/java/dr/sbs/proto/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dr.sbs.proto;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Slf4j
@SpringBootApplication
@EnableRedisHttpSession
public class App extends SpringBootServletInitializer {

public static void main(String[] args) {
// Split config files into outer of jar file
System.setProperty("spring.config.additional-location", "file:${HOME}/.sbs-proto/");

ApplicationContext context = SpringApplication.run(App.class, args);
String serverPort = context.getEnvironment().getProperty("server.port");
log.info("App started at http://127.0.0.1:" + serverPort);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
// Split config files into outer of jar file
System.setProperty("spring.config.additional-location", "file:${HOME}/.sbs-proto/");
return application.sources(App.class);
}
}
22 changes: 22 additions & 0 deletions pro-proto/src/main/java/dr/sbs/proto/Init.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dr.sbs.proto;

import dr.sbs.common.util.UuidUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class Init implements ApplicationRunner {
@Value("${app.workerId}")
private long workerId;

@Value("${app.dataCenterId}")
private long dataCenterId;

@Override
public void run(ApplicationArguments args) throws Exception {
// Init UuidUtil
UuidUtil.init(workerId, dataCenterId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dr.sbs.proto.aspect;

import dr.sbs.common.CommonResult;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

/**
* global error handling aspect
*
* <p>note: `controller`的方法里,用`@Validated`标记需要验证的参数,最后面要有`BindingResult bindingResult`参数,才能生效
*/
@Aspect
@Component
@Order(2)
public class BindingResultAspect {
@Pointcut("execution(public * dr.sbs.proto.controller.*.*(..))")
public void bindingResult() {
//
}

@Around("bindingResult()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
if (arg instanceof BindingResult) {
BindingResult result = (BindingResult) arg;
if (result.hasErrors()) {
FieldError fieldError = result.getFieldError();
if (fieldError != null) {
return CommonResult.validateFailed(fieldError.getDefaultMessage());
} else {
return CommonResult.validateFailed();
}
}
}
}
return joinPoint.proceed();
}
}
126 changes: 126 additions & 0 deletions pro-proto/src/main/java/dr/sbs/proto/aspect/WebLogAspect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package dr.sbs.proto.aspect;

import dr.sbs.common.bo.WebLog;
import dr.sbs.common.util.JsonUtil;
import dr.sbs.common.util.RequestUtil;
import io.swagger.annotations.ApiOperation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.marker.Markers;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

/** global log handling aspect */
@Aspect
@Component
@Order(1)
@Slf4j
public class WebLogAspect {
private ThreadLocal<Long> startTime = new ThreadLocal<>();

@Pointcut("execution(public * dr.sbs.proto.controller.*.*(..))")
public void webLog() {
//
}

@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
startTime.set(System.currentTimeMillis());
}

@AfterReturning(value = "webLog()", returning = "ret")
public void doAfterReturning(Object ret) throws Throwable {
//
}

@Around("webLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
// Get current request object
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();

// Record request information
WebLog webLog = new WebLog();
Object result = joinPoint.proceed();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method.isAnnotationPresent(ApiOperation.class)) {
ApiOperation log = method.getAnnotation(ApiOperation.class);
webLog.setDescription(log.value());
}
long endTime = System.currentTimeMillis();
webLog.setBasePath(RequestUtil.getBasePath(request));
webLog.setIp(request.getRemoteUser());
webLog.setMethod(request.getMethod());
webLog.setParameter(getParameter(method, joinPoint.getArgs()));
webLog.setResult(result);
webLog.setSpendTime((int) (endTime - startTime.get()));
webLog.setStartTime(startTime.get());
webLog.setUri(request.getRequestURI());
webLog.setUrl(request.getRequestURL().toString());
Map<String, Object> logMap = new HashMap<>();
logMap.put("url", webLog.getUrl());
logMap.put("method", webLog.getMethod());
logMap.put("parameter", webLog.getParameter());
logMap.put("spendTime", webLog.getSpendTime());
logMap.put("description", webLog.getDescription());
log.info(Markers.appendEntries(logMap), JsonUtil.objectToJson(webLog));
return result;
}

/** Get parameters by HTTP method and input arguments */
private Object getParameter(Method method, Object[] args) {
List<Object> argList = new ArrayList<>();
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
if (requestBody != null) {
argList.add(args[i]);
}
RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
if (requestParam != null) {
Map<String, Object> map = new HashMap<>();
String key = parameters[i].getName();
if (!StringUtils.isEmpty(requestParam.value())) {
key = requestParam.value();
}
if (args[i] instanceof MultipartFile) {
map.put(key, ((MultipartFile) args[i]).getOriginalFilename());
} else {
map.put(key, args[i]);
}
argList.add(map);
}
}
if (argList.size() == 0) {
return null;
} else if (argList.size() == 1) {
return argList.get(0);
} else {
return argList;
}
}
}
56 changes: 56 additions & 0 deletions pro-proto/src/main/java/dr/sbs/proto/bo/UserInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package dr.sbs.proto.bo;

import dr.sbs.mbg.model.FrontUser;
import java.util.Arrays;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

public class UserInfo implements UserDetails {
private FrontUser user;

public UserInfo(FrontUser user) {
this.user = user;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// get current user's privileges
return Arrays.asList(new SimpleGrantedAuthority("NONE"));
}

@Override
public String getPassword() {
return user.getPassword();
}

@Override
public String getUsername() {
return user.getUsername();
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}

public FrontUser getUser() {
return user;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dr.sbs.proto.component;

import dr.sbs.common.CommonResult;
import dr.sbs.common.exception.ApiException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

// 全局异常处理
// 注:把这个文件复制到每项目的主包名下,才能生效
// 或者启动时设置 `@SpringBootApplication(scanBasePackages = {"dr.sbs"})`
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(value = ApiException.class)
public CommonResult handle(ApiException e) {
if (e.getErrorCode() != null) {
return CommonResult.failed(e.getErrorCode());
}
return CommonResult.failed(e.getMessage());
}
}
Loading

0 comments on commit 427433d

Please sign in to comment.