mirror of
https://github.com/chillzhuang/blade-tool
synced 2024-12-12 04:09:28 +08:00
🎉 2.6.0.RELEASE 升级Hoxton.SR1 适配最新架构
This commit is contained in:
parent
457ab4088f
commit
181063c231
@ -1,7 +1,7 @@
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/license-LGPL%20v3-blue.svg" alt="Build Status">
|
||||
<img src="https://img.shields.io/badge/Spring%20Cloud-Greenwich.SR3-blue.svg" alt="Coverage Status">
|
||||
<img src="https://img.shields.io/badge/Spring%20Boot-2.1.9.RELEASE-blue.svg" alt="Downloads">
|
||||
<img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR1-blue.svg" alt="Coverage Status">
|
||||
<img src="https://img.shields.io/badge/Spring%20Boot-2.2.2.RELEASE-blue.svg" alt="Downloads">
|
||||
</p>
|
||||
|
||||
## SpringBlade微服务开发平台
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -62,28 +62,6 @@
|
||||
<artifactId>blade-core-swagger</artifactId>
|
||||
<version>${blade.tool.version}</version>
|
||||
</dependency>
|
||||
<!--Swagger-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
<version>${swagger.models.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>swagger-bootstrap-ui</artifactId>
|
||||
<version>${swagger.bootstrapui.version}</version>
|
||||
</dependency>
|
||||
<!--Redis-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -16,13 +16,12 @@
|
||||
package org.springblade.core.boot.config;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springblade.core.launch.constant.AppConstant;
|
||||
import org.springblade.core.mp.plugins.SqlLogInterceptor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/**
|
||||
* mybatisplus 配置
|
||||
@ -40,14 +39,12 @@ public class MybatisPlusConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL执行效率插件
|
||||
*
|
||||
* @return PerformanceInterceptor
|
||||
* sql 日志
|
||||
*/
|
||||
@Bean
|
||||
@Profile({AppConstant.DEV_CODE, AppConstant.TEST_CODE})
|
||||
public PerformanceInterceptor performanceInterceptor() {
|
||||
return new PerformanceInterceptor();
|
||||
@ConditionalOnProperty(value = "blade.mybatis-plus.sql-log.enable", matchIfMissing = true)
|
||||
public SqlLogInterceptor sqlLogInterceptor() {
|
||||
return new SqlLogInterceptor();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class BladeTenantHandler implements TenantHandler {
|
||||
* @return 租户ID
|
||||
*/
|
||||
@Override
|
||||
public Expression getTenantId() {
|
||||
public Expression getTenantId(boolean where) {
|
||||
return new StringValue(Func.toStr(SecureUtil.getTenantId(), TenantConstant.DEFAULT_TENANT_ID));
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ mybatis-plus:
|
||||
swagger:
|
||||
title: SpringBlade 接口文档系统
|
||||
description: SpringBlade 接口文档系统
|
||||
version: 2.5.4
|
||||
version: 2.6.0
|
||||
license: Powered By SpringBlade
|
||||
licenseUrl: https://bladex.vip
|
||||
terms-of-service-url: https://bladex.vip
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -16,9 +16,9 @@
|
||||
package $!{package.Controller};
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import lombok.AllArgsConstructor;
|
||||
import javax.validation.Valid;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -25,7 +25,7 @@ public interface AppConstant {
|
||||
/**
|
||||
* 应用版本
|
||||
*/
|
||||
String APPLICATION_VERSION = "2.5.4";
|
||||
String APPLICATION_VERSION = "2.6.0";
|
||||
|
||||
/**
|
||||
* 基础包
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -32,7 +32,7 @@ public interface BaseService<T> extends IService<T> {
|
||||
* 逻辑删除
|
||||
*
|
||||
* @param ids id集合(逗号分隔)
|
||||
* @return
|
||||
* @return boolean
|
||||
*/
|
||||
boolean deleteLogic(@NotEmpty List<Integer> ids);
|
||||
|
||||
|
@ -24,8 +24,6 @@ import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -39,14 +37,6 @@ import java.util.List;
|
||||
@Validated
|
||||
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements BaseService<T> {
|
||||
|
||||
private Class<T> modelClass;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public BaseServiceImpl() {
|
||||
Type type = this.getClass().getGenericSuperclass();
|
||||
this.modelClass = (Class<T>) ((ParameterizedType) type).getActualTypeArguments()[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(T entity) {
|
||||
BladeUser user = SecureUtil.getUser();
|
||||
|
@ -18,6 +18,7 @@ package org.springblade.core.mp.base;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 租户基础实体类
|
||||
@ -25,6 +26,7 @@ import lombok.Data;
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class TenantEntity extends BaseEntity {
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,185 @@
|
||||
package org.springblade.core.mp.plugins;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.core.toolkit.SystemClock;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.executor.statement.StatementHandler;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.apache.ibatis.reflection.SystemMetaObject;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Statement;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 用于输出每条 SQL 语句及其执行时间
|
||||
*
|
||||
* @author hubin nieqiurong TaoYu
|
||||
* @since 2016-07-07
|
||||
*/
|
||||
@Slf4j
|
||||
@Intercepts({
|
||||
@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
|
||||
@Signature(type = StatementHandler.class, method = "update", args = Statement.class),
|
||||
@Signature(type = StatementHandler.class, method = "batch", args = Statement.class)
|
||||
})
|
||||
public class SqlLogInterceptor implements Interceptor {
|
||||
private static final String DRUID_POOLED_PREPARED_STATEMENT = "com.alibaba.druid.pool.DruidPooledPreparedStatement";
|
||||
private static final String T4C_PREPARED_STATEMENT = "oracle.jdbc.driver.T4CPreparedStatement";
|
||||
private static final String ORACLE_PREPARED_STATEMENT_WRAPPER = "oracle.jdbc.driver.OraclePreparedStatementWrapper";
|
||||
|
||||
private Method oracleGetOriginalSqlMethod;
|
||||
private Method druidGetSqlMethod;
|
||||
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
Statement statement;
|
||||
Object firstArg = invocation.getArgs()[0];
|
||||
if (Proxy.isProxyClass(firstArg.getClass())) {
|
||||
statement = (Statement) SystemMetaObject.forObject(firstArg).getValue("h.statement");
|
||||
} else {
|
||||
statement = (Statement) firstArg;
|
||||
}
|
||||
MetaObject stmtMetaObj = SystemMetaObject.forObject(statement);
|
||||
try {
|
||||
statement = (Statement) stmtMetaObj.getValue("stmt.statement");
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
if (stmtMetaObj.hasGetter("delegate")) {
|
||||
//Hikari
|
||||
try {
|
||||
statement = (Statement) stmtMetaObj.getValue("delegate");
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
String originalSql = null;
|
||||
String stmtClassName = statement.getClass().getName();
|
||||
if (DRUID_POOLED_PREPARED_STATEMENT.equals(stmtClassName)) {
|
||||
try {
|
||||
if (druidGetSqlMethod == null) {
|
||||
Class<?> clazz = Class.forName(DRUID_POOLED_PREPARED_STATEMENT);
|
||||
druidGetSqlMethod = clazz.getMethod("getSql");
|
||||
}
|
||||
Object stmtSql = druidGetSqlMethod.invoke(statement);
|
||||
if (stmtSql instanceof String) {
|
||||
originalSql = (String) stmtSql;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (T4C_PREPARED_STATEMENT.equals(stmtClassName)
|
||||
|| ORACLE_PREPARED_STATEMENT_WRAPPER.equals(stmtClassName)) {
|
||||
try {
|
||||
if (oracleGetOriginalSqlMethod != null) {
|
||||
Object stmtSql = oracleGetOriginalSqlMethod.invoke(statement);
|
||||
if (stmtSql instanceof String) {
|
||||
originalSql = (String) stmtSql;
|
||||
}
|
||||
} else {
|
||||
Class<?> clazz = Class.forName(stmtClassName);
|
||||
oracleGetOriginalSqlMethod = getMethodRegular(clazz, "getOriginalSql");
|
||||
if (oracleGetOriginalSqlMethod != null) {
|
||||
//OraclePreparedStatementWrapper is not a public class, need set this.
|
||||
oracleGetOriginalSqlMethod.setAccessible(true);
|
||||
if (null != oracleGetOriginalSqlMethod) {
|
||||
Object stmtSql = oracleGetOriginalSqlMethod.invoke(statement);
|
||||
if (stmtSql instanceof String) {
|
||||
originalSql = (String) stmtSql;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
if (originalSql == null) {
|
||||
originalSql = statement.toString();
|
||||
}
|
||||
originalSql = originalSql.replaceAll("[\\s]+", StringPool.SPACE);
|
||||
int index = indexOfSqlStart(originalSql);
|
||||
if (index > 0) {
|
||||
originalSql = originalSql.substring(index);
|
||||
}
|
||||
|
||||
// 计算执行 SQL 耗时
|
||||
long start = SystemClock.now();
|
||||
Object result = invocation.proceed();
|
||||
long timing = SystemClock.now() - start;
|
||||
|
||||
// SQL 打印执行结果
|
||||
Object target = PluginUtils.realTarget(invocation.getTarget());
|
||||
MetaObject metaObject = SystemMetaObject.forObject(target);
|
||||
MappedStatement ms = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
|
||||
// 打印 sql
|
||||
System.err.println(
|
||||
StringUtil.format(
|
||||
"\n============== Sql Start ==============" +
|
||||
"\nExecute ID :{}" +
|
||||
"\nExecute SQL :{}" +
|
||||
"\nExecute Time:{} ms" +
|
||||
"\n============== Sql End ==============\n",
|
||||
ms.getId(), originalSql, timing));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
if (target instanceof StatementHandler) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此方法名的具体 Method
|
||||
*
|
||||
* @param clazz class 对象
|
||||
* @param methodName 方法名
|
||||
* @return 方法
|
||||
*/
|
||||
private Method getMethodRegular(Class<?> clazz, String methodName) {
|
||||
if (Object.class.equals(clazz)) {
|
||||
return null;
|
||||
}
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
if (method.getName().equals(methodName)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
return getMethodRegular(clazz.getSuperclass(), methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sql语句开头部分
|
||||
*
|
||||
* @param sql ignore
|
||||
* @return ignore
|
||||
*/
|
||||
private int indexOfSqlStart(String sql) {
|
||||
String upperCaseSql = sql.toUpperCase();
|
||||
Set<Integer> set = new HashSet<>();
|
||||
set.add(upperCaseSql.indexOf("SELECT "));
|
||||
set.add(upperCaseSql.indexOf("UPDATE "));
|
||||
set.add(upperCaseSql.indexOf("INSERT "));
|
||||
set.add(upperCaseSql.indexOf("DELETE "));
|
||||
set.remove(-1);
|
||||
if (CollectionUtils.isEmpty(set)) {
|
||||
return -1;
|
||||
}
|
||||
List<Integer> list = new ArrayList<>(set);
|
||||
list.sort(Comparator.naturalOrder());
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
}
|
@ -30,15 +30,17 @@ public abstract class BaseEntityWrapper<E, V> {
|
||||
|
||||
/**
|
||||
* 单个实体类包装
|
||||
* @param entity
|
||||
* @return
|
||||
*
|
||||
* @param entity 实体类
|
||||
* @return V
|
||||
*/
|
||||
public abstract V entityVO(E entity);
|
||||
|
||||
/**
|
||||
* 实体类集合包装
|
||||
* @param list
|
||||
* @return
|
||||
*
|
||||
* @param list 猎豹
|
||||
* @return List V
|
||||
*/
|
||||
public List<V> listVO(List<E> list) {
|
||||
return list.stream().map(this::entityVO).collect(Collectors.toList());
|
||||
@ -46,8 +48,9 @@ public abstract class BaseEntityWrapper<E, V> {
|
||||
|
||||
/**
|
||||
* 分页实体类集合包装
|
||||
* @param pages
|
||||
* @return
|
||||
*
|
||||
* @param pages 分页
|
||||
* @return Page V
|
||||
*/
|
||||
public IPage<V> pageVO(IPage<E> pages) {
|
||||
List<V> records = listVO(pages.getRecords());
|
||||
|
@ -33,8 +33,8 @@ public class Condition {
|
||||
/**
|
||||
* 转化成mybatis plus中的Page
|
||||
*
|
||||
* @param query
|
||||
* @return
|
||||
* @param query 查询包装类
|
||||
* @return Page T
|
||||
*/
|
||||
public static <T> IPage<T> getPage(Query query) {
|
||||
Page<T> page = new Page<>(Func.toInt(query.getCurrent(), 1), Func.toInt(query.getSize(), 10));
|
||||
@ -46,9 +46,9 @@ public class Condition {
|
||||
/**
|
||||
* 获取mybatis plus中的QueryWrapper
|
||||
*
|
||||
* @param entity
|
||||
* @param <T>
|
||||
* @return
|
||||
* @param entity 实体类
|
||||
* @param <T> 泛型
|
||||
* @return QueryWrapper
|
||||
*/
|
||||
public static <T> QueryWrapper<T> getQueryWrapper(T entity) {
|
||||
return new QueryWrapper<>(entity);
|
||||
@ -57,10 +57,10 @@ public class Condition {
|
||||
/**
|
||||
* 获取mybatis plus中的QueryWrapper
|
||||
*
|
||||
* @param query
|
||||
* @param clazz
|
||||
* @param <T>
|
||||
* @return
|
||||
* @param query 查询包装类
|
||||
* @param clazz 实体类
|
||||
* @param <T> 泛型
|
||||
* @return QueryWrapper
|
||||
*/
|
||||
public static <T> QueryWrapper<T> getQueryWrapper(Map<String, Object> query, Class<T> clazz) {
|
||||
query.remove("current");
|
||||
|
@ -88,7 +88,7 @@ public class SqlKeyword {
|
||||
*
|
||||
* @param column 字段名
|
||||
* @param keyword 关键字
|
||||
* @return
|
||||
* @return String
|
||||
*/
|
||||
private static String getColumn(String column, String keyword) {
|
||||
return StringUtil.humpToUnderline(StringUtil.removeSuffix(column, keyword));
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -23,26 +23,10 @@
|
||||
<version>${blade.tool.version}</version>
|
||||
</dependency>
|
||||
<!--Swagger-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
<version>${swagger.models.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>swagger-bootstrap-ui</artifactId>
|
||||
<version>${swagger.bootstrapui.version}</version>
|
||||
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -16,14 +16,16 @@
|
||||
package org.springblade.core.swagger;
|
||||
|
||||
|
||||
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
|
||||
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.service.*;
|
||||
@ -42,10 +44,11 @@ import java.util.List;
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration
|
||||
@EnableKnife4j
|
||||
@EnableSwagger2
|
||||
@EnableSwaggerBootstrapUI
|
||||
@Profile({"dev", "test"})
|
||||
@EnableConfigurationProperties(SwaggerProperties.class)
|
||||
@Import(BeanValidatorPluginsConfiguration.class)
|
||||
public class SwaggerAutoConfiguration {
|
||||
|
||||
private static final String DEFAULT_EXCLUDE_PATH = "/error";
|
||||
|
@ -55,7 +55,7 @@ public class SwaggerProperties {
|
||||
/**
|
||||
* 版本
|
||||
**/
|
||||
private String version = "2.5.4";
|
||||
private String version = "2.6.0";
|
||||
/**
|
||||
* 许可证
|
||||
**/
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -16,9 +16,11 @@
|
||||
package org.springblade.core.tool.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.json.JsonReadFeature;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.jackson.BladeJavaTimeModule;
|
||||
import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
@ -40,6 +42,7 @@ import java.util.TimeZone;
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@ConditionalOnClass(ObjectMapper.class)
|
||||
@AutoConfigureBefore(JacksonAutoConfiguration.class)
|
||||
public class JacksonConfiguration {
|
||||
@ -59,8 +62,8 @@ public class JacksonConfiguration {
|
||||
//序列化时,日期的统一格式
|
||||
objectMapper.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, Locale.CHINA));
|
||||
//序列化处理
|
||||
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
|
||||
objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
|
||||
objectMapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
|
||||
objectMapper.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
|
||||
objectMapper.findAndRegisterModules();
|
||||
//失败处理
|
||||
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
|
@ -19,11 +19,7 @@ package org.springblade.core.tool.config;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.jackson.MappingApiJackson2HttpMessageConverter;
|
||||
import org.springblade.core.tool.support.xss.XssFilter;
|
||||
import org.springblade.core.tool.support.xss.XssProperties;
|
||||
import org.springblade.core.tool.utils.Charsets;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@ -31,7 +27,6 @@ import org.springframework.http.converter.*;
|
||||
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -46,8 +41,6 @@ public class MessageConfiguration implements WebMvcConfigurer {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private final XssProperties xssProperties;
|
||||
|
||||
/**
|
||||
* 使用 JACKSON 作为JSON MessageConverter
|
||||
*/
|
||||
@ -61,20 +54,4 @@ public class MessageConfiguration implements WebMvcConfigurer {
|
||||
converters.add(new MappingApiJackson2HttpMessageConverter(objectMapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 防XSS注入
|
||||
*
|
||||
* @return FilterRegistrationBean
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean xssFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
registration.setFilter(new XssFilter(xssProperties));
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setName("xssFilter");
|
||||
registration.setOrder(Ordered.LOWEST_PRECEDENCE);
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,9 +16,7 @@
|
||||
package org.springblade.core.tool.config;
|
||||
|
||||
|
||||
import org.springblade.core.tool.support.xss.XssProperties;
|
||||
import org.springblade.core.tool.utils.SpringUtil;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
@ -32,7 +30,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
*/
|
||||
@Configuration
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@EnableConfigurationProperties(XssProperties.class)
|
||||
public class ToolConfiguration implements WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.tool.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.support.xss.XssFilter;
|
||||
import org.springblade.core.tool.support.xss.XssProperties;
|
||||
import org.springblade.core.tool.support.xss.XssUrlProperties;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
/**
|
||||
* Xss配置类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@ConditionalOnProperty(value = "blade.xss.enable", havingValue = "true")
|
||||
@EnableConfigurationProperties({XssProperties.class, XssUrlProperties.class})
|
||||
public class XssConfiguration {
|
||||
|
||||
private final XssProperties xssProperties;
|
||||
private final XssUrlProperties xssUrlProperties;
|
||||
|
||||
/**
|
||||
* 防XSS注入
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean<XssFilter> xssFilterRegistration() {
|
||||
FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
registration.setFilter(new XssFilter(xssProperties, xssUrlProperties));
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setName("xssFilter");
|
||||
registration.setOrder(Ordered.LOWEST_PRECEDENCE);
|
||||
return registration;
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@ package org.springblade.core.tool.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.json.JsonReadFeature;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
@ -97,7 +98,7 @@ public class JsonUtil {
|
||||
* @param <T> T 泛型标记
|
||||
* @return Bean
|
||||
*/
|
||||
public static <T> T parse(String content, TypeReference<?> typeReference) {
|
||||
public static <T> T parse(String content, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return getInstance().readValue(content, typeReference);
|
||||
} catch (IOException e) {
|
||||
@ -130,7 +131,7 @@ public class JsonUtil {
|
||||
* @param <T> T 泛型标记
|
||||
* @return Bean
|
||||
*/
|
||||
public static <T> T parse(byte[] bytes, TypeReference<?> typeReference) {
|
||||
public static <T> T parse(byte[] bytes, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return getInstance().readValue(bytes, typeReference);
|
||||
} catch (IOException e) {
|
||||
@ -162,7 +163,7 @@ public class JsonUtil {
|
||||
* @param <T> T 泛型标记
|
||||
* @return Bean
|
||||
*/
|
||||
public static <T> T parse(InputStream in, TypeReference<?> typeReference) {
|
||||
public static <T> T parse(InputStream in, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return getInstance().readValue(in, typeReference);
|
||||
} catch (IOException e) {
|
||||
@ -184,7 +185,7 @@ public class JsonUtil {
|
||||
content = StringPool.LEFT_SQ_BRACKET + content + StringPool.RIGHT_SQ_BRACKET;
|
||||
}
|
||||
|
||||
List<Map<String, Object>> list = getInstance().readValue(content, new TypeReference<List<T>>() {
|
||||
List<Map<String, Object>> list = getInstance().readValue(content, new TypeReference<List<Map<String, Object>>>() {
|
||||
});
|
||||
List<T> result = new ArrayList<>();
|
||||
for (Map<String, Object> map : list) {
|
||||
@ -208,7 +209,7 @@ public class JsonUtil {
|
||||
|
||||
public static <T> Map<String, T> toMap(String content, Class<T> valueTypeRef) {
|
||||
try {
|
||||
Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<Map<String, T>>() {
|
||||
Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<Map<String, Map<String, Object>>>() {
|
||||
});
|
||||
Map<String, T> result = new HashMap<>(16);
|
||||
for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
|
||||
@ -305,8 +306,8 @@ public class JsonUtil {
|
||||
//序列化时,日期的统一格式
|
||||
super.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, Locale.CHINA));
|
||||
//序列化处理
|
||||
super.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
|
||||
super.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
|
||||
super.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
|
||||
super.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
|
||||
super.findAndRegisterModules();
|
||||
//失败处理
|
||||
super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
|
@ -16,6 +16,7 @@
|
||||
package org.springblade.core.tool.support.xss;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@ -30,6 +31,7 @@ import java.io.IOException;
|
||||
public class XssFilter implements Filter {
|
||||
|
||||
private XssProperties xssProperties;
|
||||
private XssUrlProperties xssUrlProperties;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) {
|
||||
@ -39,7 +41,7 @@ public class XssFilter implements Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
String path = ((HttpServletRequest) request).getServletPath();
|
||||
if (xssProperties.getExcludePatterns().stream().anyMatch(path::contains)) {
|
||||
if (isSkip(path)) {
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
|
||||
@ -47,6 +49,11 @@ public class XssFilter implements Filter {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSkip(String path) {
|
||||
return (xssUrlProperties.getExcludePatterns().stream().anyMatch(path::startsWith))
|
||||
|| (xssProperties.getSkipUrl().stream().map(url -> url.replace("/**", StringPool.EMPTY)).anyMatch(path::startsWith));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
|
@ -15,9 +15,7 @@
|
||||
*/
|
||||
package org.springblade.core.tool.support.xss;
|
||||
|
||||
import org.springblade.core.tool.utils.Charsets;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
@ -29,6 +27,7 @@ import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -49,15 +48,9 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
*/
|
||||
private final static HtmlFilter HTML_FILTER = new HtmlFilter();
|
||||
|
||||
/**
|
||||
* 缓存报文,支持多次读取流
|
||||
*/
|
||||
private final byte[] body;
|
||||
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
orgRequest = request;
|
||||
body = WebUtil.getRequestBytes(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -67,51 +60,67 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
|
||||
//为空,直接返回
|
||||
if (null == super.getHeader(HttpHeaders.CONTENT_TYPE)) {
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
//非json类型,直接返回
|
||||
if (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)
|
||||
&& !super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)) {
|
||||
if (super.getHeader(HttpHeaders.CONTENT_TYPE).startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)) {
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
//为空,直接返回
|
||||
String requestStr = WebUtil.getRequestStr(orgRequest, body);
|
||||
if (StringUtil.isBlank(requestStr)) {
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
requestStr = xssEncode(requestStr);
|
||||
|
||||
final ByteArrayInputStream bis = new ByteArrayInputStream(requestStr.getBytes(Charsets.UTF_8));
|
||||
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(inputHandlers(super.getInputStream()).getBytes());
|
||||
|
||||
return new ServletInputStream() {
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
return byteArrayInputStream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return bis.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String inputHandlers(ServletInputStream servletInputStream) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(servletInputStream, StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (servletInputStream != null) {
|
||||
try {
|
||||
servletInputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return xssEncode(sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -129,7 +138,6 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
if (parameters == null || parameters.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
parameters[i] = xssEncode(parameters[i]);
|
||||
}
|
||||
@ -165,6 +173,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
/**
|
||||
* 获取最原始的request
|
||||
*
|
||||
* @return HttpServletRequest
|
||||
*/
|
||||
public HttpServletRequest getOrgRequest() {
|
||||
@ -173,6 +182,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
/**
|
||||
* 获取最原始的request
|
||||
*
|
||||
* @param request request
|
||||
* @return HttpServletRequest
|
||||
*/
|
||||
@ -180,7 +190,6 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
if (request instanceof XssHttpServletRequestWrapper) {
|
||||
return ((XssHttpServletRequestWrapper) request).getOrgRequest();
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,17 @@ import java.util.List;
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("blade.xss.url")
|
||||
@ConfigurationProperties("blade.xss")
|
||||
public class XssProperties {
|
||||
|
||||
private final List<String> excludePatterns = new ArrayList<>();
|
||||
/**
|
||||
* 开启xss
|
||||
*/
|
||||
private Boolean enable = true;
|
||||
|
||||
/**
|
||||
* 放行url
|
||||
*/
|
||||
private List<String> skipUrl = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.tool.support.xss;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Xss配置类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("blade.xss.url")
|
||||
public class XssUrlProperties {
|
||||
|
||||
private final List<String> excludePatterns = new ArrayList<>();
|
||||
|
||||
}
|
@ -1124,7 +1124,7 @@ public class Func {
|
||||
* @param <T> T 泛型标记
|
||||
* @return Bean
|
||||
*/
|
||||
public static <T> T parse(byte[] bytes, TypeReference<?> typeReference) {
|
||||
public static <T> T parse(byte[] bytes, TypeReference<T> typeReference) {
|
||||
return JsonUtil.parse(bytes, typeReference);
|
||||
}
|
||||
|
||||
@ -1136,7 +1136,7 @@ public class Func {
|
||||
* @param <T> T 泛型标记
|
||||
* @return Bean
|
||||
*/
|
||||
public static <T> T parse(String jsonString, TypeReference<?> typeReference) {
|
||||
public static <T> T parse(String jsonString, TypeReference<T> typeReference) {
|
||||
return JsonUtil.parse(jsonString, typeReference);
|
||||
}
|
||||
|
||||
@ -1148,7 +1148,7 @@ public class Func {
|
||||
* @param <T> T 泛型标记
|
||||
* @return Bean
|
||||
*/
|
||||
public static <T> T parse(InputStream in, TypeReference<?> typeReference) {
|
||||
public static <T> T parse(InputStream in, TypeReference<T> typeReference) {
|
||||
return JsonUtil.parse(in, typeReference);
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ public class StringUtil extends org.springframework.util.StringUtils {
|
||||
* @return {String}
|
||||
*/
|
||||
public static String escapeHtml(String html) {
|
||||
return HtmlUtils.htmlEscape(html);
|
||||
return StringUtil.isBlank(html) ? StringPool.EMPTY : HtmlUtils.htmlEscape(html);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1250,7 +1250,7 @@ public class StringUtil extends org.springframework.util.StringUtils {
|
||||
/**
|
||||
* 创建StringBuilder对象
|
||||
*
|
||||
* @param sb 初始StringBuilder
|
||||
* @param sb 初始StringBuilder
|
||||
* @param strs 初始字符串列表
|
||||
* @return StringBuilder对象
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
18
pom.xml
18
pom.xml
@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.6.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>blade-tool</name>
|
||||
<description>
|
||||
@ -36,24 +36,24 @@
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<blade.tool.version>2.5.4</blade.tool.version>
|
||||
<blade.tool.version>2.6.0</blade.tool.version>
|
||||
|
||||
<java.version>1.8</java.version>
|
||||
<maven.plugin.version>3.8.0</maven.plugin.version>
|
||||
<swagger.version>2.9.2</swagger.version>
|
||||
<swagger.models.version>1.5.21</swagger.models.version>
|
||||
<swagger.bootstrapui.version>1.9.6</swagger.bootstrapui.version>
|
||||
<mybatis.plus.version>3.1.2</mybatis.plus.version>
|
||||
<knife4j.version>2.0.1</knife4j.version>
|
||||
<mybatis.plus.version>3.2.0</mybatis.plus.version>
|
||||
<curator.framework.version>4.0.1</curator.framework.version>
|
||||
<protostuff.version>1.6.0</protostuff.version>
|
||||
<disruptor.version>3.4.2</disruptor.version>
|
||||
<spring.boot.admin.version>2.1.5</spring.boot.admin.version>
|
||||
<spring.boot.admin.version>2.2.0</spring.boot.admin.version>
|
||||
<mica.auto.version>1.1.0</mica.auto.version>
|
||||
<alibaba.cloud.version>2.1.0.RELEASE</alibaba.cloud.version>
|
||||
<alibaba.seata.version>0.9.0</alibaba.seata.version>
|
||||
<alibaba.cloud.version>2.1.1.RELEASE</alibaba.cloud.version>
|
||||
<alibaba.seata.version>1.0.0</alibaba.seata.version>
|
||||
|
||||
<spring.boot.version>2.1.9.RELEASE</spring.boot.version>
|
||||
<spring.cloud.version>Greenwich.SR3</spring.cloud.version>
|
||||
<spring.boot.version>2.2.2.RELEASE</spring.boot.version>
|
||||
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
|
||||
<spring.platform.version>Cairo-SR8</spring.platform.version>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
Loading…
Reference in New Issue
Block a user