新增测试包

master
lsw 3 years ago
parent 9bf8a2ba46
commit e5319c46c2

@ -18,7 +18,7 @@
<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.2.RELEASE</spring-boot.version>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>

@ -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,85 @@
package com.djy.module_test.config.druid;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.sql.DataSource;
import java.sql.SQLException;
@EnableConfigurationProperties(DruidDataSourceProperties.class)
public class DruidConfig {
@Resource
private DruidDataSourceProperties properties;
@Bean
public DataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(properties.getDriverClassName());
druidDataSource.setUrl(properties.getUrl());
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setInitialSize(properties.getInitialSize());
druidDataSource.setMinIdle(properties.getMinIdle());
druidDataSource.setMaxActive(properties.getMaxActive());
druidDataSource.setMaxWait(properties.getMaxWait());
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
druidDataSource.setValidationQuery(properties.getValidationQuery());
druidDataSource.setTestWhileIdle(properties.isTestWhileIdle());
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(properties.getMaxPoolPreparedStatementPerConnectionSize());
try {
druidDataSource.setFilters(properties.getFilters());
druidDataSource.init();
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
@Bean
@ConditionalOnMissingBean
public ServletRegistrationBean<Servlet> druidServlet() {
ServletRegistrationBean<Servlet> servletRegistrationBean = new ServletRegistrationBean<Servlet>(new StatViewServlet(), "/druid/*");
//白名单:
servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
//IP黑名单 (存在共同时deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page.
// servletRegistrationBean.addInitParameter("deny","192.168.8.119");
//登录查看信息的账号密码, 用于登录Druid监控后台
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "admin");
//是否能够重置数据.
servletRegistrationBean.addInitParameter("resetEnable", "true");
return servletRegistrationBean;
}
/**
* Filter,
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public FilterRegistrationBean<Filter> filterRegistrationBean() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<Filter>();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}

@ -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,19 @@
package com.djy.module_test.config.filter;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@SpringBootConfiguration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 匹配了所有的URL
.allowedHeaders("*") // 允许跨域请求包含任意的头信息
.allowedMethods("*") // 设置允许的方法
.allowedOrigins("http://*.griffie.club")
.allowCredentials(true); // 是否允许证书默认false
}
}

@ -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,52 @@
package com.djy.module_test.config.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 线 线
*
* @author guanyong.wang
* @version V1.0
* @Title: WhiteUrls.java
* @Package com.gavin.crim.constant
* '
* @date 202066
*/
public class WhiteUrls {
public static List<String> urlList = new ArrayList<String>();
public static WhiteUrls whiteUrls;
private WhiteUrls() {
}
public static WhiteUrls getWhiteUrls() {
if (whiteUrls == null) {
whiteUrls = new WhiteUrls();
urlList.add("/swagger-ui.html");
urlList.add("/swagger-resources");
urlList.add("/v2/api-docs");
urlList.add("/api/user/*");
urlList.add("/webjars/springfox-swagger-ui");
}
return whiteUrls;
}
public Boolean checkWhiteUtl(String url) {
for (String whiteurl : WhiteUrls.urlList) {
Pattern p = Pattern.compile("^" + whiteurl);
Matcher m = p.matcher(url);
if (m.find()) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
}

@ -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,125 @@
package com.djy.module_test.config.filter;
import com.djy.module_test.config.utils.JsoupUtil;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
HttpServletRequest orgRequest = null;
private boolean isIncludeRichText = false;
public XssHttpServletRequestWrapper(HttpServletRequest request, boolean isIncludeRichText) {
super(request);
orgRequest = request;
this.isIncludeRichText = isIncludeRichText;
}
/**
* getParameterxss<br/>
* super.getParameterValues(name)<br/>
* getParameterNames,getParameterValuesgetParameterMap
*/
@Override
public String getParameter(String name) {
Boolean flag = ("content".equals(name) || name.endsWith("WithHtml"));
if (flag && !isIncludeRichText) {
return super.getParameter(name);
}
name = JsoupUtil.clean(name);
String value = super.getParameter(name);
if (StringUtils.isNotBlank(value)) {
value = JsoupUtil.clean(value);
}
return cleanXSS(value);
}
@Override
public String[] getParameterValues(String name) {
String[] arr = super.getParameterValues(name);
if (arr != null) {
for (int i = 0; i < arr.length; i++) {
arr[i] = JsoupUtil.clean(arr[i]);
arr[i] = cleanXSS(arr[i]);
}
}
return arr;
}
/**
* getHeaderxss<br/>
* super.getHeaders(name)<br/>
* getHeaderNames
*/
@Override
public String getHeader(String name) {
name = JsoupUtil.clean(name);
String value = super.getHeader(name);
if (StringUtils.isNotBlank(value)) {
value = JsoupUtil.clean(value);
}
return cleanXSS(value);
}
/**
* request
*
* @return
*/
public HttpServletRequest getOrgRequest() {
return orgRequest;
}
/**
* request
*
* @return
*/
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
if (req instanceof XssHttpServletRequestWrapper) {
return ((XssHttpServletRequestWrapper) req).getOrgRequest();
}
return req;
}
private String cleanXSS(String value) {
if (value == null || value.trim().equals("")) {
return value;
}
// replace sql 这里可以自由发挥
String[] values = value.split(" ");
String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|%|chr|mid|master|truncate|" +
"char|declare|sitename|net center|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
"table|from|grant|use|group_concat|column_name|" +
"information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|" +
"chr|mid|master|truncate|char|declare|or|;|-|--|,|like|//|/|%|#";
String[] badStrs = badStr.split("\\|");
for (int i = 0; i < badStrs.length; i++) {
for (int j = 0; j < values.length; j++) {
if (values[j].equalsIgnoreCase(badStrs[i])) {
values[j] = "forbid";
}
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
if (i == values.length - 1) {
sb.append(values[i]);
} else {
sb.append(values[i] + " ");
}
}
value = sb.toString();
return value;
}
}

@ -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
* ahref,imgsrc,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,90 @@
server:
port: 10010
servlet:
context-path: /module_test
datacenterId: 2
workId: 2
spring:
application:
name: module_test
schedule.beOpen: false
cloud:
nacos:
discovery:
server-addr: 123.234.225.158:38848
username: nacos #用户名密码
password: Ds20040201
datasource:
name: druidDataSource
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://123.234.225.158:28010/project?useUnicode=true&serverTimezone=Asia/Shanghai&autoReconnect=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123qwe
filters: stat,wall,slf4j,config
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
conditionDoubleConstAllow: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
redis:
database: 0 # Redis数据库索引默认为0
host: 82.156.175.47 # Redis服务器地址
port: 6370 # Redis服务器连接端口
password: Lsw@0516 # Redis服务器连接密码默认为空
lettuce:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制)
max-wait: 2 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
logging:
level:
root: info
natsume:
aop:
log: true
mybatis:
mapper-locations:
- classpath*:**/*Mapper.xml # 配置 Mapper XML 地址
- classpath*:**/sqlmapper/*.xml # 配置 Mapper XML 地址
type-aliases-package: com.djy.project.**.model # 配置数据库实体包路径
configuration:
map-underscore-to-camel-case: true
# PageHelper分页插件
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
springdoc:
api-docs:
enabled: true
resolve-schema-properties: true
groups:
enabled: true
swagger-ui:
config-url:
path: /swagger-ui.html
display-request-duration: true
groups-order: DESC
operationsSorter: method
disable-swagger-default-url: true
group-configs:
- group: all
packages-to-scan: com.djy.module_test

@ -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() {
}
}

@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
@ -21,7 +21,7 @@
<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.2.RELEASE</spring-boot.version>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
@ -54,5 +54,6 @@
<modules>
<module>core</module>
<module>module_test</module>
</modules>
</project>

Loading…
Cancel
Save