新增测试包
parent
9bf8a2ba46
commit
e5319c46c2
@ -0,0 +1,47 @@
|
||||
package com.djy.core.aop;
|
||||
|
||||
import com.djy.core.aop.annotation.CostTime;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
|
||||
/**
|
||||
* 耗时切面
|
||||
*/
|
||||
|
||||
@Aspect
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "program.aop", name = "cost", havingValue = "true")
|
||||
public class CostTimeAspect {
|
||||
|
||||
@Pointcut(value = "@annotation(costTime)")
|
||||
public void timePointCut(CostTime costTime) {
|
||||
|
||||
}
|
||||
|
||||
@Around(value = "timePointCut(costTime)")
|
||||
public Object arroundAnnocation(ProceedingJoinPoint joinPoint, CostTime costTime) throws Throwable {
|
||||
Object o = null;
|
||||
try {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
o = joinPoint.proceed();
|
||||
stopWatch.stop();
|
||||
if (stopWatch.getLastTaskTimeMillis() > 1000) {
|
||||
log.error("方法:" + signature.getMethod().getName() + "耗时:" + stopWatch.getLastTaskTimeMillis());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.debug("可被使用的异常:{}", ex.getMessage());
|
||||
}
|
||||
return o;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.djy.core.aop;
|
||||
|
||||
import com.djy.core.exception.ServiceException;
|
||||
import com.djy.core.http.HttpResult;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class ExceptionAspect {
|
||||
|
||||
@ResponseBody
|
||||
@ExceptionHandler(value = ServiceException.class)
|
||||
public Object javaNatExceptionHandler(ServiceException ex) {
|
||||
log.debug("javaNatExceptionHandler" + ex.getDescription());
|
||||
return HttpResult.error(ex.getCode(), ex.getDescription());
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@ExceptionHandler(value = NullPointerException.class)
|
||||
public Object javaNpeHandler(NullPointerException ex) {
|
||||
log.error("javaExceptionHandler:", ex);
|
||||
return HttpResult.error(506, "系统开小差了~");
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@ExceptionHandler(value = Exception.class)
|
||||
public Object javaExceptionHandler(Exception ex) {
|
||||
log.error("javaExceptionHandler:" + ex.getLocalizedMessage());
|
||||
return HttpResult.error(506, "系统开小差了~");
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.djy.core.aop.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.TYPE, ElementType.METHOD})
|
||||
public @interface CostTime {
|
||||
|
||||
String value() default "";
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
package com.djy.core.aop.annotation;
|
||||
|
||||
import com.djy.core.http.HttpResult;
|
||||
import com.djy.core.resolver.annotation.CurrentUser;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "natsume.aop", name = "log", havingValue = "true")
|
||||
public class WebLogAspect {
|
||||
|
||||
@Pointcut("execution( * com.djy.*.controller..*.*(..))") // 两个..代表所有子目录,最后括号里的两个..代表所有参数
|
||||
public void commonApi() {
|
||||
}
|
||||
|
||||
@Pointcut("execution( * com.djy..module_test..*Controller.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
|
||||
public void centerApi() {
|
||||
}
|
||||
|
||||
// @Pointcut("execution( * com.djy..module_test.controller.*Controller.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
|
||||
// public void articleApi() {
|
||||
// }
|
||||
|
||||
@Before("commonApi() || centerApi()")
|
||||
public void doBefore(JoinPoint joinPoint) throws Throwable {
|
||||
// 接收到请求,记录请求内容
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if (attributes == null)
|
||||
return;
|
||||
Class<?> clz = joinPoint.getSignature().getDeclaringType();
|
||||
WebLogIgnore webLogIgnore = clz.getDeclaredAnnotation(WebLogIgnore.class);
|
||||
if (webLogIgnore != null) {
|
||||
return;
|
||||
}
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
// 记录下请求内容
|
||||
log.info("请求地址----> : {} ", request.getRequestURL().toString());
|
||||
// 获取真实的ip地址
|
||||
log.info("CLASS_METHOD-------------> : {}.{} ", joinPoint.getSignature().getDeclaringTypeName(),
|
||||
joinPoint.getSignature().getName());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("参数 ----> : {}", Arrays.toString(joinPoint.getArgs()));
|
||||
MethodSignature methodSign = (MethodSignature) joinPoint.getSignature();
|
||||
// 输出参数
|
||||
Object[] objs = joinPoint.getArgs();
|
||||
String[] names = methodSign.getParameterNames();
|
||||
Class<?> targetCls = joinPoint.getTarget().getClass();
|
||||
Method targetMethod = targetCls.getDeclaredMethod(methodSign.getName(), methodSign.getParameterTypes());
|
||||
|
||||
Parameter[] parameters = targetMethod.getParameters();
|
||||
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
Object obj = objs[i];
|
||||
String name = names[i];
|
||||
if (obj == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("password".equals(name)) {
|
||||
log.debug("[param.{}] :{}", name, "******");
|
||||
continue;
|
||||
}
|
||||
|
||||
Parameter parameter = parameters[i];
|
||||
CurrentUser apiIgnore = parameter.getAnnotation(CurrentUser.class);
|
||||
if (apiIgnore != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj instanceof HttpServletRequest) {
|
||||
// skip
|
||||
} else if (obj instanceof HttpServletResponse) {
|
||||
// skip
|
||||
} else if (obj instanceof MultipartFile) {
|
||||
// skip
|
||||
} else {
|
||||
if (obj != null) {
|
||||
if (obj.getClass().getName().startsWith("com.carlos")) {
|
||||
log.debug("[param.{}] :{}", name, objectMapper.writeValueAsString(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AfterReturning(returning = "ret", pointcut = "commonApi() || centerApi()") // returning的值和doAfterReturning的参数名一致
|
||||
public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
|
||||
// 处理完请求,返回内容(返回值太复杂时,打印的是物理存储空间的地址)
|
||||
if (ret == null) {
|
||||
return;
|
||||
}
|
||||
Class<?> clz = joinPoint.getSignature().getDeclaringType();
|
||||
WebLogIgnore webLogIgnore = clz.getDeclaredAnnotation(WebLogIgnore.class);
|
||||
if (webLogIgnore != null) {
|
||||
return;
|
||||
}
|
||||
if (ret instanceof HttpResult) {
|
||||
HttpResult jresult = (HttpResult) ret;
|
||||
log.debug("[result] :{} {}", jresult.getCode(), jresult.getMsg());
|
||||
} else {
|
||||
log.debug("返回值 : " + ret.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Around("commonApi() || centerApi()")
|
||||
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||
long startTime = System.currentTimeMillis();
|
||||
Object ob = pjp.proceed();// ob 为方法的返回值
|
||||
long useTime = System.currentTimeMillis() - startTime;
|
||||
log.info("用时----> : {}接口用时{}", pjp.getSignature(), useTime);
|
||||
return ob;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.djy.core.aop.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 忽略日志
|
||||
*/
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface WebLogIgnore {
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.djy.core.aop.config;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@SpringBootConfiguration
|
||||
@ConfigurationProperties(prefix = "program.aop")
|
||||
public class AopConfig {
|
||||
|
||||
/**
|
||||
* 详细错误
|
||||
*/
|
||||
private boolean detailError = true;
|
||||
|
||||
public boolean isDetailError() {
|
||||
return detailError;
|
||||
}
|
||||
|
||||
public void setDetailError(boolean detailError) {
|
||||
this.detailError = detailError;
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<artifactId>java_parent</artifactId>
|
||||
<groupId>com.djy</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>module_test</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>module_test</name>
|
||||
<description>module_test</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
|
||||
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
|
||||
<springdoc.version>1.5.12</springdoc.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
<version>${spring-cloud-alibaba.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.djy</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- mysql -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<!-- druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.2.8</version>
|
||||
</dependency>
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.79</version>
|
||||
</dependency>
|
||||
<!-- Redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<!-- mybatis -->
|
||||
<dependency>
|
||||
<groupId>tk.mybatis</groupId>
|
||||
<artifactId>mapper-spring-boot-starter</artifactId>
|
||||
<version>2.1.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tk.mybatis</groupId>
|
||||
<artifactId>mapper</artifactId>
|
||||
<version>4.1.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<!-- pagehelper 分页插件 -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.14.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.0.1-jre</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<!--Nacos配置中心的依赖-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<!-- actuator是SpringBoot的健康检查与应用监控组件 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.3.7.RELEASE</version>
|
||||
<configuration>
|
||||
<mainClass>com.djy.module_test.ModuleTestApplication</mainClass>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>repackage</id>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
@ -0,0 +1,23 @@
|
||||
package com.djy.module_test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import tk.mybatis.spring.annotation.MapperScan;
|
||||
|
||||
@EnableAsync
|
||||
@MapperScan(basePackages = "com.djy.**.model")
|
||||
@ComponentScan("com.djy.**")
|
||||
@EnableScheduling
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class ModuleTestApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ModuleTestApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.djy.module_test.config.aysnc;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
@SpringBootConfiguration
|
||||
public class AsyncConfig {
|
||||
|
||||
@Bean(name = "threadPoolTaskExecutor-project")
|
||||
public ThreadPoolTaskExecutor getAsyncThreadPoolTaskExecutor() {
|
||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||
taskExecutor.setCorePoolSize(20);
|
||||
taskExecutor.setMaxPoolSize(100);
|
||||
taskExecutor.setQueueCapacity(2500);
|
||||
taskExecutor.setKeepAliveSeconds(200);
|
||||
taskExecutor.setThreadNamePrefix("Async-B-Service");
|
||||
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
taskExecutor.initialize();
|
||||
return taskExecutor;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.djy.module_test.config.druid;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid")
|
||||
public class DruidDataSourceProperties {
|
||||
|
||||
// jdbc
|
||||
private String driverClassName;
|
||||
private String url;
|
||||
private String username;
|
||||
private String password;
|
||||
// jdbc connection pool
|
||||
private int initialSize;
|
||||
private int minIdle;
|
||||
private int maxActive = 100;
|
||||
private long maxWait;
|
||||
private long timeBetweenEvictionRunsMillis;
|
||||
private long minEvictableIdleTimeMillis;
|
||||
private String validationQuery;
|
||||
private boolean testWhileIdle;
|
||||
private boolean testOnBorrow;
|
||||
private boolean testOnReturn;
|
||||
private boolean poolPreparedStatements;
|
||||
private int maxPoolPreparedStatementPerConnectionSize;
|
||||
// filter
|
||||
private String filters;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.djy.module_test.config.filter;
|
||||
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
//@Configuration
|
||||
public class FilterConfiguration {
|
||||
@Bean
|
||||
public FilterRegistrationBean<SecFilter> registCrimSecuFilter() {
|
||||
//通过FilterRegistrationBean实例设置优先级可以生效
|
||||
//通过@WebFilter无效
|
||||
FilterRegistrationBean<SecFilter> bean = new FilterRegistrationBean<>();
|
||||
bean.setFilter(new SecFilter());//注册自定义过滤器
|
||||
bean.setName("SecFilter");//过滤器名称
|
||||
bean.addUrlPatterns("/*");//过滤所有路径
|
||||
bean.setOrder(1);//优先级,越低越优先
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<TokenFilter> registTokenFilter() {
|
||||
//通过FilterRegistrationBean实例设置优先级可以生效
|
||||
//通过@WebFilter无效
|
||||
FilterRegistrationBean<TokenFilter> bean = new FilterRegistrationBean<TokenFilter>();
|
||||
bean.setFilter(new TokenFilter());//注册自定义过滤器
|
||||
bean.setName("TokenFilter");//过滤器名称
|
||||
bean.addUrlPatterns("/*");//过滤所有路径
|
||||
bean.setOrder(2);//优先级,越低越优先
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* xss过滤拦截器
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean<XssFilter> registXssFilter() {
|
||||
FilterRegistrationBean<XssFilter> bean = new FilterRegistrationBean<XssFilter>();
|
||||
bean.setFilter(new XssFilter());
|
||||
bean.setOrder(3);
|
||||
bean.setName("xssFilter");
|
||||
bean.addUrlPatterns("/*");
|
||||
Map<String, String> initParameters = Maps.newHashMap();
|
||||
initParameters.put("excludes", "/favicon.ico,/img/*,/js/*,/css/*");
|
||||
initParameters.put("isIncludeRichText", "true");
|
||||
bean.setInitParameters(initParameters);
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.djy.module_test.config.filter;
|
||||
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@SpringBootConfiguration
|
||||
public class MyConfiguration {
|
||||
|
||||
@Bean
|
||||
public WebMvcConfigurer corsConfigurer() {
|
||||
return new WebMvcConfigurer() {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedOrigins("*").allowCredentials(true)
|
||||
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH").maxAge(3600);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.djy.module_test.config.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
public class SecFilter implements Filter {
|
||||
|
||||
WhiteUrls whiteUtils;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) {
|
||||
whiteUtils = WhiteUrls.getWhiteUrls();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
|
||||
|
||||
if (whiteUtils.checkWhiteUtl(req.getRequestURI())) {
|
||||
chain.doFilter(req, resp);
|
||||
return;
|
||||
}
|
||||
|
||||
String signarature = req.getHeader("sign");
|
||||
String appid = req.getHeader("appid");
|
||||
if (signarature == null || signarature.trim().equals("")) {
|
||||
return;
|
||||
}
|
||||
if (appid == null || appid.trim().equals("")) {
|
||||
return;
|
||||
}
|
||||
chain.doFilter(req, resp);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.djy.module_test.config.filter;
|
||||
|
||||
import com.djy.core.resolver.vo.UserBean;
|
||||
import com.djy.core.utils.JwtHelper;
|
||||
import org.springframework.boot.configurationprocessor.json.JSONObject;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class TokenFilter implements Filter {
|
||||
|
||||
WhiteUrls whiteUtils;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
filterConfig.getServletContext();
|
||||
whiteUtils = WhiteUrls.getWhiteUrls();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
try {
|
||||
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
if (whiteUtils.checkWhiteUtl(req.getRequestURI())) {
|
||||
chain.doFilter(req, resp);
|
||||
return;
|
||||
}
|
||||
String token = JwtHelper.getToken(req);
|
||||
if (StringUtils.isEmpty(token)) {
|
||||
this.errMsg(req, resp, "token不能为空");
|
||||
return;
|
||||
}
|
||||
UserBean userBean = JwtHelper.verifyTokenAndGetUserBean(token);
|
||||
if (userBean == null) {
|
||||
this.errMsg(req, resp, "非法请求");
|
||||
return;
|
||||
}
|
||||
chain.doFilter(req, resp);
|
||||
} catch (Throwable e) {
|
||||
// throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void errMsg(HttpServletRequest req, HttpServletResponse resp, String msg) throws Exception {
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.setContentType("application/json; charset=utf-8");
|
||||
PrintWriter out = resp.getWriter();
|
||||
JSONObject res = new JSONObject();
|
||||
res.put("msg", msg);
|
||||
resp.setStatus(401);
|
||||
out.append(res.toString());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.djy.module_test.config.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 拦截防止xss注入
|
||||
* 通过Jsoup过滤请求参数内的特定字符
|
||||
*/
|
||||
@Slf4j
|
||||
public class XssFilter implements Filter {
|
||||
|
||||
/**
|
||||
* 是否过滤富文本内容
|
||||
*/
|
||||
private static boolean IS_INCLUDE_RICH_TEXT = false;
|
||||
|
||||
public List<String> excludes = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
log.info("xss filter 成功启动");
|
||||
String isIncludeRichText = filterConfig.getInitParameter("isIncludeRichText");
|
||||
if (StringUtils.isNotBlank(isIncludeRichText)) {
|
||||
IS_INCLUDE_RICH_TEXT = BooleanUtils.toBoolean(isIncludeRichText);
|
||||
}
|
||||
|
||||
String temp = filterConfig.getInitParameter("excludes");
|
||||
if (temp != null) {
|
||||
String[] url = temp.split(",");
|
||||
excludes.addAll(Arrays.asList(url));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
if (handleExcludeURL(req, resp)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request, IS_INCLUDE_RICH_TEXT);
|
||||
filterChain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
if (excludes == null || excludes.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String url = request.getServletPath();
|
||||
for (String pattern : excludes) {
|
||||
Pattern p = Pattern.compile("^" + pattern);
|
||||
Matcher m = p.matcher(url);
|
||||
if (m.find()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.djy.module_test.config.schedule;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@EnableScheduling
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "schedule", name = "beOpen", havingValue = "true")
|
||||
public class Schedule {
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.djy.module_test.config.utils;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.safety.Whitelist;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* xss非法标签过滤
|
||||
*/
|
||||
public class JsoupUtil {
|
||||
|
||||
/**
|
||||
* 使用自带的basicWithImages 白名单
|
||||
* 允许的便签有a,b,blockquote,br,cite,code,dd,dl,dt,em,i,li,ol,p,pre,q,small,span,
|
||||
* strike,strong,sub,sup,u,ul,img
|
||||
* 以及a标签的href,img标签的src,align,alt,height,width,title属性
|
||||
*/
|
||||
private static final Whitelist whitelist = Whitelist.none();
|
||||
/**
|
||||
* 配置过滤化参数,不对代码进行格式化
|
||||
*/
|
||||
private static final Document.OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false);
|
||||
|
||||
static {
|
||||
// 富文本编辑时一些样式是使用style来进行实现的
|
||||
// 比如红色字体 style="color:red;"
|
||||
// 所以需要给所有标签添加style属性
|
||||
whitelist.addAttributes(":all", "style");
|
||||
}
|
||||
|
||||
public static String clean(String content) {
|
||||
return Jsoup.clean(content, "", whitelist, outputSettings);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException, IOException {
|
||||
String text = "<a href=\"http://www.baidu.com/a\" onclick=\"alert(1);\">sss</a><script>alert(0);</script>sss";
|
||||
System.out.println(clean(text));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.djy.module_test.config.web;
|
||||
|
||||
|
||||
import com.djy.core.resolver.resolver.CurrentUserIdMethodArgResolver;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootConfiguration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
|
||||
|
||||
resolvers.add(currentResolver());
|
||||
WebMvcConfigurer.super.addArgumentResolvers(resolvers);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CurrentUserIdMethodArgResolver currentResolver() {
|
||||
return new CurrentUserIdMethodArgResolver();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.djy.module_test.user.controller;
|
||||
|
||||
import com.djy.core.http.HttpResult;
|
||||
import com.djy.core.resolver.annotation.CurrentUser;
|
||||
import com.djy.core.resolver.vo.UserBean;
|
||||
import com.djy.module_test.user.model.User;
|
||||
import com.djy.module_test.user.service.UserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
@Tag(name = "UserController",description = "测试用户Controller")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Operation(description = "查看所有用户列表")
|
||||
@GetMapping("list")
|
||||
public HttpResult<List<User>> userList() {
|
||||
return HttpResult.ok(this.userService.userList());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.djy.module_test.user.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class User {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.djy.module_test.user.model.mapper;
|
||||
|
||||
import com.djy.core.cmapper.CommonMapper;
|
||||
import com.djy.module_test.user.model.User;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserMapper extends CommonMapper<User> {
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.djy.module_test.user.service;
|
||||
|
||||
|
||||
import com.djy.module_test.user.model.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserService {
|
||||
|
||||
/**
|
||||
* 查看用户列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<User> userList();
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.djy.module_test.user.service.impl;
|
||||
|
||||
import com.djy.module_test.user.model.User;
|
||||
import com.djy.module_test.user.model.mapper.UserMapper;
|
||||
import com.djy.module_test.user.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public List<User> userList() {
|
||||
return this.userMapper.selectAll();
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
spring:
|
||||
application:
|
||||
name: module_test
|
||||
profiles:
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
server-addr: 82.156.175.47:8848
|
||||
username: nacos
|
||||
password: nacos
|
||||
file-extension: yml
|
||||
shared-configs:
|
||||
- data-id: common-${spring.profiles.active}.yml
|
||||
group: DEFAULT_GROUP
|
||||
refresh: true #代表是否允许自动刷新
|
||||
enabled: false
|
@ -0,0 +1,13 @@
|
||||
package com.djy.module_test;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class ModuleTestApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue