提交 c81f7ee0 authored 作者: 陈世营's avatar 陈世营

loit-core-boot

上级 c54aa873
package com.loit.common.annotation;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* 字典相关注释
* @author wbh
* @date 2019年1月4日
*/
public class LoitDictAnnotation {
/**
*
* @author wbh
*
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface LoitDict {
String tableName() default "loit_dict_data";
String dictCode();
}
}
package com.loit.common.annotation;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* 自定义注释,属性验证
* @author wbh
* @date 2018年12月9日
*/
public class LoitValidateAnnotation {
/**
* 属性验证
*
* @author wbh
*
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface LoitValidate {
@Deprecated
boolean isNotNull() default false;
int length() default 0;
int max() default Integer.MAX_VALUE;
@Deprecated
String name() default "";
}
}
\ No newline at end of file
package com.loit.common.cache;
/**
* 缓存名称
*
* @author wbh
* add by 2020-02-15
*/
public interface RedisCacheNames {
}
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <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 com.loit.common.config;
import org.springframework.context.annotation.Configuration;
/**
* 公共封装包配置类
*
* @author wbh
* add by 2020-02-15
*/
@Configuration
public class CommonConfig {
}
package com.loit.common.json;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.loit.common.mapper.JsonMapper;
import com.loit.common.spring.timeloit.utils.LoitStatusCode;
/**
- $.ajax后需要接受的JSON
-
- @author
- */
@SuppressWarnings("rawtypes")
public class AjaxJson<T> implements Serializable{
public static final String CODE_COMMON_FAIL = LoitStatusCode.FAIL.statusCode;
/**
- @author wbh
- @date 2018年12月11日
*/
private static final long serialVersionUID = -7790919285662399570L;
private boolean success = true;// 是否成功
private String code = LoitStatusCode.SUCESS.statusCode;//返回码 100-成功,101失败,其他返回码参见LoitStatusCode
private String msg = "操作成功";// 提示信息
private Map<String, T> body = new LinkedHashMap<String, T>();//封装json的map
public Map<String, T> getBody() {
return body;
}
public void setBody(Map<String, T> body) {
this.body = body;
}
public void put(String key, T value){//向json中添加属性,在js中访问,请调用data.map.key
body.put(key, value);
}
public void remove(String key){
body.remove(key);
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {//向json中添加属性,在js中访问,请调用data.msg
this.msg = msg;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
@JsonIgnore//返回对象时忽略此属性
public String getJsonStr() {//返回json字符串数组,将访问msg和key的方式统一化,都使用data.key的方式直接访问。
String json = JsonMapper.getInstance().toJson(this);
return json;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "AjaxJson [success=" + success + ", code=" + code + ", msg=" + msg + "]";
}
/**
- 返回普通异常信息。code=101
- @author wbh
- @date:2018年12月16日
- @param info
- @return
*/
public static AjaxJson returnExceptionInfo(String info) {
AjaxJson json = new AjaxJson();
json.setSuccess(false);
json.setCode(CODE_COMMON_FAIL);
json.setMsg(info);
return json;
}
/**
- 返回普通异常信息。code=101
- @author wbh
- @date:2018年12月16日
- @param info
- @return
*/
public static AjaxJson returnExceptionInfo(String code, String info) {
AjaxJson json = new AjaxJson();
json.setSuccess(false);
json.setCode(code);
json.setMsg(info);
return json;
}
/**
- 返回普通异常信息。code=101
- @author wbh
- @date:2018年12月16日
- @param info
- @return
*/
public static AjaxJson returnExceptionInfo(String info, AjaxJson json) {
json.setSuccess(false);
json.setCode(CODE_COMMON_FAIL);
json.setMsg(info);
return json;
}
/**
- 返回指定异常信息。
- @author wbh
- @date:2019年10月31日
- @param code 状态码
- @param info 返回信息
- @return
*/
public static AjaxJson returnExceptionInfo(LoitStatusCode info) {
AjaxJson json = new AjaxJson();
json.setSuccess(false);
json.setCode(info.statusCode);
json.setMsg(info.statusDesc);
return json;
}
/**
- 返回指定异常信息。
- @author wbh
- @date:2019年10月31日
- @param code 状态码
- @param info 返回信息
- @return
*/
public static AjaxJson returnExceptionInfo(LoitStatusCode info, AjaxJson json) {
json.setSuccess(false);
json.setCode(info.statusCode);
json.setMsg(info.statusDesc);
return json;
}
}
package com.loit.common.mapper;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
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.fasterxml.jackson.databind.util.JSONPObject;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* 简单封装Jackson,实现JSON String<->Java Object的Mapper.
* 封装不同的输出风格, 使用不同的builder函数创建实例.
* @author loit
* @version 2013-11-15
*/
@SuppressWarnings("deprecation")
public class JsonMapper extends ObjectMapper {
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);
private static JsonMapper mapper;
public JsonMapper() {
//this(Include.NON_EMPTY);
}
public JsonMapper(Include include) {
// 设置输出时包含属性的风格
if (include != null) {
this.setSerializationInclusion(include);
}
// 允许单引号、允许不带引号的字段名称
this.enableSimple();
// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 空值处理为空串
this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
@Override
public void serialize(Object value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeString("");
}
});
// 进行HTML解码。
this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){
@Override
public void serialize(String value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeString(StringEscapeUtils.unescapeHtml4(value));
}
}));
// 设置时区
this.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00")
}
/**
* 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.
*/
public static JsonMapper getInstance() {
if (mapper == null){
mapper = new JsonMapper().enableSimple();
}
return mapper;
}
/**
* 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。
*/
public static JsonMapper nonDefaultMapper() {
if (mapper == null){
mapper = new JsonMapper(Include.NON_DEFAULT);
}
return mapper;
}
/**
* Object可以是POJO,也可以是Collection或数组。
* 如果对象为Null, 返回"null".
* 如果集合为空集合, 返回"[]".
*/
public String toJson(Object object) {
try {
return this.writeValueAsString(object);
} catch (IOException e) {
logger.warn("write to json string error:" + object, e);
return null;
}
}
/**
* 反序列化POJO或简单Collection如List<String>.
*
* 如果JSON字符串为Null或"null"字符串, 返回Null.
* 如果JSON字符串为"[]", 返回空集合.
*
* 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType)
* @see #fromJson(String, JavaType)
*/
public <T> T fromJson(String jsonString, Class<T> clazz) {
if (StringUtils.isEmpty(jsonString)) {
return null;
}
try {
return this.readValue(jsonString, clazz);
} catch (IOException e) {
logger.warn("parse json string error:" + jsonString, e);
return null;
}
}
/**
* 反序列化复杂Collection如List<Bean>, 先使用函數createCollectionType构造类型,然后调用本函数.
* @see #createCollectionType(Class, Class...)
*/
@SuppressWarnings("unchecked")
public <T> T fromJson(String jsonString, JavaType javaType) {
if (StringUtils.isEmpty(jsonString)) {
return null;
}
try {
return (T) this.readValue(jsonString, javaType);
} catch (IOException e) {
logger.warn("parse json string error:" + jsonString, e);
return null;
}
}
/**
* 構造泛型的Collection Type如:
* ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class)
* HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class)
*/
public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return this.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
/**
* 當JSON裡只含有Bean的部分屬性時,更新一個已存在Bean,只覆蓋該部分的屬性.
*/
@SuppressWarnings("unchecked")
public <T> T update(String jsonString, T object) {
try {
return (T) this.readerForUpdating(object).readValue(jsonString);
} catch (JsonProcessingException e) {
logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
} catch (IOException e) {
logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
}
return null;
}
/**
* 輸出JSONP格式數據.
*/
public String toJsonP(String functionName, Object object) {
return toJson(new JSONPObject(functionName, object));
}
/**
* 設定是否使用Enum的toString函數來讀寫Enum,
* 為False時時使用Enum的name()函數來讀寫Enum, 默認為False.
* 注意本函數一定要在Mapper創建後, 所有的讀寫動作之前調用.
*/
public JsonMapper enableEnumUseToString() {
this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
return this;
}
/**
* 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。
* 默认会先查找jaxb的annotation,如果找不到再找jackson的。
*/
public JsonMapper enableJaxbAnnotation() {
JaxbAnnotationModule module = new JaxbAnnotationModule();
this.registerModule(module);
return this;
}
/**
* 允许单引号
* 允许不带引号的字段名称
*/
public JsonMapper enableSimple() {
this.configure(Feature.ALLOW_SINGLE_QUOTES, true);
this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
return this;
}
/**
* 取出Mapper做进一步的设置或使用其他序列化API.
*/
public ObjectMapper getMapper() {
return this;
}
/**
* 对象转换为JSON字符串
* @param object
* @return
*/
public static String toJsonString(Object object){
return JsonMapper.getInstance().toJson(object);
}
/**
* JSON字符串转换为对象
* @param jsonString
* @param clazz
* @return
*/
public static Object fromJsonString(String jsonString, Class<?> clazz){
return JsonMapper.getInstance().fromJson(jsonString, clazz);
}
/**
* 测试
*/
public static void main(String[] args) {
List<Map<String, Object>> list = Lists.newArrayList();
Map<String, Object> map = Maps.newHashMap();
map.put("id", 1);
map.put("pId", -1);
map.put("name", "根节点");
list.add(map);
map = Maps.newHashMap();
map.put("id", 2);
map.put("pId", 1);
map.put("name", "你好");
map.put("open", true);
list.add(map);
// String json = JsonMapper.getInstance().toJson(list);
}
}
package com.loit.common.spring.timeloit.constant;
/**
* 通用常量
*
* @author wbh
* add by 2020-02-15
*/
public interface CommonConstant {
/**
* 客户端ip-请求头
*/
public String CLIENT_IP_REQUEST_HEADER = "client_ip_request_header";
}
package com.loit.common.spring.timeloit.utils;
/**
* 日志工具类-非数据层面的日志工具类
* Demon add by 2020-07-07
*/
public class LogUtil {
public static String print(String msg){
return "############--- " + msg + " ---############";
}
}
package com.loit.common.spring.timeloit.utils;
/**
* @ClassName LoitStatusCode
* @Description: 系统状态码 编码:3位状态码中,第一位代表一个应用
* @Author gzx
* @Date 2019-10-17
* @Version V1.0
**/
public enum LoitStatusCode {
/**
* 登录相关
*/
SUCESS("100","成功"),
FAIL("101","失败"),
UNKNOWN_EXCEPTION("102","未知异常,请联系管理员"),
USER_UNREGISTERED("103","用户未注册"),
USER_FORBID("104","用户被禁止登录"),
USER_PASSWORD_FAIL("105","登录失败"),
USER_TOKEN_ERRO("106","TOKEN验证错误"),
USER_TOKEN_INVALID("107","TOKEN验证失效"),
USER_ILLEGAL_AUTH("109","非法授权"),
USER_SESSION_ERRO("110","session验证错误"),
USER_SESSION_INVALID("111","session验证失效"),
USER_ACCOUNT_EXISTED("112","账号已经存在"),
USER_NAME_EXISTED("113","人员名称已经存在"),
/**
* 服务相关
*/
SERVICE_NOT_ONLINE_FOR_LOIT_PORTAL_ERROR("190", "loit-portal服务未在线"),
APP_ORG_ASSIGN("114","应用组织权限已分配"),
PRIMARY_KEY_ISNULL("115","主键为空"),
APP_IS_EXIST("116", "保存失败,应用已存在"),
SAVE_EXCEPTION("117", "保存异常,请联系管理员"),
UPDATE_EXCEPTION("118", "修改异常,请联系管理员"),
DELETE_EXCEPTION("119", "删除异常,请联系管理员"),
DISTRIBUTE_RESOURCES_EXCEPTION("120", "分配资源异常,请联系管理员"),
APP_ID_ISNULL("121", "应用id为空"),
CONTEXT_IS_EXIST("122", "保存失败,上下文配置已存在"),
RESOURCETYPE_IS_EXIST("123", "保存失败,资源类别已存在"),
MENU_IS_EXIST("124", "保存失败,菜单已存在"),
DICT_IS_EXIST("125", "保存失败,字典已存在"),
DICTDATA_IS_EXIST("126", "保存失败,字典项已存在"),
MENULAYOUT_IS_EXIST("127", "保存失败,菜单布局已存在"),
SKIN_IS_EXIST("128", "保存失败,皮肤设置已存在"),
RESOURCETYPE_OPERATION_IS_EXIST("129", "保存失败,资源类别操作已存在"),
ORG_NAME_IS_EXIST("130", "组织已存在"),
APPLICATION_APP_CODE_ERRO("131", "appCode无效"),
APPLICATION_APP_ID_CODE_SIMULTANEOUSLYEXIST_ERRO("131", "appId和appCode不能同时存在"),
ROLE_ID_CODE_PARAM_ISNULL("132", "角色Id和角色编码不能同时存在也不能同时为空"),
ROLE_IS_NOT_NULL("133", "用户至少需要有一个角色"),
FILE_PATH_ISNULL("140", "文件路径为空"),
FILE_ISNULL("141", "文件为空"),
FILE_UPLOAD_FAILED("142", "文件上传失败"),
FILE_NOT_EXIST("143", "文件不存在"),
FILE_DOWNLOAD_FAILED("144", "文件下载失败"),
FILE_DELETE_FAILED("145", "删除文件失败"),
FILE_SERVER_CONNECTION_FAILED("146", "文件服务器连接失败"),
FILE_OUT_SIZE("147", "文件超过大小"),
FILE_TYPE_ERROR_IMAGE("148", "图片类型错误"),
FILE_TYPE_ERROR_DOC("149", "文档类型错误"),
FILE_TYPE_ERROR_VIDEO("140", "音频类型错误"),
FILE_TYPE_ERROR_COMPRESS("141", "压缩文件类型错误"),
FILE_TYPE_ERROR_ALLOW("142", "不是允许的文件类型"),
REDIS_LINK_FAIL("145","redis连接异常"),
GRP_ADD_ORG_FAIL("146","该组织已添加"),
GRP_ADD_PERSON_FAIL("147","该用户已添加"),
GRP_NOT_EXIST("148","用户组不存在"),
GRP_NAME_EXISTED("149","用户组名称已存在"),
/**
* 单点登录相关 TODO DEMN cas statuscode 需要修改
*/
CAS_URI_RESOLVE_ERROR("151", "CAS AccessToken换取用户信息的回调URI解析错误"),
CAS_REDIRECT_URL_NOT_USERNAME_ERROR("152", "CAS AccessToken换取用户信息的回调URI没有用户登录名称"),
CAS_USER_AUTH_FAIL("153","用户认证失败, 用户未登录或登录过期"),
CAS_USER_TOKEN_NOT_FOUND("154", "AccessToken 头部参数没找到"),
CAS_AUTHENTICATION_FAIL("155", "无权限访问该资源"),
CAS_AUTHENTICATION_NOT_APPID_FAIL("156", "鉴权失败,缓存中没有当前用户操作的应用id"),
CAS_NOT_IN_APPOINT_AREA("157", "不在指定区域,无法登录"),
CAS_LOGIN_FAIL("158", "登录失败"),
CAS_PARAMS_ERROR("159", "参数错误"),
CURRENT_USER_ERROR("160", "无用户信息"),
/**
* 密码策略相关
*/
POLICY_PASSWORD_SUCCESS("161", "密码格式正确"),
POLICY_PASSWORD_LENGTH_ERR("162", "密码长度错误"),
POLICY_PASSWORD_MIXLEVEL_ERR("163", "密码格式错误"),
POLICY_PASSWORD_NOT_NULL("164", "密码不能为空"),
/**
* 移动端相关
*/
APP_MOBILE_OLD_PASSWORD_ERR("165", "旧密码错误"),
/**
* 限流相关
*/
SENTINEL_BLOCK_ERROR("444", "系统繁忙请稍后再试");
/**
* 状态编码号
*/
public String statusCode;
/**
* 状态描述
*/
public String statusDesc;
/**
* 构造函数
* @param statusCode
* @param statusDesc
*/
LoitStatusCode(String statusCode,String statusDesc){
this.statusCode = statusCode;
this.statusDesc = statusDesc;
}
}
package com.loit.common.spring.timeloit.utils;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
/**
* @author xutao
* @description 实体转换类
* @date 2019-10-18
*/
public class ModelMapperUtils {
private static class ModelMapperInstance{
private final static ModelMapper modelMapper = new ModelMapper();
}
public static <D> D map(Object source,Class<D> destinationType){
return getInstance().map(source,destinationType);
}
public static ModelMapper getInstance(){
//设置完全匹配以及严格匹配,只有属性名完全相同才可以进行匹配和填充
ModelMapperInstance.modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
ModelMapperInstance.modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
return ModelMapperInstance.modelMapper;
}
}
package com.loit.common.spring.timeloit.utils;
public interface RedisConstants {
// 根据access_token换取userId
String LOIT_CAS_USERID_BY_ACCESSTOKEN ="loit:cas:userId:{accessToken}";
// 根据userId换取权限范围内的资源列表
String LOIT_CAS_RESOURCEMANAGES_BY_USERID = "loit:cas:resourceManages:{userId}";
// 根据appId换取应用内的资源列表
String LOIT_CAS_RESOURCEMANAGES_BY_APPID = "loit:cas:resourceManages:{appId}";
// 根据userId换取应用id
String LOIT_CAS_APPID_BY_USERID = "loit:cas:appId:{userId}";
//根据dictId获取字典数据项
String CACHE_DICT_KEY = "portal:dictdata:{dictId}";
//根据userId获取缓存用户信息
String PORTAL_USER_KEY = "portal:user:{userId}";
}
package com.loit.common.validator;
import java.lang.reflect.Field;
import com.loit.common.annotation.LoitValidateAnnotation.LoitValidate;
import com.loit.common.json.AjaxJson;
import io.swagger.annotations.ApiModelProperty;
/**
* 属性验证解析器
* @author wbh
* @date 2018年12月9日
*/
public class LoitValidaters {
public static final String LENGTH_INFO = "超过定义长度";
public static final String IS_NOT_NUL_INFO = "不能为空";
/**
* 常用验证(不为空,长度限制)
* @author wbh
* @date:2018年12月9日
* @param obj
* @return
* @throws Exception
*/
public static AjaxJson validateField(Object obj) throws Exception{
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//打开私有访问
field.setAccessible(true);
// String name = field.getName();
//获取属性值
Object value = field.get(obj);
String name=null;
//获取swagger注释信息做校验
ApiModelProperty myApiModelProperty = field.getAnnotation(ApiModelProperty.class);
if(myApiModelProperty!=null) {
name = myApiModelProperty.value();
if(name==null) name = field.getName();
if(myApiModelProperty.required()&&value==null) {//验证不为空
return AjaxJson.returnExceptionInfo(name+IS_NOT_NUL_INFO);
}
}
LoitValidate myFieldAnnotation = field.getAnnotation(LoitValidate.class);
if(myFieldAnnotation!=null) {
if(name==null) name = myFieldAnnotation.name();
if(name==null) name = field.getName();
if(myFieldAnnotation.isNotNull()&&value == null) {//验证不为空
return AjaxJson.returnExceptionInfo(name+IS_NOT_NUL_INFO);
}
if(myApiModelProperty!=null&&myApiModelProperty.required()&&myFieldAnnotation.length()!=0) {//验证长度限制
int len = value.toString().length();
if(len>myFieldAnnotation.length()) {
AjaxJson json = new AjaxJson();
json.setSuccess(false);
json.setCode("-3");
json.setMsg(name+LENGTH_INFO+":"+myFieldAnnotation.length());
return json;
}
}
}
field.setAccessible(false);
}
return null;
}
public static boolean validateFieldBoolean(Object obj) throws Exception{
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
LoitValidate myFieldAnnotation = field.getAnnotation(LoitValidate.class);
if(myFieldAnnotation!=null) {
//打开私有访问
field.setAccessible(true);
// String name = field.getName();
//获取属性值
Object value = field.get(obj);
if(myFieldAnnotation.isNotNull()) {//验证不为空
if(value == null) {
return false;
}
}
if(myFieldAnnotation.length()!=0) {//验证长度限制
int len = value.toString().length();
if(len>myFieldAnnotation.length()) {
return false;
}
}
}
}
return true;
}
}
package com.loit.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Description: 方法执行抛出异常aop自定义注解
* @author: gzx
* @date: 2019年10月26日 上午10:45:48
* @version: V1.0
*/
@Target(ElementType.METHOD) //定义是用在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface AfterReturnAuditAnnotation {
}
package com.loit.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Description: 方法执行后aop自定义注解
* @author: gzx
* @date: 2019年10月26日 上午10:45:48
* @version: V1.0
*/
@Target(ElementType.METHOD) //定义是用在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface AfterThrowAuditAnnotation {
}
package com.loit.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Description: 方法执行前aop自定义注解
* @author: gzx
* @date: 2019年10月26日 上午10:45:48
* @version: V1.0
*/
@Target(ElementType.METHOD) //定义是用在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface BeforeAuditAnnotation {
String param() default "";
}
package com.loit.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 加密注解
* @author gyaoyy
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CryptoType {
Type value() default Type.NONE;
enum Type {
/**
* 无
*/
NONE,
/**
* 签名
*/
SIGN,
/**
* 加密
*/
CRYPTO
}
}
package com.loit.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* bean中文名注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {
String value();
}
package com.loit.common.annotation;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* 字典相关注释
* @author wbh
* @date 2019年1月4日
*/
public class LoitDictAnnotation {
/**
*
* @author wbh
*
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface LoitDict {
String tableName() default "loit_dict_data";
String dictCode();
}
}
package com.loit.common.annotation;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* 自定义注释,属性验证
* @author wbh
* @date 2018年12月9日
*/
public class LoitValidateAnnotation {
/**
* 属性验证
*
* @author wbh
*
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface LoitValidate {
@Deprecated
boolean isNotNull() default false;
int length() default 0;
int max() default Integer.MAX_VALUE;
@Deprecated
String name() default "";
}
}
\ No newline at end of file
package com.loit.common.aspect;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.jms.Destination;
import javax.servlet.http.HttpServletRequest;
import org.apache.activemq.command.ActiveMQQueue;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import com.alibaba.fastjson.JSON;
import com.loit.common.constant.AuditConstants;
import com.loit.common.constant.CommonConstant;
import com.loit.common.utils.StringUtils;
import com.loit.loitcasclient.utils.ClientSpringContextUtil;
import com.loit.loitcasclient.utils.ClientTokenUtil;
import com.loit.loitcasclient.utils.ClientUserUtil;
/**
* @Description: 审计切面
* @author: gzx
* @date: 2019年10月26日 上午11:07:21
* @version: V1.0
*/
@Aspect
@Component
public class AuditAspect {
private Logger logger = LoggerFactory.getLogger(AuditAspect.class);
@Autowired
private JmsTemplate jmsTemplate;
public static final Destination destination = new ActiveMQQueue(AuditConstants.AUDIT_MESSAGE);
/**
* @param @param joinPoint 参数
* @return void 返回类型
* @throws
* @Description: 前置通知
* @author: gzx
* @date: 2019年10月26日 上午11:25:56
*/
@Before("@annotation(com.loit.common.annotation.BeforeAuditAnnotation)")
public void doBefore(JoinPoint joinPoint) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("auditType", AuditConstants.AUDIT_TYPE_BEFORE);
// 组装数据
this.assemblyData(map, joinPoint);
// 发送信息至mq,实现异步处理
jmsTemplate.convertAndSend(destination, map);
}
/**
* @param @param joinPoint 参数
* @return void 返回类型
* @throws
* @Description: 后置通知
* @author: gzx
* @date: 2019年10月26日 上午11:43:28
*/
@AfterReturning(value = "@annotation(com.loit.common.annotation.AfterReturnAuditAnnotation)", returning = "returnValue")
public void doAfterReturning(JoinPoint joinPoint, Object returnValue) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("auditType", AuditConstants.AUDIT_TYPE_AFTERRETURN);
map.put("returnValue", returnValue);
// 组装数据
this.assemblyData(map, joinPoint);
// 发送信息至mq,实现异步处理
jmsTemplate.convertAndSend(destination, map);
logger.info("****已经进入后置通知*****");
}
/**
* @param @param e 参数
* @return void 返回类型
* @throws
* @Description: 后置抛出异常
* @author: gzx
* @date: 2019年10月26日 下午3:52:58
*/
@AfterThrowing(value = "@annotation(com.loit.common.annotation.AfterThrowAuditAnnotation)", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Exception e) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("auditType", AuditConstants.AUDIT_TYPE_AFTERTHROW);
map.put("exceptionStr", e.getMessage());
// 组装数据
this.assemblyData(map, joinPoint);
// 发送信息至mq,实现异步处理
jmsTemplate.convertAndSend(destination, map);
}
private void assemblyData(Map<String, Object> map, JoinPoint joinPoint) {
//用的最多 通知的签名
Signature signature = joinPoint.getSignature();
map.put("className", signature.getDeclaringTypeName());
map.put("method", signature.getName());
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
//如果要获取Session信息的话,可以这样写:
//HttpSession session = (HttpSession) requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
//获取请求参数
// Enumeration<String> enumeration = request.getParameterNames();
// Map<String, String> parameterMap = Maps.newHashMap();
// while (enumeration.hasMoreElements()) {
// String parameter = enumeration.nextElement();
// parameterMap.put(parameter, request.getParameter(parameter));
// }
// String str = JSON.toJSONString(parameterMap);
// map.put("args", str);
Object[] parameterValues = joinPoint.getArgs();
String args = "";
if (parameterValues != null && parameterValues.length > 0) {
args = JSON.toJSONString(parameterValues[0]);
}
map.put("args", args);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
map.put("actDate", sdf.format(new Date()));
//获取userId
String userId = request.getHeader(CommonConstant.AUTHORIZATION);
// String accessToken = ClientTokenUtil.cookieAccessToken();
// if (StringUtils.isNotEmpty(accessToken)) {
// ClientUserUtil clientUserUtil = (ClientUserUtil) ClientSpringContextUtil.getBean("clientUserUtil");
// userId = clientUserUtil.getUserId(accessToken);
// }
map.put("userId", userId);
}
}
package com.loit.common.cache;
import com.loit.common.cache.exception.CacheException;
import java.util.List;
/**
* Description: 定义缓存操作接口
* Author: yangwenbin
* Date: Created in 2020/5/29 8:43
* Version: 1.0
* Modified By:
*/
public interface Cache {
/**
* 读取缓存
* @param key
* @return
* @throws CacheException
*/
Object get(String key) throws CacheException;
/**
* 写入缓存
* @param key
* @param value
* @return
* @throws CacheException
*/
boolean set(String key, Object value) throws CacheException;
/**
* 写入缓存
* @param key
* @param value
* @param expireTime 有效期
* @return
* @throws CacheException
*/
boolean set(String key, Object value,Long expireTime) throws CacheException;
/**
* 批量删除对应的key
* @param keys
* @throws CacheException
*/
void remove(String ... keys) throws CacheException;
/**
* 删除对应的key
* @param key
* @throws CacheException
*/
void remove(String key) throws CacheException;
/**
* 批量删除匹配的key
* @param pattern
* @throws CacheException
*/
void removePattern(String pattern) throws CacheException;
/**
* 判断是否存在key
* @param key
* @return
*/
boolean exists(final String key) throws CacheException;
/**
* 向集合中添加一个元素,从左到右 redis有效
* @param key
* @param value
* @return
* @throws CacheException
*/
boolean lpush(final String key,Object value) throws CacheException;
/**
* 向集合中添加一个元素,从左到右,有效期
* @param key
* @param value
* @param expireTime
* @return
* @throws CacheException
*/
boolean lpush(final String key,Object value,Long expireTime) throws CacheException;
/**
* 获取List集合
* @param key
* @return
* @throws CacheException
*/
List<Object> getList(final String key) throws CacheException;
}
package com.loit.common.cache.ehcache;
import com.loit.common.cache.Cache;
import com.loit.common.cache.exception.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.regex.Pattern;
/**
* Description: TODO
* Author: yangwenbin
* Date: Created in 2020/5/29 17:39
* Version: 1.0
* Modified By:
*/
public class EhcacheCache implements Cache {
private static Logger logger = LoggerFactory.getLogger(EhcacheCache.class);
public static CacheManager cacheManager;
private net.sf.ehcache.Cache cache;
static{
try {
cacheManager = CacheManager.getInstance();
if(cacheManager==null)
cacheManager = CacheManager.create();
} catch (CacheException e) {
logger.error("Initialize cache manager failed.", e);
}
}
public EhcacheCache(String cacheName){
cache = cacheManager.getCache(cacheName);
if(cache == null){
cacheManager.addCache(cacheName);
cache = cacheManager.getCache(cacheName);
cache.getCacheConfiguration().setEternal(true);
}
}
@Override
public Object get(String key) throws CacheException {
final Element element = cache.get(key);
return element.getObjectValue();
}
@Override
public boolean set(String key, Object value) throws CacheException {
final Element element = new Element(key, value);
cache.put(element);
return true;
}
@Override
public boolean set(String key, Object value, Long expireTime) throws CacheException {
final Element element = new Element(key, value);
element.setTimeToLive(Integer.valueOf(expireTime.toString()));
cache.put(element);
return true;
}
@Override
public void remove(String... keys) throws CacheException {
for(String key : keys){
cache.remove(key);
}
}
@Override
public void remove(String key) throws CacheException {
cache.remove(key);
}
@Override
public void removePattern(String pattern) throws CacheException {
List keyList = cache.getKeys();
Pattern p = Pattern.compile(pattern);
for(Object obj : keyList){
String key = String.valueOf(obj);
if(p.matcher(key).find()){
cache.remove(key);
}
}
}
@Override
public boolean exists(String key) throws CacheException {
Object object = cache.get(key);
if(object != null){
return true;
}
return false;
}
@Override
public boolean lpush(String key, Object value) throws CacheException {
final Element element = new Element(key, value);
cache.put(element);
return true;
}
@Override
public boolean lpush(String key, Object value, Long expireTime) throws CacheException {
final Element element = new Element(key, value);
element.setTimeToLive(Integer.parseInt(expireTime.toString()));
cache.put(element);
return true;
}
@Override
public List<Object> getList(String key) throws CacheException {
final Element element = cache.get(key);
return (List< Object >) element.getObjectValue();
}
}
package com.loit.common.cache.exception;
/**
* Description: TODO
* Author: yangwenbin
* Date: Created in 2020/5/28 19:03
* Version: 1.0
* Modified By:
*/
public class CacheException extends RuntimeException {
private static final long serialVersionUID = 142468800110101833L;
public CacheException() {
}
public CacheException(String message) {
super(message);
}
public CacheException(String message, Throwable cause) {
super(message, cause);
}
public CacheException(Throwable cause) {
super(cause);
}
}
\ No newline at end of file
package com.loit.common.cache.redis;
import com.loit.common.cache.Cache;
import com.loit.common.cache.exception.CacheException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Description: redis缓存实现
* Author: yangwenbin
* Date: Created in 2020/5/29 8:43
* Version: 1.0
* Modified By:
*/
public class RedisCache implements Cache {
private long expireTime = 3600;// 缓存的超时时间,单位为s
@Autowired
private RedisTemplate redisTemplate;// 通过构造方法注入该对象
public RedisCache() {
super();
}
public RedisCache( RedisTemplate redisTemplate) {
super();
this.redisTemplate = redisTemplate;
}
@Override
public Object get(String key) throws CacheException {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
@Override
public boolean set(String key, Object value) throws CacheException {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public boolean set(String key, Object value, Long expireTime) throws CacheException {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public void remove(String... keys) throws CacheException {
for(String key : keys){
remove(key);
}
}
@Override
public void remove(String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
@Override
public void removePattern(String pattern) throws CacheException {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
public boolean lpush(final String key,Object value){
boolean result = false;
try {
ListOperations<Serializable, Object> operations = redisTemplate.opsForList();
operations.leftPush(key,value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
public boolean lpush(String key, Object value, Long expireTime) throws CacheException {
boolean result = false;
try {
ListOperations<Serializable, Object> operations = redisTemplate.opsForList();
operations.leftPush(key,value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public List<Object> getList(final String key){
List<Object> list=null;
try {
ListOperations<Serializable, Object> operations = redisTemplate.opsForList();
list = operations.range(key,0,-1);
}catch (Exception e){
e.printStackTrace();
}
return list;
}
@Override
public boolean exists(String key) {
return redisTemplate.hasKey(key);
}
}
package com.loit.common.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ConditionalOnProperty(name = "spring.cache.type", havingValue = "ehcache")
@Configuration
@EnableCaching//标注启动缓存.
public class EhCacheConfig {
/**
* @param ehCacheManagerFactoryBean
* @return
*/
@Bean
public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean ehCacheManagerFactoryBean){
System.out.println("CacheConfiguration.ehCacheCacheManager()");
return new EhCacheCacheManager(ehCacheManagerFactoryBean.getObject());
}
/*
* 据shared与否的设置,
* Spring分别通过CacheManager.create()
* 或new CacheManager()方式来创建一个ehcache基地.
*/
@Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
System.out.println("CacheConfiguration.ehCacheManagerFactoryBean()");
EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean ();
cacheManagerFactoryBean.setShared(true);
return cacheManagerFactoryBean;
}
}
package com.loit.common.config;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
import com.netflix.hystrix.strategy.properties.HystrixProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 自定义Feign的隔离策略;
* 在转发Feign的请求头的时候,如果开启了Hystrix,Hystrix的默认隔离策略是Thread(线程隔离策略)
* ,因此转发拦截器内是无法获取到请求的请求头信息的
* ,可以修改默认隔离策略为信号量模式:hystrix.command.default.execution.isolation.strategy=SEMAPHORE
* ,这样的话转发线程和请求线程实际上是一个线程,这并不是最好的解决方法,信号量模式也不是官方最为推荐的隔离策略;
* 另一个解决方法就是自定义Hystrix的隔离策略,思路是将现有的并发策略作为新并发策略的成员变量
* ,在新并发策略中,返回现有并发策略的线程池、Queue;将策略加到Spring容器即可;
*
* @author mozping
* @version 1.0
* @date 2018/7/5 9:08
* @see FeignHystrixConcurrencyStrategyIntellif
* @since JDK1.8
*/
@Component
public class FeignHystrixConcurrencyStrategyIntellif extends HystrixConcurrencyStrategy {
private static final Logger log = LoggerFactory.getLogger(FeignHystrixConcurrencyStrategyIntellif.class);
private HystrixConcurrencyStrategy delegate;
public FeignHystrixConcurrencyStrategyIntellif() {
try {
this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
if (this.delegate instanceof FeignHystrixConcurrencyStrategyIntellif) {
// Welcome to singleton hell...
return;
}
HystrixCommandExecutionHook commandExecutionHook =
HystrixPlugins.getInstance().getCommandExecutionHook();
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy =
HystrixPlugins.getInstance().getPropertiesStrategy();
this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy);
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
} catch (Exception e) {
log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
}
}
private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier,
HystrixMetricsPublisher metricsPublisher, HystrixPropertiesStrategy propertiesStrategy) {
if (log.isDebugEnabled()) {
log.debug("Current Hystrix plugins configuration is [" + "concurrencyStrategy ["
+ this.delegate + "]," + "eventNotifier [" + eventNotifier + "]," + "metricPublisher ["
+ metricsPublisher + "]," + "propertiesStrategy [" + propertiesStrategy + "]," + "]");
log.debug("Registering Sleuth Hystrix Concurrency Strategy.");
}
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return new WrappedCallable<>(callable, requestAttributes);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize,
HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime,
unit, workQueue);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
HystrixThreadPoolProperties threadPoolProperties) {
return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);
}
@Override
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
return this.delegate.getBlockingQueue(maxQueueSize);
}
@Override
public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) {
return this.delegate.getRequestVariable(rv);
}
static class WrappedCallable<T> implements Callable<T> {
private final Callable<T> target;
private final RequestAttributes requestAttributes;
public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {
this.target = target;
this.requestAttributes = requestAttributes;
}
@Override
public T call() throws Exception {
try {
if(requestAttributes!=null)
RequestContextHolder.setRequestAttributes(requestAttributes);
return target.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}
\ No newline at end of file
package com.loit.common.config;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
import java.util.Properties;
import org.apache.ibatis.io.Resources;
import org.springframework.core.io.DefaultResourceLoader;
import com.google.common.collect.Maps;
import com.loit.common.utils.PropertiesLoader;
import com.loit.common.utils.StringUtils;
/**
* 全局配置类
* @author loit
* @version 2014-06-25
*/
public class Global {
/**
* 当前对象实例
*/
private static Global global = new Global();
/**
* 保存全局属性值
*/
private static Map<String, String> map = Maps.newHashMap();
/**
* 属性文件加载对象
*/
private static PropertiesLoader loader = new PropertiesLoader("/config/custom.properties");
/**
* 显示/隐藏
*/
public static final String SHOW = "1";
public static final String HIDE = "0";
/**
* 是/否
*/
public static final String YES = "1";
public static final String NO = "0";
/**
* 对/错
*/
public static final String TRUE = "true";
public static final String FALSE = "false";
/**
* 上传文件基础虚拟路径
*/
public static final String USERFILES_BASE_URL = "/userfiles/";
/**
* 获取当前对象实例
*/
public static Global getInstance() {
return global;
}
public static String HOSTIP;
/**
* 获取配置
* @see ${fns:getConfig('adminPath')}
*/
public static String getConfig(String key) {
String value = map.get(key);
if (value == null){
value = loader.getProperty(key);
map.put(key, value != null ? value : StringUtils.EMPTY);
}
return value;
}
/**
* 获取管理端根路径
*/
public static String getAdminPath() {
return getConfig("adminPath");
}
/**
* 获取前端根路径
*/
public static String getFrontPath() {
return getConfig("frontPath");
}
/**
* 获取URL后缀
*/
public static String getUrlSuffix() {
return getConfig("urlSuffix");
}
/**
* 是否是演示模式,演示模式下不能修改用户、角色、密码、菜单、授权
*/
public static Boolean isDemoMode() {
String dm = getConfig("demoMode");
return "true".equals(dm) || "1".equals(dm);
}
/**
* 在修改系统用户和角色时是否同步到Activiti
*/
public static Boolean isSynActivitiIndetity() {
String dm = getConfig("activiti.isSynActivitiIndetity");
return "true".equals(dm) || "1".equals(dm);
}
/**
* 页面获取常量
* @see ${fns:getConst('YES')}
*/
public static Object getConst(String field) {
try {
return Global.class.getField(field).get(null);
} catch (Exception e) {
// 异常代表无配置,这里什么也不做
}
return null;
}
/**
* 获取上传文件的根目录
* @return
*/
public static String getUserfilesBaseDir() {
String dir = getConfig("userfiles.basedir");
if (StringUtils.isBlank(dir)){
try {
// dir = ServletContextFactory.getServletContext().getRealPath("/");
} catch (Exception e) {
return "";
}
}
if(!dir.endsWith("/")) {
dir += "/";
}
return dir;
}
/**
* 获取工程路径
* @return
*/
public static String getProjectPath(){
// 如果配置了工程路径,则直接返回,否则自动获取。
String projectPath = Global.getConfig("projectPath");
if (StringUtils.isNotBlank(projectPath)){
return projectPath;
}
try {
File file = new DefaultResourceLoader().getResource("").getFile();
if (file != null){
while(true){
File f = new File(file.getPath() + File.separator + "src" + File.separator + "main");
if (f == null || f.exists()){
break;
}
if (file.getParentFile() != null){
file = file.getParentFile();
}else{
break;
}
}
projectPath = file.toString();
}
} catch (IOException e) {
e.printStackTrace();
}
return projectPath;
}
/**
* 写入properties信息
*
* @param key
* 名称
* @param value
* 值
*/
public static void modifyConfig(String key, String value) {
try {
// 从输入流中读取属性列表(键和元素对)
Properties prop = getProperties();
prop.setProperty(key, value);
String path = Global.class.getResource("/config/custom.properties").getPath();
FileOutputStream outputFile = new FileOutputStream(path);
prop.store(outputFile, "modify");
outputFile.close();
outputFile.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 返回 Properties
* @param fileName 文件名 (注意:加载的是src下的文件,如果在某个包下.请把包名加上)
* @param
* @return
*/
public static Properties getProperties(){
Properties prop = new Properties();
try {
Reader reader = Resources.getResourceAsReader("/config/custom.properties");
prop.load(reader);
} catch (Exception e) {
return null;
}
return prop;
}
}
package com.loit.common.config;
import java.nio.charset.StandardCharsets;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
public RestTemplate commRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
return restTemplate;
}
}
package com.loit.common.config;
import java.util.Locale;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
*
* @ClassName: SpringContextUtil
* @Description: SpringContext相关
* @author gaodengyun
* @date 2019年5月11日 上午11:59:02
*
*/
@Component
@SuppressWarnings({"unchecked","static-access"})
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
}
// 传入线程中
public static <T> T getBean(String beanName) {
return (T) context.getBean(beanName);
}
// 国际化使用
public static String getMessage(String key) {
return context.getMessage(key, null, Locale.getDefault());
}
/// 获取当前环境
public static String getActiveProfile() {
return context.getEnvironment().getActiveProfiles()[0];
}
}
package com.loit.common.config;
import static com.google.common.collect.Lists.newArrayList;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger配置
* @author wbh
* @date 2018年12月15日
*/
@Configuration
@EnableSwagger2
@SuppressWarnings("deprecation")
public class Swagger2 {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Value("${server.port}")
private String localPort;//文件上传的地址
@Value("${loit.swagger.basePackage}")
private String basePackage;//swagger引入其他包的集合
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.useDefaultResponseMessages(false)
.select()
.apis(Swagger2.basePackage(basePackage))
.paths(PathSelectors.any())
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
private List<ApiKey> securitySchemes() {
return newArrayList(
new ApiKey("Authorization", "accessToken", "header"));
}
private List<SecurityContext> securityContexts() {
return newArrayList(
SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$"))
.build()
);
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return newArrayList(
new SecurityReference("Authorization", authorizationScopes));
}
/**
* Predicate that matches RequestHandler with given base package name for the class of the handler method.
* This predicate includes all request handlers matching the provided basePackage
*
* @param basePackage - base package of the classes
* @return this
*/
public static Predicate<RequestHandler> basePackage(final String basePackage) {
return new Predicate<RequestHandler>() {
@Override
public boolean apply(RequestHandler input) {
return declaringClass(input).transform(handlerPackage(basePackage)).or(true);
}
};
}
/**
* 处理包路径配置规则,支持多路径扫描匹配以逗号隔开
*
* @param basePackage 扫描包路径
* @return Function
*/
private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
return new Function<Class<?>, Boolean>() {
@Override
public Boolean apply(Class<?> input) {
for (String strPackage : basePackage.split(",")) {
boolean isMatch = input.getPackage().getName().startsWith(strPackage);
if (isMatch) {
return true;
}
}
return false;
}
};
}
/**
* @param input RequestHandler
* @return Optional
*/
private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
return Optional.fromNullable(input.declaringClass());
}
private ApiInfo apiInfo() {
InetAddress address;
String hostAddress=null;
try {
address = InetAddress.getLocalHost();
hostAddress = address.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}//获取的是本地的IP地址
String projectName = Global.getConfig("productName");
return new ApiInfoBuilder()
.title(projectName+"api文档")
.description("v1.0 add by gaoyanyun (2514917157@qq.com) \n"
+ "v1.1 update by wangbh (wbh1211@qq.com)")
.termsOfServiceUrl("http://"+hostAddress+":"+localPort+"/swagger-ui.html")
.version("1.0")
.build();
}
}
package com.loit.common.config;
import com.loit.modules.sys.interceptor.LogInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 拦截器配置
*
* @author wbh
* @date 2018年12月3日
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Value("${fileUpload.uploadDir}")
private String uploadPath;//文件上传的地址
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 添加拦截器
registry.addInterceptor(securityInterceptor()).addPathPatterns("/**");
}
private HandlerInterceptor securityInterceptor() {
return new LogInterceptor();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//和页面有关的静态目录都放在项目的static目录下
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
//上传的图片在D盘下的img目录下,访问路径如:http://localhost:7007/image/d3cf0281-bb7f-40e0-ab77-406db95ccf2c.jpg
//其中image表示访问的前缀。"file:E:/img/"是文件真实的存储路径
logger.info("本地图片存储路径:" + uploadPath);
registry.addResourceHandler("/image/**").addResourceLocations("file:" + uploadPath);
}
/**
* 设置SpringBoot默认返回体Content-Type
*
* @param configurer
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
}
}
package com.loit.common.constant;
/**
* @Description: 审计常量定义
* @author: gzx
* @date: 2019年10月27日 下午4:59:38
* @version: V1.0
*/
public class AuditConstants {
//审计类型-调用方法前
public static String AUDIT_TYPE_BEFORE = "1";
//审计类型-调用方法后
public static String AUDIT_TYPE_AFTERRETURN = "2";
//审计类型-调用方法后异常
public static String AUDIT_TYPE_AFTERTHROW = "3";
//审计级别- 忽略
public static int AUDIT_LEVEL_IGNORE = -1;
/** 审计消息队列名 **/
public static String AUDIT_MESSAGE = "audit.message";
}
package com.loit.common.constant;
/**
* 网关通用常量
*
* @author wbh
* add by 2020-02-15
*/
public interface CommonConstant {
String TOKEN_NAME = "accessToken";
String AUTHORIZATION = "Authorization";
}
package com.loit.common.constant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 分页相关参数
* @author wbh12
* @date: 2020年6月6日
* add by wbh
*/
public enum LoitPageParamEnum {
PAGE_NO("pageNo", "当前页码"),
PAGE_SIZE("pageSize", "页面大小"),
REGARE("repage", "页面刷新"),
ORDER_BY("orderBy", "查询排序");
;
/**
* 状态值
*/
public String code;
/**
* 状态描述
*/
public String desc;
/**
* 构造函数
* @param code
* @param value
*/
LoitPageParamEnum(String code,String desc){
this.code = code;
this.desc = desc;
}
public static List<String> toList() {
List<String> list = new ArrayList<String>();
for (LoitPageParamEnum lppEnum : LoitPageParamEnum.values()) {
list.add(lppEnum.getCode());
}
return list;
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
package com.loit.common.exception;
/**
* 基础异常
*/
public class BusinessException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
//所属模块
private String module;
/**
* 错误码
*/
private String code;
/**
* Ba
* 错误码对应的参数
*/
private Object[] args;
/**
* 错误消息
*/
private String defaultMessage;
public BusinessException(String module, String code, Object[] args, String defaultMessage) {
super(defaultMessage);
this.module = module;
this.code = code;
this.args = args;
this.defaultMessage = defaultMessage;
}
public BusinessException(String module, String code, Object[] args) {
this(module, code, args, null);
}
public BusinessException(String module, String defaultMessage) {
this(module, null, null, defaultMessage);
}
public BusinessException(String code, Object[] args) {
this(null, code, args, null);
}
public BusinessException(String defaultMessage) {
this(null, null, null, defaultMessage);
}
public String getModule() {
return module;
}
public String getCode() {
return code;
}
public Object[] getArgs() {
return args;
}
public String getDefaultMessage() {
return defaultMessage;
}
@Override
public String toString() {
return this.getClass() + "{" +
"module='" + module + '\'' +
", message='" + getMessage() + '\'' +
'}';
}
}
package com.loit.common.exception;
/**
* Service层公用的Exception, 从由Spring管理事务的函数中抛出时会触发事务回滚.
*
* @author loit
*/
public class ServiceException extends BusinessException {
public ServiceException(String module, String code, Object[] args, String defaultMessage) {
super(module, code, args, defaultMessage);
}
public ServiceException(String module, String code, Object[] args) {
super(module, code, args);
}
public ServiceException(String module, String defaultMessage) {
super(module, defaultMessage);
}
public ServiceException(String code, Object[] args) {
super(code, args);
}
public ServiceException(String defaultMessage) {
super(defaultMessage);
}
}
package com.loit.common.json;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
public class PrintJSON {
public static void write(HttpServletResponse response,String content) {
response.reset();
response.setContentType("application/json");
response.setHeader("Cache-Control", "no-store");
response.setCharacterEncoding("UTF-8");
try {
PrintWriter pw=response.getWriter();
pw.write(content);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.loit.common.mapper;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
/**
* className:ConvertBlobTypeHandler
*
* 自定义typehandler,解决mybatis存储blob字段后,出现乱码的问题
* 配置mapper.xml:
* <result typeHandler="cn.ffcs.drive.common.util.ConvertBlobTypeHandler"/>
*
* @author lgf
* @version 1.0.0
* @date 2016-05-05 11:15:23
*
*/
@MappedJdbcTypes(JdbcType.BLOB)
public class ConvertBlobTypeHandler extends BaseTypeHandler<String> {//指定字符集
private static final String DEFAULT_CHARSET = "utf-8";
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
String parameter, JdbcType jdbcType) throws SQLException {
ByteArrayInputStream bis;
try {
bis = new ByteArrayInputStream(parameter.getBytes(DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
ps.setBinaryStream(i, bis, parameter.length());
}
@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Blob blob = rs.getBlob(columnName);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
Blob blob = cs.getBlob(columnIndex);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
@Override
public String getNullableResult(ResultSet arg0, int arg1) throws SQLException {
return null;
} }
package com.loit.common.mapper;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
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.fasterxml.jackson.databind.util.JSONPObject;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* 简单封装Jackson,实现JSON String<->Java Object的Mapper.
* 封装不同的输出风格, 使用不同的builder函数创建实例.
* @author loit
* @version 2013-11-15
*/
@SuppressWarnings("deprecation")
public class JsonMapper extends ObjectMapper {
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);
private static JsonMapper mapper;
public JsonMapper() {
//this(Include.NON_EMPTY);
}
public JsonMapper(Include include) {
// 设置输出时包含属性的风格
if (include != null) {
this.setSerializationInclusion(include);
}
// 允许单引号、允许不带引号的字段名称
this.enableSimple();
// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 空值处理为空串
this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
@Override
public void serialize(Object value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeString("");
}
});
// 进行HTML解码。
this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){
@Override
public void serialize(String value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeString(StringEscapeUtils.unescapeHtml4(value));
}
}));
// 设置时区
this.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00")
}
/**
* 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.
*/
public static JsonMapper getInstance() {
if (mapper == null){
mapper = new JsonMapper().enableSimple();
}
return mapper;
}
/**
* 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。
*/
public static JsonMapper nonDefaultMapper() {
if (mapper == null){
mapper = new JsonMapper(Include.NON_DEFAULT);
}
return mapper;
}
/**
* Object可以是POJO,也可以是Collection或数组。
* 如果对象为Null, 返回"null".
* 如果集合为空集合, 返回"[]".
*/
public String toJson(Object object) {
try {
return this.writeValueAsString(object);
} catch (IOException e) {
logger.warn("write to json string error:" + object, e);
return null;
}
}
/**
* 反序列化POJO或简单Collection如List<String>.
*
* 如果JSON字符串为Null或"null"字符串, 返回Null.
* 如果JSON字符串为"[]", 返回空集合.
*
* 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType)
* @see #fromJson(String, JavaType)
*/
public <T> T fromJson(String jsonString, Class<T> clazz) {
if (StringUtils.isEmpty(jsonString)) {
return null;
}
try {
return this.readValue(jsonString, clazz);
} catch (IOException e) {
logger.warn("parse json string error:" + jsonString, e);
return null;
}
}
/**
* 反序列化复杂Collection如List<Bean>, 先使用函數createCollectionType构造类型,然后调用本函数.
* @see #createCollectionType(Class, Class...)
*/
@SuppressWarnings("unchecked")
public <T> T fromJson(String jsonString, JavaType javaType) {
if (StringUtils.isEmpty(jsonString)) {
return null;
}
try {
return (T) this.readValue(jsonString, javaType);
} catch (IOException e) {
logger.warn("parse json string error:" + jsonString, e);
return null;
}
}
/**
* 構造泛型的Collection Type如:
* ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class)
* HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class)
*/
public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return this.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
/**
* 當JSON裡只含有Bean的部分屬性時,更新一個已存在Bean,只覆蓋該部分的屬性.
*/
@SuppressWarnings("unchecked")
public <T> T update(String jsonString, T object) {
try {
return (T) this.readerForUpdating(object).readValue(jsonString);
} catch (JsonProcessingException e) {
logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
} catch (IOException e) {
logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
}
return null;
}
/**
* 輸出JSONP格式數據.
*/
public String toJsonP(String functionName, Object object) {
return toJson(new JSONPObject(functionName, object));
}
/**
* 設定是否使用Enum的toString函數來讀寫Enum,
* 為False時時使用Enum的name()函數來讀寫Enum, 默認為False.
* 注意本函數一定要在Mapper創建後, 所有的讀寫動作之前調用.
*/
public JsonMapper enableEnumUseToString() {
this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
return this;
}
/**
* 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。
* 默认会先查找jaxb的annotation,如果找不到再找jackson的。
*/
public JsonMapper enableJaxbAnnotation() {
JaxbAnnotationModule module = new JaxbAnnotationModule();
this.registerModule(module);
return this;
}
/**
* 允许单引号
* 允许不带引号的字段名称
*/
public JsonMapper enableSimple() {
this.configure(Feature.ALLOW_SINGLE_QUOTES, true);
this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
return this;
}
/**
* 取出Mapper做进一步的设置或使用其他序列化API.
*/
public ObjectMapper getMapper() {
return this;
}
/**
* 对象转换为JSON字符串
* @param object
* @return
*/
public static String toJsonString(Object object){
return JsonMapper.getInstance().toJson(object);
}
/**
* JSON字符串转换为对象
* @param jsonString
* @param clazz
* @return
*/
public static Object fromJsonString(String jsonString, Class<?> clazz){
return JsonMapper.getInstance().fromJson(jsonString, clazz);
}
/**
* 测试
*/
public static void main(String[] args) {
List<Map<String, Object>> list = Lists.newArrayList();
Map<String, Object> map = Maps.newHashMap();
map.put("id", 1);
map.put("pId", -1);
map.put("name", "根节点");
list.add(map);
map = Maps.newHashMap();
map.put("id", 2);
map.put("pId", 1);
map.put("name", "你好");
map.put("open", true);
list.add(map);
// String json = JsonMapper.getInstance().toJson(list);
}
}
package com.loit.common.persistence;
/**
* DAO支持类实现
* @author loit
* @version 2014-05-16
*/
public interface BaseDao {
}
\ No newline at end of file
package com.loit.common.persistence;
import java.io.Serializable;
import java.util.Map;
import javax.xml.bind.annotation.XmlTransient;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Maps;
import com.loit.common.config.Global;
import com.loit.modules.sys.entity.User;
/**
* Entity支持类
* @author loit
* @version 2014-05-16
*/
public abstract class BaseEntity<T> implements Serializable{
/**
*
*/
private static final long serialVersionUID = 2362476363395495242L;
/**
* 当前用户
*/
protected User currentUser;
/**
* 当前实体分页对象
*/
protected Page<T> page;
/**
* 自定义SQL(SQL标识,SQL内容)
*/
protected Map<String, String> sqlMap;
/**
* 是否是新记录(默认:false),调用setIsNewRecord()设置新记录,使用自定义ID。
* 设置为true后强制执行插入语句,ID不会自动生成,需从手动传入。
*/
@JsonIgnore
protected boolean isNewRecord = false;
public BaseEntity() {
}
@JsonIgnore
@XmlTransient
public User getCurrentUser() {
return currentUser;
}
public void setCurrentUser(User currentUser) {
this.currentUser = currentUser;
}
@JsonIgnore
@XmlTransient
public Page<T> getPage() {
if (page == null){
page = new Page<T>();
}
return page;
}
public Page<T> setPage(Page<T> page) {
this.page = page;
return page;
}
@JsonIgnore
@XmlTransient
public Map<String, String> getSqlMap() {
if (sqlMap == null){
sqlMap = Maps.newHashMap();
}
return sqlMap;
}
public void setSqlMap(Map<String, String> sqlMap) {
this.sqlMap = sqlMap;
}
/**
* 插入之前执行方法,子类实现
*/
public abstract void preInsert();
/**
* 更新之前执行方法,子类实现
*/
public abstract void preUpdate();
/**
* 是否是新记录(默认:false),调用setIsNewRecord()设置新记录,使用自定义ID。
* 设置为true后强制执行插入语句,ID不会自动生成,需从手动传入。
*/
public void setIsNewRecord(boolean isNewRecord) {
this.isNewRecord = isNewRecord;
}
/**
* 全局变量对象
*/
@JsonIgnore
public Global getGlobal() {
return Global.getInstance();
}
/**
* 获取数据库名称
*/
@JsonIgnore
public String getDbName(){
return Global.getConfig("jdbc.type");
}
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
/**
* 删除标记(0:正常;1:删除;)
*/
public static final String DEL_FLAG_NORMAL = "0";
public static final String DEL_FLAG_DELETE = "1";
}
package com.loit.common.persistence;
import java.util.List;
import org.apache.ibatis.annotations.Param;
/**
* DAO支持类实现
* @author loit
* @version 2014-05-16
* @param <T>
*/
public interface CrudDao<T> extends BaseDao {
/**
* 获取单条数据
* @param id
* @return
*/
public T get(String id);
/**
* 获取单条数据
* @param id
* @return
*/
public T get(int id);
/**
* 获取单条数据
* @param entity
* @return
*/
public T get(T entity);
/**
* 根据ID列表获取多条数据
* @param ids
* @return
*/
public List<T> findByIdList(List<String> ids);
/**
* 根据实体名称和字段名称和字段值获取唯一记录
*
* @param <T>
* @param entityClass
* @param propertyName
* @param value
* @return
*/
public T findUniqueByProperty(@Param(value="propertyName")String propertyName, @Param(value="value")Object value);
/**
* 查询数据列表,如果需要分页,请设置分页对象,如:entity.setPage(new Page<T>());
* @param entity
* @return
*/
public List<T> findList(T entity);
/**
* 查询所有数据列表
* @param entity
* @return
*/
public List<T> findAllList(T entity);
/**
* 查询所有数据列表
* @see public List<T> findAllList(T entity)
* @return
*/
@Deprecated
public List<T> findAllList();
/**
* 插入数据
* @param entity
* @return
*/
public int insert(T entity);
/**
* 更新数据
* @param entity
* @return
*/
public int update(T entity);
/**
* 删除数据(物理删除,从数据库中彻底删除)
* @param id
* @see public int delete(T entity)
* @return
*/
@Deprecated
public int delete(String id);
/**
* 删除数据(逻辑删除,更新del_flag字段为1,在表包含字段del_flag时,可以调用此方法,将数据隐藏)
* @param id
* @see public int delete(T entity)
* @return
*/
@Deprecated
public int deleteByLogic(String id);
/**
* 删除数据(物理删除,从数据库中彻底删除)
* @param entity
* @return
*/
public int delete(T entity);
/**
* 删除数据(逻辑删除,更新del_flag字段为1,在表包含字段del_flag时,可以调用此方法,将数据隐藏)
* @param entity
* @return
*/
public int deleteByLogic(T entity);
}
\ No newline at end of file
package com.loit.common.persistence;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.hibernate.validator.constraints.Length;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.loit.common.constant.CommonConstant;
import com.loit.common.utils.StringUtils;
import com.loit.loitcasclient.utils.ClientSpringContextUtil;
import com.loit.loitcasclient.utils.ClientTokenUtil;
import com.loit.loitcasclient.utils.ClientUserUtil;
import com.loit.modules.sys.entity.User;
import io.swagger.annotations.ApiModelProperty;
/**
* 数据Entity类
* @author loit
* @version 2014-05-16
*/
public abstract class DataEntity<T> extends BaseEntity<T> {
private static final long serialVersionUID = 1-1082077813040196160L;
protected User createBy; // 创建者
@ApiModelProperty(hidden = true)
protected Date createTime; // 创建日期
protected User updateBy; // 更新者
@ApiModelProperty(hidden = true)
protected Date updateTime; // 更新日期
protected String delFlag; // 删除标记(0:正常;1:删除;)
public DataEntity() {
super();
this.delFlag = DEL_FLAG_NORMAL;
}
/**
* 插入之前执行方法,需要手动调用
*/
@Override
public void preInsert(){
User user = getUser();
this.updateBy = user;
this.createBy = user;
this.updateTime = new Date();
this.createTime = this.updateTime;
}
/**
* 更新之前执行方法,需要手动调用
*/
@Override
public void preUpdate(){
User user = getUser();
// DEMON modify by 2019-12-5: 登录后没有产生令牌, 是获取不到当前登录用户的, 但是需要更新用户的最后登录时间, 所以添加判断
if(user != null) {
this.updateBy = user;
}
this.updateTime = new Date();
}
@Override
public User getCurrentUser() {
if(currentUser == null){
currentUser = getUser();
}
return currentUser;
}
/**
* 获取当前用户缓存信息
*
* @return 取不到返回 new User()
*/
protected static User getUser() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes == null) {
return null;
}
HttpServletRequest request = servletRequestAttributes.getRequest();
return getUser(request);
}
/**
* 获取当前登录用户
*
* DEMON modify by 2019-11-19
*/
protected static User getUser(HttpServletRequest request){
// 获取accessToken
// String accessToken = ClientTokenUtil.cookieAccessToken();
// if(null == accessToken || StringUtils.isEmpty(accessToken)){
// accessToken = request.getHeader("access_token");
// }
//
// if(null == accessToken || StringUtils.isEmpty(accessToken)){
// return null;
// }
//
// // access token 换 userId
// ClientUserUtil clientUserUtil = (ClientUserUtil) ClientSpringContextUtil.getBean("clientUserUtil");
// Object userId = clientUserUtil.getUserId(accessToken);
// if(StringUtils.isEmpty((String)userId)){
// return null;
// }
String userId = request.getHeader(CommonConstant.AUTHORIZATION);
User user = new User();
user.setUserId(userId);
return user;
}
@JsonIgnore
public User getCreateBy() {
return createBy;
}
public void setCreateBy(User createBy) {
this.createBy = createBy;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@JsonIgnore
public User getUpdateBy() {
return updateBy;
}
public void setUpdateBy(User updateBy) {
this.updateBy = updateBy;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@JsonIgnore
@Length(min=1, max=1)
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
}
package com.loit.common.persistence;
import java.util.List;
/**
* DAO支持类实现
* @author loit
* @version 2014-05-16
* @param <T>
*/
public interface TreeDao<T extends TreeEntity<T>> extends CrudDao<T> {
/**
* 找到所有子节点
* @param entity
* @return
*/
public List<T> findByParentIdsLike(T entity);
/**
* 更新所有父节点字段
* @param entity
* @return
*/
public int updateParentIds(T entity);
}
\ No newline at end of file
package com.loit.common.persistence;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.loit.common.utils.Reflections;
import com.loit.common.utils.StringUtils;
/**
* 数据Entity类
* @author loit
* @version 2014-05-16
*/
public abstract class TreeEntity<T> extends DataEntity<T> {
private static final long serialVersionUID = 1L;
protected T parent; // 父级编号
protected String parentIds; // 所有父级编号
protected String name; // 机构名称
protected Integer sort; // 排序
public TreeEntity() {
super();
this.sort = 30;
}
/**
* 父对象,只能通过子类实现,父类实现mybatis无法读取
* @return
*/
@JsonBackReference
@NotNull
public abstract T getParent();
/**
* 父对象,只能通过子类实现,父类实现mybatis无法读取
* @return
*/
public abstract void setParent(T parent);
@Length(min=1, max=2000)
public String getParentIds() {
return parentIds;
}
public void setParentIds(String parentIds) {
this.parentIds = parentIds;
}
@Length(min=1, max=100)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
public String getParentId() {
String id = null;
if (parent != null){
id = (String)Reflections.getFieldValue(parent, "id");
}
return StringUtils.isNotBlank(id) ? id : "0";
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论