Commit 5b01dc64 authored by lihaipeng's avatar lihaipeng

add

parent 8c46b10a
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version> <version>2.3.0.RELEASE</version>
<relativePath/> <relativePath/>
</parent> </parent>
...@@ -57,17 +57,6 @@ ...@@ -57,17 +57,6 @@
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId> <artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
...@@ -83,13 +84,13 @@ ...@@ -83,13 +84,13 @@
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version> <version>5.1.49</version>
</dependency> </dependency>
<!-- fastjson --> <!-- RocketMQ配置 -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>fastjson</artifactId> <artifactId>rocketmq-spring-boot-starter</artifactId>
<version>1.2.68</version> <version>2.0.2</version>
</dependency> </dependency>
<!-- redis配置 --> <!-- Redis配置 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
...@@ -98,16 +99,18 @@ ...@@ -98,16 +99,18 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<!-- Fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
<!-- 动态配置监听 --> <!-- 动态配置监听 -->
<dependency> <dependency>
<groupId>com.purgeteam</groupId> <groupId>com.purgeteam</groupId>
<artifactId>dynamic-config-spring-boot-starter</artifactId> <artifactId>dynamic-config-spring-boot-starter</artifactId>
<version>0.1.0.RELEASE</version> <version>0.1.0.RELEASE</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
<!-- 测试相关 --> <!-- 测试相关 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
......
package com.unififi; package com.unififi;
import com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ApplicationContext;
@SpringBootApplication @SpringBootApplication
@EnableDiscoveryClient @EnableDiscoveryClient
@EnableFeignClients @EnableFeignClients
public class Demo1Application { public class Demo1Application {
private static final Logger logger = LoggerFactory.getLogger(Demo1Application.class);
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(Demo1Application.class, args); logger.info("Application starting...");
ApplicationContext ac = SpringApplication.run(Demo1Application.class, args);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
logger.info("Application ShutdownHook...");
NacosAutoServiceRegistration nacosAutoServiceRegistration = ac.getBean(NacosAutoServiceRegistration.class);
if (nacosAutoServiceRegistration != null) {
nacosAutoServiceRegistration.stop();
}
}
});
} }
} }
package com.unififi.config; package com.unififi.config;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@Configuration @Configuration
@RefreshScope
@ConfigurationProperties(ignoreInvalidFields = true, prefix = UnififiProperties.PREFIX) @ConfigurationProperties(ignoreInvalidFields = true, prefix = UnififiProperties.PREFIX)
public class UnififiProperties { public class UnififiProperties {
...@@ -14,6 +16,8 @@ public class UnififiProperties { ...@@ -14,6 +16,8 @@ public class UnififiProperties {
private Logger logger = new Logger(); private Logger logger = new Logger();
private Header header = new Header(); private Header header = new Header();
private String controllerPointcut = "execution(* com.*.controller.*.*(..))";
private String servicePointcut = "execution(* com.u2c.service..*.*(..))";
public Logger getLogger() { public Logger getLogger() {
return logger; return logger;
...@@ -31,6 +35,22 @@ public class UnififiProperties { ...@@ -31,6 +35,22 @@ public class UnififiProperties {
this.header = header; this.header = header;
} }
public String getControllerPointcut() {
return controllerPointcut;
}
public void setControllerPointcut(String controllerPointcut) {
this.controllerPointcut = controllerPointcut;
}
public String getServicePointcut() {
return servicePointcut;
}
public void setServicePointcut(String servicePointcut) {
this.servicePointcut = servicePointcut;
}
public static class Logger { public static class Logger {
private Setting feign = new Setting(); private Setting feign = new Setting();
private Setting rest = new Setting(); private Setting rest = new Setting();
......
package com.unififi.config.advice;
import com.unififi.config.UnififiProperties;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AdviceConfig {
@Bean
@ConditionalOnMissingBean(UnififiProperties.class)
UnififiProperties unififiProperties() {
return new UnififiProperties();
}
@Bean(value = "controllerLogAdvice")
public AspectJExpressionPointcutAdvisor controllerLogAdvice(UnififiProperties unififiProperties) {
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
advisor.setExpression(unififiProperties.getControllerPointcut());
advisor.setAdvice(new ControllerLogAdvice(unififiProperties));
return advisor;
}
@Bean(value = "serviceExceptionAdvice")
public AspectJExpressionPointcutAdvisor serviceExceptionAdvice(UnififiProperties unififiProperties) {
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
advisor.setExpression("execution(* com.*.service..*.*(..))");
advisor.setAdvice(new ServiceExceptionAdvice(unififiProperties));
return advisor;
}
}
package com.unififi.config.controller; package com.unififi.config.advice;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException;
......
package com.unififi.config.controller; package com.unififi.config.advice;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.unififi.config.UnififiProperties; import com.unififi.config.UnififiProperties;
import org.aspectj.lang.ProceedingJoinPoint; import org.aopalliance.intercept.MethodInterceptor;
import org.aspectj.lang.annotation.Around; import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
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;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Aspect public class ControllerLogAdvice implements MethodInterceptor {
@Component
public class ControllerLogAspect {
private final static Logger logger = LoggerFactory.getLogger("ControllerLog"); private final static Logger logger = LoggerFactory.getLogger("ControllerLog");
@Autowired
private UnififiProperties unififiProperties; private UnififiProperties unififiProperties;
@Pointcut("execution(* com.unififi.controller.*.*(..))") public ControllerLogAdvice(UnififiProperties unififiProperties) {
public void printLog() { this.unififiProperties = unififiProperties;
} }
@Around("printLog()") @Override
private Object doAround(ProceedingJoinPoint pjp) { public Object invoke(MethodInvocation invocation) throws Throwable {
String sortMethodName = getSortMethodName(invocation.getMethod());
try { try {
long start = System.nanoTime(); long start = System.nanoTime();
RequestAttributes ra = RequestContextHolder.getRequestAttributes(); RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest(); HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
String requestData = null; String requestData = null;
if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) { if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) {
requestData = JSONArray.toJSONString(pjp.getArgs()); requestData = JSONArray.toJSONString(invocation.getArguments());
} else if ("GET".equalsIgnoreCase(request.getMethod())) { } else if ("GET".equalsIgnoreCase(request.getMethod())) {
requestData = request.getQueryString(); requestData = request.getQueryString();
} }
if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) { if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(pjp.getSignature().toShortString())) { if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(sortMethodName)) {
logger.info("UNIFIFI-REQ-[{}] {}", pjp.getSignature().toShortString(), (requestData != null ? requestData : "")); logger.info("UNIFIFI-REQ-[{}] {}", sortMethodName, (requestData != null ? requestData : ""));
} }
} }
Object result = pjp.proceed(); Object result = invocation.proceed();
long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start); long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
String responseData = null; String responseData = null;
if (result != null) { if (result != null) {
responseData = JSON.toJSONString(result); responseData = JSON.toJSONString(result);
} }
if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) { if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(pjp.getSignature().toShortString())) { if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(sortMethodName)) {
if (unififiProperties.getLogger().getController().getIgnoreResponseDataMethodSigns().contains(pjp.getSignature().toShortString())) { if (unififiProperties.getLogger().getController().getIgnoreResponseDataMethodSigns().contains(sortMethodName)) {
logger.info("UNIFIFI-RESP-[{}] IGNORE_DATA size:{} spend:{}ms", pjp.getSignature().toShortString(), (responseData != null ? responseData.length() : 0), elapsedTime); logger.info("UNIFIFI-RESP-[{}] IGNORE_DATA size:{} spend:{}ms", sortMethodName, (responseData != null ? responseData.length() : 0), elapsedTime);
} else { } else {
logger.info("UNIFIFI-RESP-[{}] {} size:{} spend:{}ms", pjp.getSignature().toShortString(), (responseData != null ? responseData : ""), (responseData != null ? responseData.length() : 0), elapsedTime); logger.info("UNIFIFI-RESP-[{}] {} size:{} spend:{}ms", sortMethodName, (responseData != null ? responseData : ""), (responseData != null ? responseData.length() : 0), elapsedTime);
} }
} }
} }
return result; return result;
} catch (Throwable throwable) { } catch (Throwable throwable) {
if (logger.isErrorEnabled() && unififiProperties.getLogger().getController().isEnabled()) { if (logger.isErrorEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
logger.error("UNIFIFI-RESP-[{}] [{}]{}", pjp.getSignature().toShortString(), throwable.getClass().getSimpleName(), throwable.getMessage()); logger.error("UNIFIFI-RESP-[{}] [{}]{}", sortMethodName, throwable.getClass().getSimpleName(), throwable.getMessage());
} }
return throwable; return throwable;
} }
} }
private String getSortMethodName(Method method) {
StringBuilder sb = new StringBuilder();
appendType(sb, method.getDeclaringClass(), false);
sb.append(".");
sb.append(method.getName());
sb.append("(");
Class<?>[] parametersTypes = method.getParameterTypes();
appendTypes(sb, parametersTypes, false, false);
sb.append(")");
return sb.toString();
}
private void appendTypes(StringBuilder sb, Class<?>[] types, boolean includeArgs,
boolean useLongReturnAndArgumentTypeName) {
if (includeArgs) {
for (int size = types.length, i = 0; i < size; i++) {
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
if (i < size - 1) {
sb.append(",");
}
}
} else {
if (types.length != 0) {
sb.append("..");
}
}
}
private void appendType(StringBuilder sb, Class<?> type, boolean useLongTypeName) {
if (type.isArray()) {
appendType(sb, type.getComponentType(), useLongTypeName);
sb.append("[]");
} else {
sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
}
}
} }
package com.unififi.config.advice;
import com.unififi.config.UnififiProperties;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
public class ServiceExceptionAdvice implements MethodInterceptor {
private final static Logger logger = LoggerFactory.getLogger(ServiceExceptionAdvice.class);
private UnififiProperties unififiProperties;
public ServiceExceptionAdvice(UnififiProperties unififiProperties) {
this.unififiProperties = unififiProperties;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
return invocation.proceed();
} catch (Throwable throwable) {
logger.error("ServiceException: ", throwable);
Map map = new HashMap();
map.put("code", 500);
map.put("msg", "系统错误");
return map;
}
}
}
package com.unififi.config.controller; package com.unififi.config.converter;
import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.commons.codec.Charsets; import com.google.common.base.Charsets;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
......
...@@ -4,6 +4,7 @@ import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; ...@@ -4,6 +4,7 @@ import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.unififi.config.UnififiProperties; import com.unififi.config.UnififiProperties;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -23,6 +24,11 @@ import java.util.List; ...@@ -23,6 +24,11 @@ import java.util.List;
@Configuration @Configuration
public class RestTemplateConfig { public class RestTemplateConfig {
@Value("${ribbon.ConnectTimeout:5000}")
private Integer connectTimeout;
@Value("${ribbon.ReadTimeout:60000}")
private Integer readTimeout;
@Bean @Bean
@ConditionalOnMissingBean(UnififiProperties.class) @ConditionalOnMissingBean(UnififiProperties.class)
UnififiProperties loggerConfig() { UnififiProperties loggerConfig() {
...@@ -32,13 +38,12 @@ public class RestTemplateConfig { ...@@ -32,13 +38,12 @@ public class RestTemplateConfig {
@Bean @Bean
public ClientHttpRequestFactory httpRequestFactory(HttpClient httpClient) { public ClientHttpRequestFactory httpRequestFactory(HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
httpComponentsClientHttpRequestFactory.setConnectTimeout(5000); httpComponentsClientHttpRequestFactory.setConnectTimeout(this.connectTimeout);
httpComponentsClientHttpRequestFactory.setReadTimeout(60000); httpComponentsClientHttpRequestFactory.setReadTimeout(this.readTimeout);
return httpComponentsClientHttpRequestFactory; return httpComponentsClientHttpRequestFactory;
} }
@LoadBalanced @Bean(value = "restTemplate")
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory httpRequestFactory, UnififiProperties unififiProperties, FastJsonHttpMessageConverter fastJsonHttpMessageConverter) { public RestTemplate restTemplate(ClientHttpRequestFactory httpRequestFactory, UnififiProperties unififiProperties, FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory = new BufferingClientHttpRequestFactory(httpRequestFactory); BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory = new BufferingClientHttpRequestFactory(httpRequestFactory);
RestTemplate restTemplate = new RestTemplate(bufferingClientHttpRequestFactory); RestTemplate restTemplate = new RestTemplate(bufferingClientHttpRequestFactory);
...@@ -60,4 +65,28 @@ public class RestTemplateConfig { ...@@ -60,4 +65,28 @@ public class RestTemplateConfig {
messageConverters.add(fastJsonHttpMessageConverter); messageConverters.add(fastJsonHttpMessageConverter);
return restTemplate; return restTemplate;
} }
@LoadBalanced
@Bean(value = "restTemplateRibbon")
public RestTemplate restTemplateRibbon(ClientHttpRequestFactory httpRequestFactory, UnififiProperties unififiProperties, FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory = new BufferingClientHttpRequestFactory(httpRequestFactory);
RestTemplate restTemplate = new RestTemplate(bufferingClientHttpRequestFactory);
restTemplate.getInterceptors().add(new RestTemplateLogInterceptor(unififiProperties.getLogger().getRest()));
//fastjson 替换 jackson
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
while (iterator.hasNext()) {
HttpMessageConverter<?> converter = iterator.next();
if (converter instanceof StringHttpMessageConverter) {
iterator.remove();
}
if (converter instanceof GsonHttpMessageConverter || converter instanceof MappingJackson2HttpMessageConverter) {
iterator.remove();
}
}
messageConverters.add(new StringHttpMessageConverter(Charsets.UTF_8));
messageConverters.add(fastJsonHttpMessageConverter);
return restTemplate;
}
} }
...@@ -20,12 +20,14 @@ public class SwaggerConfig { ...@@ -20,12 +20,14 @@ public class SwaggerConfig {
@Value("${swagger.enable:false}") @Value("${swagger.enable:false}")
private Boolean enable; private Boolean enable;
@Value("${spring.cloud.nacos.discovery.metadata.unififi.service.version}") @Value("${spring.cloud.nacos.discovery.metadata.unififi.version}")
private String serviceVersion; private String serviceVersion;
@Value("${spring.application.name}") @Value("${spring.application.name}")
private String serviceName; private String serviceName;
private static final String basePackage = "com.unififi.controller";
@Bean @Bean
public Docket docket() { public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2) return new Docket(DocumentationType.SWAGGER_2)
...@@ -34,7 +36,7 @@ public class SwaggerConfig { ...@@ -34,7 +36,7 @@ public class SwaggerConfig {
.genericModelSubstitutes(Response.class) .genericModelSubstitutes(Response.class)
.forCodeGeneration(true) .forCodeGeneration(true)
.select() .select()
.apis(RequestHandlerSelectors.basePackage("com.unififi.controller")) .apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.any()) .paths(PathSelectors.any())
.build(); .build();
} }
......
...@@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*; ...@@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -29,6 +30,8 @@ public class Demo1Controller { ...@@ -29,6 +30,8 @@ public class Demo1Controller {
@Autowired @Autowired
private RestTemplate restTemplate; private RestTemplate restTemplate;
@Autowired @Autowired
private RestTemplate restTemplateRibbon;
@Autowired
private StringRedisTemplate stringRedisTemplate; private StringRedisTemplate stringRedisTemplate;
@Autowired @Autowired
private UserApi userApi; private UserApi userApi;
...@@ -51,14 +54,20 @@ public class Demo1Controller { ...@@ -51,14 +54,20 @@ public class Demo1Controller {
} }
@PostMapping(value = "/user/add", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/user/add", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public Boolean userAdd(@RequestBody User user) { public Boolean userAdd(@Valid @RequestBody User user) {
return userService.add(user); return userService.add(user);
} }
@GetMapping("/user/get") @GetMapping("/user/get")
public User userGet(@RequestParam("name") String name, @RequestParam("age") Integer age) { public User userGet(@RequestParam("name") String name, @RequestParam("age") Integer age) {
log.info("header. token:{}", request.getHeader("token")); log.info("header. token:{}", request.getHeader("token"));
return userApi.get(name, age); User user = null;
user = userApi.get(name, age);
// try {
// } catch (Exception e) {
// log.error("Exception:", e);
// }
return user;
} }
@GetMapping("/user/get/v2") @GetMapping("/user/get/v2")
...@@ -71,7 +80,7 @@ public class Demo1Controller { ...@@ -71,7 +80,7 @@ public class Demo1Controller {
public List<User> userList() { public List<User> userList() {
// return userApi.list(); // return userApi.list();
log.info("header. token:{}", request.getHeader("token")); log.info("header. token:{}", request.getHeader("token"));
return restTemplate.getForObject("http://unififi-demo2-service/user/list", List.class); return restTemplateRibbon.getForObject("http://unififi-demo2-service/user/list", List.class);
} }
@GetMapping("/config/username") @GetMapping("/config/username")
......
...@@ -8,7 +8,10 @@ server: ...@@ -8,7 +8,10 @@ server:
web: web:
exposure: exposure:
include: '*' include: '*'
shutdown: graceful
spring: spring:
lifecycle:
timeout-per-shutdown-phase: 60s
profiles: profiles:
active: dev active: dev
application: application:
...@@ -37,11 +40,18 @@ spring: ...@@ -37,11 +40,18 @@ spring:
discovery: discovery:
#ip: 39.106.6.97 #ip: 39.106.6.97
metadata: metadata:
unififi.mode: ${unififi.mode:}
unififi.env: ${spring.profiles.active:} unififi.env: ${spring.profiles.active:}
unififi.service.version: '@unififi-service.version@' unififi.version: '@unififi-service.version@'
user.home: ${user.home} user.home: ${user.home}
# 测试时使用配置服务列表 # 测试时使用配置服务列表
#unififi-demo2-service: #unififi-demo2-service:
# ribbon: # ribbon:
# NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList # NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
# listOfServers: 39.106.6.97:18080 # listOfServers: 39.106.6.97:18080
\ No newline at end of file unififi:
#controller-pointcut: 'execution(* com.*.controller.*.*(..))'
swagger:
enable: true
\ No newline at end of file
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId> <artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
...@@ -74,8 +75,13 @@ ...@@ -74,8 +75,13 @@
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version> <version>5.1.49</version>
</dependency> </dependency>
<!-- RocketMQ配置 -->
<!-- redis配置 --> <dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<!-- Redis配置 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
...@@ -84,16 +90,12 @@ ...@@ -84,16 +90,12 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<!-- Fastjson -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>
<version>1.2.68</version> <version>1.2.68</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
......
...@@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j; ...@@ -4,6 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap; import java.util.HashMap;
...@@ -15,7 +16,7 @@ import java.util.Map; ...@@ -15,7 +16,7 @@ import java.util.Map;
@Slf4j @Slf4j
@RestControllerAdvice @RestControllerAdvice
public class ControllerExceptionHandler { public class ControllerExceptionHandler {
@ResponseBody
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public Map handleException(Exception e) { public Map handleException(Exception e) {
Map map = new HashMap(); Map map = new HashMap();
...@@ -25,6 +26,7 @@ public class ControllerExceptionHandler { ...@@ -25,6 +26,7 @@ public class ControllerExceptionHandler {
return map; return map;
} }
@ResponseBody
@ExceptionHandler(HttpRequestMethodNotSupportedException.class) @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Map handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { public Map handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
Map map = new HashMap(); Map map = new HashMap();
...@@ -34,6 +36,7 @@ public class ControllerExceptionHandler { ...@@ -34,6 +36,7 @@ public class ControllerExceptionHandler {
return map; return map;
} }
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class) @ExceptionHandler(MethodArgumentNotValidException.class)
public Map handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { public Map handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
Map map = new HashMap(); Map map = new HashMap();
......
package com.unififi.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
public class ControllerLogAdvice implements MethodInterceptor {
private final static Logger logger = LoggerFactory.getLogger("ControllerLog");
private UnififiProperties unififiProperties;
public ControllerLogAdvice(UnififiProperties unififiProperties) {
this.unififiProperties = unififiProperties;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String sortMethodName = getSortMethodName(invocation.getMethod());
try {
long start = System.nanoTime();
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
String requestData = null;
if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) {
requestData = JSONArray.toJSONString(invocation.getArguments());
} else if ("GET".equalsIgnoreCase(request.getMethod())) {
requestData = request.getQueryString();
}
if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(sortMethodName)) {
logger.info("UNIFIFI-REQ-[{}] {}", sortMethodName, (requestData != null ? requestData : ""));
}
}
Object result = invocation.proceed();
long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
String responseData = null;
if (result != null) {
responseData = JSON.toJSONString(result);
}
if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(sortMethodName)) {
if (unififiProperties.getLogger().getController().getIgnoreResponseDataMethodSigns().contains(sortMethodName)) {
logger.info("UNIFIFI-RESP-[{}] IGNORE_DATA size:{} spend:{}ms", sortMethodName, (responseData != null ? responseData.length() : 0), elapsedTime);
} else {
logger.info("UNIFIFI-RESP-[{}] {} size:{} spend:{}ms", sortMethodName, (responseData != null ? responseData : ""), (responseData != null ? responseData.length() : 0), elapsedTime);
}
}
}
return result;
} catch (Throwable throwable) {
if (logger.isErrorEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
logger.error("UNIFIFI-RESP-[{}] [{}]{}", sortMethodName, throwable.getClass().getSimpleName(), throwable.getMessage());
}
return throwable;
}
}
private String getSortMethodName(Method method) {
StringBuilder sb = new StringBuilder();
appendType(sb, method.getDeclaringClass(), false);
sb.append(".");
sb.append(method.getName());
sb.append("(");
Class<?>[] parametersTypes = method.getParameterTypes();
appendTypes(sb, parametersTypes, false, false);
sb.append(")");
return sb.toString();
}
private void appendTypes(StringBuilder sb, Class<?>[] types, boolean includeArgs,
boolean useLongReturnAndArgumentTypeName) {
if (includeArgs) {
for (int size = types.length, i = 0; i < size; i++) {
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
if (i < size - 1) {
sb.append(",");
}
}
} else {
if (types.length != 0) {
sb.append("..");
}
}
}
private void appendType(StringBuilder sb, Class<?> type, boolean useLongTypeName) {
if (type.isArray()) {
appendType(sb, type.getComponentType(), useLongTypeName);
sb.append("[]");
} else {
sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
}
}
}
package com.unififi.config;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ControllerLogAdviceConfig {
@Value("${unififi.controller-pointcut:execution(* com.unififi.controller.*.*(..))}")
private String pointcut;
@Bean
@ConditionalOnMissingBean(UnififiProperties.class)
UnififiProperties unififiProperties() {
return new UnififiProperties();
}
@Bean
public AspectJExpressionPointcutAdvisor configurabledvisor(UnififiProperties unififiProperties) {
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
advisor.setExpression(pointcut);
advisor.setAdvice(new ControllerLogAdvice(unififiProperties));
return advisor;
}
}
package com.unififi.config;
import com.unififi.model.User;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ServiceExceptionAspect {
private final static Logger logger = LoggerFactory.getLogger("ServiceExceptionAspect");
@Pointcut("execution(* com.unififi.service..*.*(..))")
public void printLog() {
}
@Around("printLog()")
private Object doAround(ProceedingJoinPoint pjp) {
try {
return pjp.proceed();
} catch (Throwable throwable) {
logger.error("ServiceException:", throwable);
User u = new User();
u.setAge(-1);
u.setName(throwable.getMessage());
return u;
}
}
}
package com.unififi.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
@ConfigurationProperties(ignoreInvalidFields = true, prefix = UnififiProperties.PREFIX)
public class UnififiProperties {
public static final String PREFIX = "unififi";
private Logger logger = new Logger();
private Header header = new Header();
private String controllerPointcut = "";
public Logger getLogger() {
return logger;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}
public String getControllerPointcut() {
return controllerPointcut;
}
public void setControllerPointcut(String controllerPointcut) {
this.controllerPointcut = controllerPointcut;
}
public static class Logger {
private Setting feign = new Setting();
private Setting rest = new Setting();
private Setting controller = new Setting();
public Setting getFeign() {
return feign;
}
public void setFeign(Setting feign) {
this.feign = feign;
}
public Setting getRest() {
return rest;
}
public void setRest(Setting rest) {
this.rest = rest;
}
public Setting getController() {
return controller;
}
public void setController(Setting controller) {
this.controller = controller;
}
}
public static class Header {
private List<String> throughNames = new ArrayList<>();
public List<String> getThroughNames() {
return throughNames;
}
public void setThroughNames(List<String> throughNames) {
this.throughNames = throughNames;
}
}
public static class Setting {
private boolean enabled = true;
private List<String> ignoreResponseDataMethodSigns = new ArrayList<>();
private List<String> skipMethodSigns = new ArrayList<>();
private boolean showSpendms = false;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public List<String> getIgnoreResponseDataMethodSigns() {
return ignoreResponseDataMethodSigns;
}
public void setIgnoreResponseDataMethodSigns(List<String> ignoreResponseDataMethodSigns) {
this.ignoreResponseDataMethodSigns = ignoreResponseDataMethodSigns;
}
public List<String> getSkipMethodSigns() {
return skipMethodSigns;
}
public void setSkipMethodSigns(List<String> skipMethodSigns) {
this.skipMethodSigns = skipMethodSigns;
}
public boolean isShowSpendms() {
return showSpendms;
}
public void setShowSpendms(boolean showSpendms) {
this.showSpendms = showSpendms;
}
}
}
...@@ -13,6 +13,7 @@ import org.springframework.http.MediaType; ...@@ -13,6 +13,7 @@ import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
...@@ -36,7 +37,7 @@ public class Demo2Controller implements UserApi { ...@@ -36,7 +37,7 @@ public class Demo2Controller implements UserApi {
@Override @Override
@PostMapping(value = "/user/add", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/user/add", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public Boolean add(@RequestBody User user) { public Boolean add(@RequestBody @Valid User user) {
log.info("user/add. {}", JSON.toJSONString(user)); log.info("user/add. {}", JSON.toJSONString(user));
return userService.add(user); return userService.add(user);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment