4670101279
2 years ago
18 changed files with 448 additions and 179 deletions
@ -0,0 +1,66 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) 2016-2019 人人开源 All rights reserved. |
||||||
|
* |
||||||
|
* https://www.renren.io
|
||||||
|
* |
||||||
|
* 版权所有,侵权必究! |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.ruoyi.common.core.page; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回数据 |
||||||
|
* |
||||||
|
* @author Mark sunlightcs@gmail.com |
||||||
|
*/ |
||||||
|
public class R extends HashMap<String, Object> { |
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
public R() { |
||||||
|
put("code", 0); |
||||||
|
put("msg", "操作成功"); |
||||||
|
} |
||||||
|
|
||||||
|
public R(Object o) {} |
||||||
|
|
||||||
|
public static R error() { |
||||||
|
return error(500, "发生错误,请联系管理员"); |
||||||
|
} |
||||||
|
|
||||||
|
public static R error(String msg) { |
||||||
|
return error(500, msg); |
||||||
|
} |
||||||
|
|
||||||
|
public static R error(int code, String msg) { |
||||||
|
R r = new R(); |
||||||
|
r.put("code", code); |
||||||
|
r.put("msg", msg); |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
public static R ok(String msg) { |
||||||
|
R r = new R(); |
||||||
|
r.put("msg", msg); |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
public static R ok(Map<String, Object> map) { |
||||||
|
R r = new R(); |
||||||
|
r.putAll(map); |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
public static R ok() { |
||||||
|
return new R(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public R put(String key, Object value) { |
||||||
|
super.put(key, value); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) 2016-2019 人人开源 All rights reserved. |
||||||
|
* |
||||||
|
* https://www.renren.io
|
||||||
|
* |
||||||
|
* 版权所有,侵权必究! |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.ruoyi.common.exception; |
||||||
|
|
||||||
|
/** |
||||||
|
* 自定义异常 |
||||||
|
* |
||||||
|
* @author Mark sunlightcs@gmail.com |
||||||
|
*/ |
||||||
|
public class RYException extends RuntimeException { |
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
|
||||||
|
private String msg; |
||||||
|
private int code = 500; |
||||||
|
|
||||||
|
public RYException(String msg) { |
||||||
|
super(msg); |
||||||
|
this.msg = msg; |
||||||
|
} |
||||||
|
|
||||||
|
public RYException(String msg, Throwable e) { |
||||||
|
super(msg, e); |
||||||
|
this.msg = msg; |
||||||
|
} |
||||||
|
|
||||||
|
public RYException(String msg, int code) { |
||||||
|
super(msg); |
||||||
|
this.msg = msg; |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
public RYException(String msg, int code, Throwable e) { |
||||||
|
super(msg, e); |
||||||
|
this.msg = msg; |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMsg() { |
||||||
|
return msg; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMsg(String msg) { |
||||||
|
this.msg = msg; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCode(int code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package com.ruoyi.common.utils; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.apache.commons.io.output.CloseShieldOutputStream; |
||||||
|
import org.springframework.beans.BeansException; |
||||||
|
import org.springframework.beans.factory.DisposableBean; |
||||||
|
import org.springframework.context.ApplicationContext; |
||||||
|
import org.springframework.context.ApplicationContextAware; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class BeanUtil implements ApplicationContextAware, DisposableBean { |
||||||
|
private static ApplicationContext applicationContext = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. |
||||||
|
*/ |
||||||
|
public static <T> T getBean(Class<T> requiredType) { |
||||||
|
if(applicationContext==null){ |
||||||
|
throw new IllegalStateException("applicaitonContext属性未注入, 请在SpringBoot启动类中注册BeanUtil."); |
||||||
|
} |
||||||
|
return applicationContext.getBean(requiredType); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void destroy() { |
||||||
|
applicationContext = null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
||||||
|
if (BeanUtil.applicationContext != null) { |
||||||
|
System.out.println("BeanUtil中的ApplicationContext被覆盖, 原有ApplicationContext为:" + BeanUtil.applicationContext); |
||||||
|
} |
||||||
|
BeanUtil.applicationContext = applicationContext; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) 2016-2019 人人开源 All rights reserved. |
||||||
|
* |
||||||
|
* https://www.renren.io
|
||||||
|
* |
||||||
|
* 版权所有,侵权必究! |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.ruoyi.common.utils; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.OrderItem; |
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||||
|
import com.ruoyi.common.constant.Constants; |
||||||
|
import com.ruoyi.common.xss.SQLFilter; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* 查询参数 |
||||||
|
* |
||||||
|
* @author Mark sunlightcs@gmail.com |
||||||
|
*/ |
||||||
|
public class Query<T> { |
||||||
|
|
||||||
|
public Page<T> getPage(Map<String, Object> params) { |
||||||
|
return this.getPage(params, null, false); |
||||||
|
} |
||||||
|
|
||||||
|
public Page<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) { |
||||||
|
//分页参数
|
||||||
|
long curPage = 1; |
||||||
|
long limit = 10; |
||||||
|
|
||||||
|
if(params.get(Constants.PAGE) != null){ |
||||||
|
curPage = Long.parseLong((String)params.get(Constants.PAGE)); |
||||||
|
} |
||||||
|
if(params.get(Constants.LIMIT) != null){ |
||||||
|
limit = Long.parseLong((String)params.get(Constants.LIMIT)); |
||||||
|
} |
||||||
|
|
||||||
|
//分页对象
|
||||||
|
Page<T> page = new Page<>(curPage, limit); |
||||||
|
|
||||||
|
//分页参数
|
||||||
|
params.put(Constants.PAGE, page); |
||||||
|
|
||||||
|
//排序字段
|
||||||
|
//防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
|
||||||
|
String orderField = SQLFilter.sqlInject((String)params.get(Constants.ORDER_FIELD)); |
||||||
|
String order = (String)params.get(Constants.ORDER); |
||||||
|
|
||||||
|
//前端字段排序
|
||||||
|
if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){ |
||||||
|
if(Constants.ASC.equalsIgnoreCase(order)) { |
||||||
|
return page.addOrder(OrderItem.asc(orderField)); |
||||||
|
}else { |
||||||
|
return page.addOrder(OrderItem.desc(orderField)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//没有排序字段,则不排序
|
||||||
|
if(StringUtils.isBlank(defaultOrderField)){ |
||||||
|
return page; |
||||||
|
} |
||||||
|
|
||||||
|
//默认排序
|
||||||
|
if(isAsc) { |
||||||
|
page.addOrder(OrderItem.asc(defaultOrderField)); |
||||||
|
}else { |
||||||
|
page.addOrder(OrderItem.desc(defaultOrderField)); |
||||||
|
} |
||||||
|
|
||||||
|
return page; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) 2016-2019 人人开源 All rights reserved. |
||||||
|
* |
||||||
|
* https://www.renren.io
|
||||||
|
* |
||||||
|
* 版权所有,侵权必究! |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.ruoyi.common.xss; |
||||||
|
|
||||||
|
|
||||||
|
import com.ruoyi.common.exception.RYException; |
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* SQL过滤 |
||||||
|
* |
||||||
|
* @author Mark sunlightcs@gmail.com |
||||||
|
*/ |
||||||
|
public class SQLFilter { |
||||||
|
|
||||||
|
/** |
||||||
|
* SQL注入过滤 |
||||||
|
* @param str 待验证的字符串 |
||||||
|
*/ |
||||||
|
public static String sqlInject(String str){ |
||||||
|
if(StringUtils.isBlank(str)){ |
||||||
|
return null; |
||||||
|
} |
||||||
|
//去掉'|"|;|\字符
|
||||||
|
str = StringUtils.replace(str, "'", ""); |
||||||
|
str = StringUtils.replace(str, "\"", ""); |
||||||
|
str = StringUtils.replace(str, ";", ""); |
||||||
|
str = StringUtils.replace(str, "\\", ""); |
||||||
|
|
||||||
|
//转换成小写
|
||||||
|
str = str.toLowerCase(); |
||||||
|
|
||||||
|
//非法字符
|
||||||
|
String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"}; |
||||||
|
|
||||||
|
//判断是否包含非法字符
|
||||||
|
for(String keyword : keywords){ |
||||||
|
if(str.indexOf(keyword) != -1){ |
||||||
|
throw new RYException("包含非法字符"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return str; |
||||||
|
} |
||||||
|
} |
@ -1,132 +0,0 @@ |
|||||||
package com.ruoyi.framework.config; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Arrays; |
|
||||||
import java.util.HashSet; |
|
||||||
import java.util.List; |
|
||||||
import javax.sql.DataSource; |
|
||||||
import org.apache.ibatis.io.VFS; |
|
||||||
import org.apache.ibatis.session.SqlSessionFactory; |
|
||||||
import org.mybatis.spring.SqlSessionFactoryBean; |
|
||||||
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; |
|
||||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||||
import org.springframework.context.annotation.Bean; |
|
||||||
import org.springframework.context.annotation.Configuration; |
|
||||||
import org.springframework.core.env.Environment; |
|
||||||
import org.springframework.core.io.DefaultResourceLoader; |
|
||||||
import org.springframework.core.io.Resource; |
|
||||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
|
||||||
import org.springframework.core.io.support.ResourcePatternResolver; |
|
||||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory; |
|
||||||
import org.springframework.core.type.classreading.MetadataReader; |
|
||||||
import org.springframework.core.type.classreading.MetadataReaderFactory; |
|
||||||
import org.springframework.util.ClassUtils; |
|
||||||
import com.ruoyi.common.utils.StringUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Mybatis支持*匹配扫描包 |
|
||||||
* |
|
||||||
* @author ruoyi |
|
||||||
*/ |
|
||||||
@Configuration |
|
||||||
public class MyBatisConfig |
|
||||||
{ |
|
||||||
@Autowired |
|
||||||
private Environment env; |
|
||||||
|
|
||||||
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; |
|
||||||
|
|
||||||
public static String setTypeAliasesPackage(String typeAliasesPackage) |
|
||||||
{ |
|
||||||
ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver(); |
|
||||||
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); |
|
||||||
List<String> allResult = new ArrayList<String>(); |
|
||||||
try |
|
||||||
{ |
|
||||||
for (String aliasesPackage : typeAliasesPackage.split(",")) |
|
||||||
{ |
|
||||||
List<String> result = new ArrayList<String>(); |
|
||||||
aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX |
|
||||||
+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN; |
|
||||||
Resource[] resources = resolver.getResources(aliasesPackage); |
|
||||||
if (resources != null && resources.length > 0) |
|
||||||
{ |
|
||||||
MetadataReader metadataReader = null; |
|
||||||
for (Resource resource : resources) |
|
||||||
{ |
|
||||||
if (resource.isReadable()) |
|
||||||
{ |
|
||||||
metadataReader = metadataReaderFactory.getMetadataReader(resource); |
|
||||||
try |
|
||||||
{ |
|
||||||
result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); |
|
||||||
} |
|
||||||
catch (ClassNotFoundException e) |
|
||||||
{ |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
if (result.size() > 0) |
|
||||||
{ |
|
||||||
HashSet<String> hashResult = new HashSet<String>(result); |
|
||||||
allResult.addAll(hashResult); |
|
||||||
} |
|
||||||
} |
|
||||||
if (allResult.size() > 0) |
|
||||||
{ |
|
||||||
typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0])); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包"); |
|
||||||
} |
|
||||||
} |
|
||||||
catch (IOException e) |
|
||||||
{ |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
return typeAliasesPackage; |
|
||||||
} |
|
||||||
|
|
||||||
public Resource[] resolveMapperLocations(String[] mapperLocations) |
|
||||||
{ |
|
||||||
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); |
|
||||||
List<Resource> resources = new ArrayList<Resource>(); |
|
||||||
if (mapperLocations != null) |
|
||||||
{ |
|
||||||
for (String mapperLocation : mapperLocations) |
|
||||||
{ |
|
||||||
try |
|
||||||
{ |
|
||||||
Resource[] mappers = resourceResolver.getResources(mapperLocation); |
|
||||||
resources.addAll(Arrays.asList(mappers)); |
|
||||||
} |
|
||||||
catch (IOException e) |
|
||||||
{ |
|
||||||
// ignore
|
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return resources.toArray(new Resource[resources.size()]); |
|
||||||
} |
|
||||||
|
|
||||||
@Bean |
|
||||||
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception |
|
||||||
{ |
|
||||||
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); |
|
||||||
String mapperLocations = env.getProperty("mybatis.mapperLocations"); |
|
||||||
String configLocation = env.getProperty("mybatis.configLocation"); |
|
||||||
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); |
|
||||||
VFS.addImplClass(SpringBootVFS.class); |
|
||||||
|
|
||||||
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); |
|
||||||
sessionFactory.setDataSource(dataSource); |
|
||||||
sessionFactory.setTypeAliasesPackage(typeAliasesPackage); |
|
||||||
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ","))); |
|
||||||
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); |
|
||||||
return sessionFactory.getObject(); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,62 @@ |
|||||||
|
package com.ruoyi.framework.config; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType; |
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; |
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; |
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement; |
||||||
|
|
||||||
|
/** |
||||||
|
* Mybatis Plus 配置 |
||||||
|
* |
||||||
|
* @author ruoyi |
||||||
|
*/ |
||||||
|
@EnableTransactionManagement(proxyTargetClass = true) |
||||||
|
@Configuration |
||||||
|
public class MybatisPlusConfig |
||||||
|
{ |
||||||
|
@Bean |
||||||
|
public MybatisPlusInterceptor mybatisPlusInterceptor() |
||||||
|
{ |
||||||
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
||||||
|
// 分页插件
|
||||||
|
interceptor.addInnerInterceptor(paginationInnerInterceptor()); |
||||||
|
// 乐观锁插件
|
||||||
|
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor()); |
||||||
|
// 阻断插件
|
||||||
|
interceptor.addInnerInterceptor(blockAttackInnerInterceptor()); |
||||||
|
return interceptor; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
|
||||||
|
*/ |
||||||
|
public PaginationInnerInterceptor paginationInnerInterceptor() |
||||||
|
{ |
||||||
|
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); |
||||||
|
// 设置数据库类型为mysql
|
||||||
|
paginationInnerInterceptor.setDbType(DbType.MYSQL); |
||||||
|
// 设置最大单页限制数量,默认 500 条,-1 不受限制
|
||||||
|
paginationInnerInterceptor.setMaxLimit(-1L); |
||||||
|
return paginationInnerInterceptor; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
|
||||||
|
*/ |
||||||
|
public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() |
||||||
|
{ |
||||||
|
return new OptimisticLockerInnerInterceptor(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
|
||||||
|
*/ |
||||||
|
public BlockAttackInnerInterceptor blockAttackInnerInterceptor() |
||||||
|
{ |
||||||
|
return new BlockAttackInnerInterceptor(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue