Commit 321361c9 authored by xiandafu's avatar xiandafu
Browse files

init

parent 2971e3f1
<!--#layout("/common/layout.html",{"jsBase":"/js/admin/role/"}){ -->
<layui:searchForm formId="searchForm" condition="${search}">
</layui:searchForm>
<div class="layui-btn-group">
<layui:accessButton function="role.add" action="add">增加</layui:accessButton>
<layui:accessButton function="role.edit" action="edit">编辑</layui:accessButton>
<layui:accessButton function="role.del" action="del">删除</layui:accessButton>
<layui:accessButton function="role.user.query" action="roleUser">查看用户</layui:accessButton>
</div>
<table id="roleTable" lay-filter="roleTable"></table>
<!--#} -->
<script>
layui.use(['index'], function(){
var index = layui.index
index.init();
});
</script>
<!--#layout("/common/layout.html",{"jsBase":"/js/admin/role/"}){ -->
<layui:searchForm formId="roleUserSearchForm" condition="${search}">
<input type="hidden" name="roleId" value="${role.id}">
</layui:searchForm>
<table id="userTable" lay-filter="userTable"></table>
<layui:closeButton id="close"/>
<!--#} -->
<script>
layui.use(['roleUser'], function(){
var roleUser = layui.roleUser
roleUser.init(${role.id});
});
</script>
<!--# layout("/common/layout.html",{"jsBase":"/js/admin/user/"}){ -->
<form class="layui-form layui-form-pane" id="addForm"
action="/admin/user/add.json">
<div class="layui-row">
<div class="layui-form-item">
<label class="layui-form-label">用户姓名</label>
<div class="layui-input-block">
<input type="text" name="name" autocomplete="off"
placeholder="请输入标题" class="layui-input" value="">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户帐号</label>
<div class="layui-input-inline">
<input type="text" name="code" lay-verify="required"
placeholder="请输入" autocomplete="off" class="layui-input"
value="">
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs4">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">所在机构</label>
<layui:orgInput style='layui-input-inline' name="orgId" id="orgId"
value=""></layui:orgInput>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-form-item">
<label class="layui-form-label">用户状态</label>
<layui:simpleDictSelect style='layui-input-inline' type="user_state"
id="state" name="state" value="" />
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs4">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">职务类型</label>
<layui:simpleDictSelect style='layui-input-inline' type="job_type"
id="jobType0" name="jobType0" value="" group="job"/>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-form-item">
<label class="layui-form-label">职务类型明细</label>
<layui:simpleDictSelect style='layui-input-inline' type=""
id="jobType1" name="jobType1" value="" group="job"/>
</div>
</div>
</div>
<layui:submitButtons id="saveUser" />
</form>
<!--#} -->
<script>
layui.use(['add'], function(){
var userAdd = layui.add
userAdd.init();
});
</script>
<!--# layout("/common/layout.html",{"jsBase":"/js/admin/user/"}){ -->
<form class="layui-form layui-form-pane" id="changePasswordForm"
action="/admin/user/changePassword.json">
<div class="layui-row">
<div class="layui-form-item">
<label class="layui-form-label">用户姓名</label>
<div class="layui-input-block">
<input type="text" name="name" disabled autocomplete="off"
class="layui-input" value="${user.name}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户帐号</label>
<div class="layui-input-inline">
<input type="text" name="code" disabled
placeholder="请输入" autocomplete="off" class="layui-input"
value="${user.code}">
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" name="password" autocomplete="off"
placeholder="请输入密码" class="layui-input" value="">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码确认</label>
<div class="layui-input-inline">
<input type="password" name="password2" lay-verify="required"
placeholder="请再次输入密码" autocomplete="off" class="layui-input"
>
</div>
</div>
</div>
<layui:submitButtons id="savePassword" />
<input type="hidden" name="id" value=${user.id} />
</form>
<!--#} -->
<script>
layui.use(['changePassword'], function(){
var changePassword = layui.changePassword
changePassword.init();
});
</script>
<!--# layout("/common/layout.html",{"jsBase":"/js/admin/user/"}){ -->
<form class="layui-form layui-form-pane" id="updateForm"
action="/admin/user/update.json">
<div class="layui-row">
<div class="layui-form-item">
<label class="layui-form-label">用户姓名</label>
<div class="layui-input-block">
<input type="text" name="name" autocomplete="off"
placeholder="请输入标题" class="layui-input" value="${user.name}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户帐号</label>
<div class="layui-input-inline">
<input type="text" name="code" disabled lay-verify="required"
placeholder="请输入" autocomplete="off" class="layui-input"
value="${user.code}">
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs4">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">所在机构</label>
<layui:orgInput style='layui-input-inline' name="orgId" id="orgId"
value="${user.orgId}"></layui:orgInput>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-form-item">
<label class="layui-form-label">用户状态</label>
<layui:simpleDictSelect style='layui-input-inline' type="user_state"
id="state" name="state" value="${user.state}" />
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-col-xs4">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">职务类型</label>
<layui:simpleDictSelect style='layui-input-inline' type="job_type"
id="jobType0" name="jobType0" value="${user.jobType0}" group="job"/>
</div>
</div>
</div>
<div class="layui-col-xs4">
<div class="layui-form-item">
<label class="layui-form-label">职务类型明细</label>
<layui:simpleDictSelect style='layui-input-inline' type=""
id="jobType1" name="jobType1" value="${user.jobType1}" group="job"/>
</div>
</div>
</div>
<layui:submitButtons id="saveUser" />
<input type="hidden" name="id" value=${user.id} />
</form>
<!--#} -->
<script>
layui.use(['edit'], function(){
var userEdit = layui.edit
userEdit.init();
});
</script>
<!--#layout("/common/layout.html",{"jsBase":"/js/admin/user/"}){ -->
<layui:searchForm formId="searchForm" condition="${search}">
</layui:searchForm>
<div class="layui-btn-group">
<layui:accessButton function="user.add" action="add">增加</layui:accessButton>
<layui:accessButton function="user.edit" action="edit">编辑</layui:accessButton>
<layui:accessButton function="user.del" action="del">删除</layui:accessButton>
<layui:accessButton function="user.role" action="userRole">操作角色</layui:accessButton>
<layui:accessButton function="user.role" action="userRole">流程角色</layui:accessButton>
<layui:accessButton function="user.password" action="changePassword">修改密码</layui:accessButton>
</div>
<table id="userTable" lay-filter="userTable"></table>
<!--#} -->
<script>
layui.use(['index'], function(){
var index = layui.index
index.init();
});
</script>
<!--#layout("/common/layout.html",{"jsBase":"/js/admin/user/"}){ -->
<layui:searchForm formId="userRoleSearchForm" condition="${search}">
<input type="hidden" name="userId" value="${user.id}">
</layui:searchForm>
<div class="layui-btn-group">
<layui:accessButton function="user.role.add" action="add">增加</layui:accessButton>
<layui:accessButton function="user.role.delete" action="del">删除</layui:accessButton>
</div>
<table id="userRoleTable" lay-filter="userRoleTable"></table>
<layui:closeButton id="close"/>
<!--#} -->
<script>
layui.use(['userRole'], function(){
var userRole = layui.userRole
userRole.init(${user.id});
});
</script>
<!--# layout("/common/layout.html",{"jsBase":"/js/admin/user/"}){ -->
<form class="layui-form layui-form-pane" id="userRoleAddForm"
action="/admin/user/role/add.json">
<div class="layui-row">
<div class="layui-form-item">
<label class="layui-form-label">用户姓名</label>
<div class="layui-input-block">
<input type="text" name="name" autocomplete="off"
placeholder="请输入标题" class="layui-input" value="${user.name}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户帐号</label>
<div class="layui-input-inline">
<input type="text" name="code" disabled lay-verify="required"
placeholder="请输入" autocomplete="off" class="layui-input"
value="${user.code}">
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-form-item">
<label class="layui-form-label">选择公司</label>
<div class="layui-input-block">
<layui:orgInput style='layui-input-inline' name="orgId" id="orgId"
value="${user.orgId}"></layui:orgInput>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">选择角色</label>
<div class="layui-input-block">
<layui:roleInput name="roleId" type="R0" />
</div>
</div>
</div>
<layui:submitButtons id="saveUserRole" />
<input type="hidden" name="userId" value=${user.id} />
</form>
<!--#} -->
<script>
layui.use(['userRoleAdd'], function(){
var userRoleAdd = layui.userRoleAdd
userRoleAdd.init();
});
</script>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.coamc.starter.CosonleApplication</param-value>
</context-param>
<listener>
<listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
http://xmlns.oracle.com/weblogic/weblogic-web-app
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>org.slf4j</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
\ No newline at end of file
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ibeetl</groupId>
<artifactId>admin-core</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
<parent>
<groupId>com.ibeetl</groupId>
<artifactId>admin</artifactId>
<version>1.0</version>
</parent>
</project>
package com.ibeetl.admin.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.ibeetl.admin.core.util.enums.CoreDictType;
/**
* 描述: 用来标注词典字段
*
*
* @author : lijiazhi
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Dict {
/**
* 类型
*
* @return
*/
public String type() default "";
/**
* 默认值
*
* @return
*/
public String defaultDisplay() default "";
/**
* 字典文本的后缀
*
* @return
*/
public String suffix() default "Text";
}
package com.ibeetl.admin.core.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 用来标注功能id
* <pre>
* &#064;Function("user.add")
* public String addUser(){
* }
* </pre>
*
* 只有拥有此项功能的角色才能操作,否则,权限不足
* @author lijiazhi
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Function {
public String value();
}
package com.ibeetl.admin.core.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 用来标准一个查询类
* @author lijiazhi
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Query {
public static final int TYPE_GENERAL = 1;
public static final int TYPE_DATE_BETWEEN = 2;
public static final int TYPE_DATETIME_BETWEEN = 3;
public static final int TYPE_VALUE_BETWEEN = 4;
public static final int TYPE_DICT = 5;
//用户自己定义
public static final int TYPE_CONTROL = 6;
/**
* 中文名字
* @return
*/
public String name();
/**
* 查询类型,常规,范围,字典,前端自定义
* @return
*/
public int type() default TYPE_GENERAL;
/**
* 是否显示在查询界面上
* @return
*/
public boolean display() default false;
/**
* 模糊查询,仅仅针对TYPE_GENERAL
* @return
*/
public boolean fuzzy() default false;
/**
* 字典的主键,比如,"user_state"
* @return
*/
public String dict() default "";
/*描述*/
public String comment() default "";
/**
* 控件名字,如组织机构面板
* @return
*/
public String control() default "";
/**
* 顺序,值越小,排在前面
* @return
*/
public int order() default 0;
/*控件组*/
public String group() default "";
}
package com.ibeetl.admin.core.conf;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.beetl.core.Context;
import org.beetl.core.Function;
import org.beetl.core.GroupTemplate;
import org.beetl.ext.simulate.WebSimulate;
import org.beetl.sql.core.InterceptorContext;
import org.beetl.sql.ext.DebugInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibeetl.admin.core.rbac.DataAccess;
import com.ibeetl.admin.core.rbac.DataAccessFactory;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.beetl.DictQueryByValueFunction;
import com.ibeetl.admin.core.util.beetl.DictQueryFunction;
import com.ibeetl.admin.core.util.beetl.DictUpQueryFunction;
import com.ibeetl.admin.core.util.beetl.FunFunction;
import com.ibeetl.admin.core.util.beetl.OrgFunction;
import com.ibeetl.admin.core.util.beetl.RoleFunction;
import com.ibeetl.admin.core.util.beetl.SearchCondtionFunction;
import com.ibeetl.admin.core.util.beetl.SysFunctionTreeFunction;
import com.ibeetl.admin.core.web.query.QueryParser;
import com.ibeetl.starter.BeetlTemplateCustomize;
import com.ibeetl.starter.ObjectMapperJsonUtil;
@Configuration
@AutoConfigureAfter(JasonConfig.class)
public class BeetlConf {
@Autowired
Environment env;
@Autowired
CorePlatformService platFormService;
@Autowired
OrgFunction orgFunction;
@Autowired
SysFunctionTreeFunction sysFunctionTreeFunction;
@Autowired
DictQueryFunction dictDownQueryFunction;
@Autowired
DictUpQueryFunction dictUpQueryFunction;
@Autowired
DictQueryByValueFunction dictQueryByValueFunction;
@Autowired
RoleFunction roleFunction;
@Autowired
SearchCondtionFunction searchCondtionFunction;
@Autowired
DataAccessFactory dataAccessFactory;
@Autowired
ApplicationContext applicationContext;
@Autowired
FunFunction funFunction;
@Bean
public WebSimulate getWebSimulate(GroupTemplate gt, ObjectMapper objectMapper) {
return new WebSimulate(gt, new ObjectMapperJsonUtil(objectMapper)) {
protected String getRenderPath(HttpServletRequest request) {
String defaultRenderPath = request.getServletPath();
return defaultRenderPath.replace(".do", ".html");
}
};
}
@Bean
public BeetlTemplateCustomize beetlTemplateCustomize() {
return new BeetlTemplateCustomize() {
public void customize(GroupTemplate groupTemplate) {
groupTemplate.registerFunctionPackage("platform", platFormService);
groupTemplate.registerFunctionPackage("queryCondtion", new QueryParser());
groupTemplate.registerFunction("core.orgName", orgFunction);
groupTemplate.registerFunction("core.functionName", funFunction);
groupTemplate.registerFunction("core.searchCondtion", searchCondtionFunction);
groupTemplate.registerFunction("core.dictDownQuery", dictDownQueryFunction);
groupTemplate.registerFunction("core.dictLevel", dictUpQueryFunction);
groupTemplate.registerFunction("core.dictListByValue", dictQueryByValueFunction);
groupTemplate.registerFunction("core.roles", roleFunction);
// 模板页面判断是否有按钮权限,比如canAccess
groupTemplate.registerFunction("canAccess", new Function() {
@Override
public Boolean call(Object[] paras, Context ctx) {
Long userId = platFormService.getCurrentUser().getId();
Long orgId = platFormService.getCurrentOrgId();
String functionCode = (String) paras[0];
return platFormService.canAcessFunction(userId, orgId, functionCode);
}
});
groupTemplate.registerFunction("dataAccessList", new Function() {
@Override
public List<DataAccess> call(Object[] paras, Context ctx) {
return dataAccessFactory.all();
}
});
}
};
}
static class StarterDebugInterceptor extends DebugInterceptor {
protected boolean isSimple(String sqlId) {
if (sqlId.indexOf("_gen_") != -1) {
return true;
} else {
return false;
}
}
protected void simpleOut(InterceptorContext ctx) {
return;
}
}
}
package com.ibeetl.admin.core.conf;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair;
/**
* 支持一二级缓存,使得性能逆天快.默认不开启
*
* @author xiandafu
*
*/
//@Configuration
//@ConditionalOnProperty(name="springext.cache.enabled", havingValue="true" ,matchIfMissing=false)
public class CacheConfig {
// 定义一个redis 的频道,默认叫cache,用于pub/sub
@Value("${springext.cache.redis.topic:cache}")
String topicName;
@Bean
public TowLevelCacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(redisTemplate.getConnectionFactory());
SerializationPair pair = SerializationPair
.fromSerializer(new JdkSerializationRedisSerializer(this.getClass().getClassLoader()));
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
TowLevelCacheManager cacheManager = new TowLevelCacheManager(redisTemplate, writer, config);
return cacheManager;
}
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, new PatternTopic(topicName));
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(final TowLevelCacheManager cacheManager) {
return new MessageListenerAdapter(new MessageListener() {
public void onMessage(Message message, byte[] pattern) {
byte[] bs = message.getChannel();
try {
// Sub 一个消息,通知缓存管理器
String type = new String(bs, "UTF-8");
cacheManager.receiver(type);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
// 不可能出错,忽略
}
}
});
}
class TowLevelCacheManager extends RedisCacheManager {
RedisTemplate redisTemplate;
public TowLevelCacheManager(RedisTemplate redisTemplate, RedisCacheWriter cacheWriter,
RedisCacheConfiguration defaultCacheConfiguration) {
super(cacheWriter, defaultCacheConfiguration);
this.redisTemplate = redisTemplate;
}
// 使用RedisAndLocalCache代替Spring Boot自带的RedisCache
@Override
protected Cache decorateCache(Cache cache) {
return new RedisAndLocalCache(this, (RedisCache) cache);
}
// 通过其他分布式节点,缓存改变
public void publishMessage(String cacheName) {
this.redisTemplate.convertAndSend(topicName, cacheName);
}
// 接受一个消息清空本地缓存
public void receiver(String name) {
RedisAndLocalCache cache = ((RedisAndLocalCache) this.getCache(name));
if (cache != null) {
cache.clearLocal();
}
}
}
class RedisAndLocalCache implements Cache {
// 本地缓存提供
ConcurrentHashMap<Object, Object> local = new ConcurrentHashMap<Object, Object>();
RedisCache redisCache;
TowLevelCacheManager cacheManager;
public RedisAndLocalCache(TowLevelCacheManager cacheManager, RedisCache redisCache) {
this.redisCache = redisCache;
this.cacheManager = cacheManager;
}
@Override
public String getName() {
return redisCache.getName();
}
@Override
public Object getNativeCache() {
return redisCache.getNativeCache();
}
@Override
public ValueWrapper get(Object key) {
ValueWrapper wrapper = (ValueWrapper) local.get(key);
if (wrapper != null) {
return wrapper;
} else {
// 二级缓存取
wrapper = redisCache.get(key);
if (wrapper != null) {
local.put(key, wrapper);
}
return wrapper;
}
}
@Override
public <T> T get(Object key, Class<T> type) {
return redisCache.get(key, type);
}
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
return redisCache.get(key, valueLoader);
}
@Override
public void put(Object key, Object value) {
System.out.println(value.getClass().getClassLoader());
redisCache.put(key, value);
clearOtherJVM();
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
ValueWrapper v = redisCache.putIfAbsent(key, value);
clearOtherJVM();
return v;
}
@Override
public void evict(Object key) {
redisCache.evict(key);
clearOtherJVM();
}
@Override
public void clear() {
redisCache.clear();
}
public void clearLocal() {
this.local.clear();
}
protected void clearOtherJVM() {
cacheManager.publishMessage(redisCache.getName());
}
}
}
package com.ibeetl.admin.core.conf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibeetl.admin.core.util.FormFieldException;
import com.ibeetl.admin.core.util.PlatformException;
import com.ibeetl.admin.core.web.JsonResult;
/**
* 自定义的全局错误页面
*
* @author lijiazhi
*/
@Controller
public class CustomErrorController extends AbstractErrorController {
private static final String ERROR_PATH = "/error";
Log log = LogFactory.getLog(ErrorController.class);
@Autowired
ObjectMapper objectMapper;
public CustomErrorController() {
super(new DefaultErrorAttributes());
}
@RequestMapping(ERROR_PATH)
public ModelAndView getErrorPath(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
request, false));
Throwable cause =getCause(request);
int status = (Integer)model.get("status");
//错误信息
String message = (String)model.get("message");
//友好提示
String errorMessage = getErrorMessage(cause);
String requestPath = (String)model.get("path");
List<FieldError> filedErrors = this.getFieldError(model, cause);
//后台打印日志信息方方便查错
log.info(status+":"+message+filedErrors, cause);
log.info("requestPath"+":"+requestPath);
response.setStatus(status);
if(!isJsonRequest(request)){
ModelAndView view = new ModelAndView("/error.html");
view.addAllObjects(model);
view.addObject("errorMessage", errorMessage);
view.addObject("filedErrors", filedErrors);
view.addObject("cause", cause);
view.addObject("requestPath", requestPath);
return view;
}else{
if(filedErrors==null){
if(status==404){
writeJson(response,JsonResult.http404(requestPath));
}else{
writeJson(response,JsonResult.failMessage(getErrorMessage(cause)));
}
}else{
writeJson(response,JsonResult.fail(this.wrapFieldErrors(filedErrors)));
}
return null;
}
}
protected List<FieldError> getFieldError(Map<String, Object> model,Throwable cause){
List<FieldError> filedErrors = (List<FieldError>)model.get("errors");
if(filedErrors!=null){
return filedErrors;
}
if(cause instanceof FormFieldException){
FormFieldException fe = (FormFieldException)cause;
return fe.getErrors();
}
return null;
}
protected List<Map<String,String>> wrapFieldErrors(List<FieldError> errors){
List<Map<String,String>> list = new ArrayList<Map<String,String>>();
for(FieldError e:errors){
Map<String,String> error = new HashMap<String,String>();
error.put("field", e.getField());
error.put("message", e.getDefaultMessage());
list.add(error);
}
return list;
}
protected boolean isJsonRequest(HttpServletRequest request){
String requestUri = (String)request.getAttribute("javax.servlet.error.request_uri");
if(requestUri!=null&&requestUri.endsWith(".json")){
return true;
}else{
return (request.getHeader("Accept").contains("application/json") || (request.getHeader("X-Requested-With") != null
&& request.getHeader("X-Requested-With").contains("XMLHttpRequest")));
}
}
protected void writeJson(HttpServletResponse response,JsonResult error){
response.setContentType("application/json;charset=utf-8");
try {
response.getWriter().write(objectMapper.writeValueAsString(error));
} catch (IOException e) {
// ignore
}
}
protected String getErrorMessage(Throwable ex) {
if(ex instanceof PlatformException){
return ex.getMessage();
}else{
return "服务器错误,请联系管理员";
}
}
protected Throwable getCause(HttpServletRequest request) {
Throwable error = (Throwable)request.getAttribute("javax.servlet.error.exception");
if (error != null) {
while (error instanceof ServletException && error.getCause() != null) {
error = ((ServletException) error).getCause();
}
}
return error;
}
@Override
public String getErrorPath() {
// TODO Auto-generated method stub
return null;
}
}
package com.ibeetl.admin.core.conf;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
public class DataSourceConfig {
@Bean(name = "dataSource")
public DataSource datasource(Environment env) {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(env.getProperty("spring.datasource.url"));
ds.setUsername(env.getProperty("spring.datasource.username"));
ds.setPassword(env.getProperty("spring.datasource.password"));
ds.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
return ds;
}
}
package com.ibeetl.admin.core.conf;
import java.io.IOException;
import java.text.SimpleDateFormat;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.ibeetl.admin.core.web.JsonResult;
@Configuration
public class JasonConfig {
@Bean
public ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
SimpleModule simpleModule = new SimpleModule("SimpleModule",
Version.unknownVersion());
simpleModule.addSerializer(JsonResult.class, new CustomJsonResultSerializer());
objectMapper.registerModule(simpleModule);
return objectMapper;
}
/**
* layui 前端要求后台返回的数据格式
* @author xiandafu
*
*/
static class CustomJsonResultSerializer extends JsonSerializer<JsonResult> {
public CustomJsonResultSerializer() {
}
@Override
public void serialize(JsonResult value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
if(value.getCode().equals("200")) {
gen.writeObjectField("code", 0);
}else {
gen.writeObjectField("code", Integer.parseInt(value.getCode()));
}
gen.writeStringField("msg", value.getMsg());
Object data = value.getData();
if(data instanceof PageQuery ) {
PageQuery query = (PageQuery)(data);
gen.writeObjectField("count", query.getTotalRow());
gen.writeObjectField("data", query.getList());
}else {
gen.writeObjectField("data", data);
}
gen.writeEndObject();
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment