Commit 3d1fda99 authored by 姜耀祖's avatar 姜耀祖

项目初始化

parent 91c19341
package com.infoepoch.pms.dispatchassistant.common.component;
import org.apache.commons.lang3.StringUtils;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
public abstract class AbstractCriteria {
private Integer pageIndex;
private Integer pageSize;
public Integer getPageIndex() {
return pageIndex;
}
public void setPageIndex(Integer pageIndex) {
this.pageIndex = pageIndex;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public boolean byPage() {
if (pageIndex == null || pageSize == null)
return false;
if (pageIndex < 0 || pageSize < 1)
return false;
return true;
}
/*** andMap*/
protected Map<String, Object> andMap = new LinkedHashMap<>();
/*** 是否有查询条件*/
public boolean hasCriteria() {
return !andMap.isEmpty();
}
/**
* @Description: 移除andMap内value为null或空字符串
* @Param: []
* @Author: zhangyd
*/
public void removeMapNullOrEmpty() {
Iterator<Map.Entry<String, Object>> it = andMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Object> entry = it.next();
if (entry.getValue() == null) {
it.remove();
continue;
}
//如果是字符串,判断是否是空字符串
if ((entry.getValue() instanceof String) && StringUtils.isBlank(entry.getValue().toString())) {
it.remove();
}
}
}
/**
* @Description: 移除andMap内value为null或空字符串
* @Param: []
* @Author: zhangyd
*/
public void removeMapNull() {
Iterator<Map.Entry<String, Object>> it = andMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Object> entry = it.next();
if (entry.getValue() == null) {
it.remove();
}
}
}
}
\ No newline at end of file
package com.infoepoch.pms.dispatchassistant.common.component;
/**
* 分页查询参数
*/
public class PageCriteria {
public static Integer startIndex(Integer pageIndex,Integer pageSize) {
return new PageCriteria(pageIndex,pageSize).startIndex();
}
/**
* 页码自增
*/
public void pageIndexAdd() {
this.pageIndex += 1;
}
public Integer startIndex() {
if(this.getPageIndex() <= 0) {
return 1;
} else {
return (this.getPageIndex() - 1) * this.getPageSize() + 1;
}
}
public Integer endIndex() {
if(this.getPageIndex() <= 0) {
return this.getPageSize();
} else {
return this.getPageIndex() * this.getPageSize();
}
}
public PageCriteria() {
}
public PageCriteria(Integer pageIndex, Integer pageSize) {
this.pageIndex = pageIndex;
this.pageSize = pageSize;
}
private boolean paginationFlag;
private Integer pageIndex;
private Integer pageSize;
public boolean isPaginationFlag() {
return paginationFlag;
}
public void setPaginationFlag(boolean paginationFlag) {
this.paginationFlag = paginationFlag;
}
public Integer getPageIndex() {
return pageIndex == null ? 0 : pageIndex;
}
public void setPageIndex(Integer pageIndex) {
if(pageIndex < 0) {
this.pageIndex = 0;
} else {
this.pageIndex = pageIndex;
}
}
public Integer getPageSize() {
return pageSize == null ? 10 : pageSize;
}
public void setPageSize(Integer pageSize) {
if(pageSize <= 0) {
this.pageSize = 10;
} else {
this.pageSize = pageSize;
}
}
}
package com.infoepoch.pms.dispatchassistant.common.component;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
*
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisTemplate redisTemplate) {
//创建jackson的序列化方式
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
Object.class);
ObjectMapper objectMapper = new ObjectMapper();
//设置序列化时允许访问对象中的所有属性
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//json转化时保存类的信息
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//修改jackson序列化的方式
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
StringRedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
}
}
package com.infoepoch.pms.dispatchassistant.common.component;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Component
public class RedisTool {
@Autowired
private RedisTemplate redisTemplate;
/**
* 缓存基本对象:Integer、String、实体类等
*
* @param key 缓存KEY
* @param value 缓存内容
* @param <T>
*/
public <T> void put(String key, T value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 缓存基本对象:Integer、String、实体类等
*
* @param key 缓存KEY
* @param value 缓存内容
* @param timeout 失效时间
* @param timeUnit 失效时间单位
* @param <T>
*/
public <T> void put(String key, T value, long timeout, TimeUnit timeUnit) {
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 设置缓存有效时间
*
* @param key 缓存KEY
* @param timeout 失效时间(单位:秒)
* @return
*/
public boolean expire(String key, long timeout) {
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置缓存有效时间
*
* @param key 缓存KEY
* @param timeout 失效时间
* @param timeUnit 失效时间单位
* @return
*/
public boolean expire(String key, long timeout, TimeUnit timeUnit) {
return redisTemplate.expire(key, timeout, timeUnit);
}
/**
* 获取缓存
*
* @param key 缓存KEY
* @param <T>
* @return
*/
public <T> T get(String key) {
ValueOperations<String, T> operations = redisTemplate.opsForValue();
return operations.get(key);
}
/**
* 删除缓存
*
* @param key 缓存KEY
* @return
*/
public boolean remove(String key) {
return redisTemplate.delete(key);
}
/**
* 删除集合对象
*
* @param collection
* @return
*/
public long removeCollection(Collection collection) {
return redisTemplate.delete(collection);
}
/**
* 设置LIST类型缓存数据
*
* @param key 缓存KEY
* @param dataList LIST对象
* @param <T>
* @return
*/
public <T> long putList(String key, List<T> dataList) {
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 获取缓存的LIST对象
*
* @param key 缓存KEY
* @param <T>
* @return
*/
public <T> List<T> getList(String key) {
return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 缓存SET
*
* @param key 缓存KEY
* @param set SET对象
* @param <T>
* @return
*/
public <T> BoundSetOperations<String, T> putSet(String key, Set<T> set) {
BoundSetOperations<String, T> setOperations = redisTemplate.boundSetOps(key);
Iterator<T> it = set.iterator();
while (it.hasNext()) {
setOperations.add(it.next());
}
return setOperations;
}
/**
* 获取缓存SET
*
* @param key 缓存KEY
* @param <T>
* @return
*/
public <T> Set<T> getSet(String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* 缓存值到MAP中
*
* @param key
* @param mapKey
* @param value
* @param <T>
*/
public <T> void putMap(String key, String mapKey, T value) {
if (value != null)
redisTemplate.opsForHash().put(key, mapKey, value);
}
/**
* 缓存MAP
*
* @param key 缓存KEY
* @param map MAP对象
* @param <T>
*/
public <T> void putMap(String key, Map<String, T> map) {
if (map != null)
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 获取MAP中的值
*
* @param key 缓存KEY
* @param mapKey MAP的key
* @param <T>
* @return
*/
public <T> T getMapValue(String key, String mapKey) {
HashOperations<String, String, T> operations = redisTemplate.opsForHash();
return operations.get(key, mapKey);
}
/**
* 获取多个MAP中的值
*
* @param key 缓存KEY
* @param mapKeys MAP的key集合
* @param <T>
* @return
*/
public <T> List<T> getMultiMapValue(String key, Collection<Object> mapKeys) {
return redisTemplate.opsForHash().multiGet(key, mapKeys);
}
/**
*
* @param key
* @param mapKey
* @return
*/
public boolean removeMapValue(String key, String mapKey) {
return redisTemplate.opsForHash().delete(key, mapKey) > 0;
}
/**
* 获取缓存的KEY列表
*
* @param pattern 正则表达式
* @return
*/
public Collection<String> keys(String pattern) {
return redisTemplate.keys(pattern);
}
}
package com.infoepoch.pms.dispatchassistant.common.component;
import java.util.HashMap;
import java.util.Map;
/**
* Json返回值定义
*/
public class Result {
private int code; //返回码
private String message; //返回消息
private Object data; //数据
public Result()
{}
/**
* 构造函数
*/
private Result(int code, String message) {
this.code = code;
this.message = message;
}
/**
* 构造函数
*/
private Result(int code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public Object getData() {
return data;
}
/**
* 成功的返回码为0
*/
private static final int CODE_SUCCESS = 0;
/**
* 是否成功
*/
public boolean isSuccess() {
return code == CODE_SUCCESS;
}
/**
* 成功,成功时返回码为0
*/
public static Result success() {
return new Result(CODE_SUCCESS, "");
}
/**
* 成功,成功时返回码为0
*/
public static Result success(String message) {
return new Result(CODE_SUCCESS, message);
}
/**
* 成功,成功时返回码为0
*/
public static Result success(String message, Object data) {
return new Result(CODE_SUCCESS, message, data);
}
/**
* 成功,成功时返回码为0
*/
public static Result successData(Object data) {
return new Result(CODE_SUCCESS, "", data == null ? "" : data);
}
/**
* 失败
*
* @param code 返回码,由于默认0为成功时的返回码,如此参数传入0将自动替换为-1
* @return
*/
public static Result error(int code) {
if (code == CODE_SUCCESS) {
code = -1;
}
return new Result(code, "");
}
/**
* 失败
*
* @param code 返回码,由于默认0为成功时的返回码,如此参数传入0将自动替换为-1
* @param message
* @return
*/
public static Result error(int code, String message) {
if (code == CODE_SUCCESS) {
code = -1;
}
return new Result(code, message);
}
/**
* 失败
*
* @param code 返回码,由于默认0为成功时的返回码,如此参数传入0将自动替换为-1
* @param message
* @param data
* @return
*/
public static Result error(int code, String message, Object data) {
if (code == CODE_SUCCESS) {
code = -1;
}
return new Result(code, message, data);
}
/**
* 转换为map,便于动态添加属性
*/
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("code", code);
map.put("message", message);
map.put("data", data);
map.put("success", isSuccess());
return map;
}
}
package com.infoepoch.pms.dispatchassistant.common.component;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* 用于在应用启动加载时根据配置值实例化SnowFlake
*/
@Component
public class Runner implements ApplicationRunner {
@Value("${snowflake.datacenter-id:0}")
long datacenterId;
@Value("${snowflake.machine-id:0}")
long machineId;
@Override
public void run(ApplicationArguments arguments) {
//根据配置文件实例SnowFlake
SnowFlake.init(datacenterId, machineId);
}
}
\ No newline at end of file
package com.infoepoch.pms.dispatchassistant.common.component;
/**
* SnowFlake算法Id生成器
*/
public class SnowFlake {
/**
* 起始的时间戳
*/
private final static long START_STMP = 1480166465631L;
/**
* 每一部分占用的位数
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数,一个时间戳最多产生4096个序列号
private final static long MACHINE_BIT = 5; //机器标识占用的位数,最大支持32台机器
private final static long DATACENTER_BIT = 5;//数据中心占用的位数,最大支持32个数据中心
/**
* 每一部分的最大值
*/
private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
/**
* 每一部分向左的位移
*/
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
public long datacenterId; //数据中心
public long machineId; //机器标识
private long sequence = 0L; //序列号
private long lastStmp = -1L;//上一次时间戳
public long getDatacenterId() {
return datacenterId;
}
public long getMachineId() {
return machineId;
}
public SnowFlake(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
/**
* 产生下一个Id
*/
public synchronized Long nextId() {
long currStmp = getNewstmp();
if (currStmp < lastStmp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (currStmp == lastStmp) {
//相同毫秒内,序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大
if (sequence == 0L) {
currStmp = getNextMill();
}
} else {
//不同毫秒内,序列号置为0
sequence = 0L;
}
lastStmp = currStmp;
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT //数据中心部分
| machineId << MACHINE_LEFT //机器标识部分
| sequence; //序列号部分
}
private long getNextMill() {
long mill = getNewstmp();
while (mill <= lastStmp) {
mill = getNewstmp();
}
return mill;
}
private long getNewstmp() {
return System.currentTimeMillis();
}
//-------------------------------------------------------------------------
//静态实例
//private static SnowFlake snowFlake = new SnowFlake(0, 0);
private volatile static SnowFlake snowFlake;
/**
* 初始化
*/
public static void init(long datacenterId, long machineId) {
snowFlake = new SnowFlake(datacenterId, machineId);
}
public static SnowFlake instant() {
if (snowFlake == null)
synchronized (SnowFlake.class) {
if (snowFlake == null) {
snowFlake = new SnowFlake(0, 0);
}
}
return snowFlake;
}
}
package com.infoepoch.pms.dispatchassistant.common.configuration;
import com.infoepoch.pms.dispatchassistant.common.utils.ListTool;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @program: scm
* @description: CorsConfig(CORS)过滤
* @author: zhangyd
* @create: 2020-03-04 15:54
**/
@Configuration
public class CorsConfig {
/**
* 跨域拦截过滤器
*
* @return
*/
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// 不根据origin拦截
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
// 不根据method拦截
String allowedMethods = "*";
config.setAllowedMethods(ListTool.splitString(allowedMethods, ","));
// 不根据header拦截
String allowedHeaders = "*";
config.setAllowedHeaders(ListTool.splitString(allowedHeaders, ","));
// 设置过滤器匹配uri,/**表示匹配所有地址
configSource.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(configSource));
// 这个顺序很重要哦,为避免麻烦请设置在最前
bean.setOrder(0);
return bean;
}
}
package com.infoepoch.pms.dispatchassistant.common.configuration;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.infoepoch.pms.dispatchassistant.common.enums.EnumBase;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Optional;
/**
* Jackson全局配置
*/
@Configuration
public class JacksonConfiguration {
/**
* 配置Spring MVC的Json转换器
*/
@Bean
public HttpMessageConverters jacksonConverters() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.indentOutput(true) //输出时自动缩进
.dateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")) //日期时间格式化
.serializerByType(Long.TYPE, new ToStringSerializer()) //long转String
.serializerByType(Long.class, new ToStringSerializer()) //Long转String
.serializerByType(EnumBase.class, new EnumSerializer()) //转换枚举
;
ObjectMapper objectMapper = builder.build();
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
return new HttpMessageConverters(new MappingJackson2HttpMessageConverter(objectMapper));
}
/**
* 配置@Autowired的ObjectMapper对象
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
return builder -> {
builder.indentOutput(true);
builder.dateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
builder.serializerByType(Long.TYPE, new ToStringSerializer());
builder.serializerByType(Long.class, new ToStringSerializer());
builder.serializerByType(EnumBase.class, new EnumSerializer());
};
}
/**
* 枚举序列化类
*/
public class EnumSerializer extends JsonSerializer<EnumBase> {
@Override
public void serialize(EnumBase value, JsonGenerator jgen, SerializerProvider provider)
throws IOException {
if (value == null) {
jgen.writeString("");
return;
}
Optional<EnumBase> data = Optional.of(value);
jgen.writeObject(data.get().getValue());
}
}
/**
* null值序列化类
*/
public class NullDeserializer extends JsonDeserializer<Object> {
@Override
public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
return "";
}
}
}
package com.infoepoch.pms.dispatchassistant.common.configuration;
import com.infoepoch.pms.dispatchassistant.common.component.RedisTool;
import com.infoepoch.pms.dispatchassistant.common.constant.RedisKeys;
import com.infoepoch.pms.dispatchassistant.common.exception.NotLoginException;
import com.infoepoch.pms.dispatchassistant.common.utils.JsonUtils;
import com.infoepoch.pms.dispatchassistant.domain.basic.user.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* MVC拦截全局配置
*/
@Configuration
public class MvcInterceptConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// URL格式校验拦截器
InterceptorRegistration urlFormatInterceptor = registry.addInterceptor(getUrlFormatInterceptor());
// 拦截所有请求
urlFormatInterceptor.addPathPatterns("/**");
//拦截器
InterceptorRegistration adminInterceptor = registry.addInterceptor(getAdminInterceptor());
//拦截api开头地址
adminInterceptor.addPathPatterns("/**");
// 账号登录相关请求不拦截
adminInterceptor.excludePathPatterns("/auth/**");
}
@Bean
public UrlFormatInterceptor getUrlFormatInterceptor() {
return new UrlFormatInterceptor();
}
@Bean
public AdminInterceptor getAdminInterceptor() {
return new AdminInterceptor();
}
/**
* 访问地址格式校验拦截器
*/
private static class UrlFormatInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
// 不合法的访问地址,统一跳转到首页
if (uri.contains("..") || uri.contains(":") || uri.contains(";")) {
throw new NotLoginException("请求地址非法");
}
return true;
}
}
/**
* 拦截后台访问,判断是否登录,如未登录跳转到登录页面
*/
private static class AdminInterceptor extends HandlerInterceptorAdapter {
@Autowired
private RedisTool redisTool;
@Value("${spring.application.name}")
private String applicationName;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws IOException, NotLoginException {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String cookieName = cookie.getName();
if (cookieName.equals(RedisKeys.SIGN)) {
String userStr = redisTool.get(RedisKeys.AUTHED_USER + cookie.getValue());
if(userStr == null) {
throw new NotLoginException("登录已失效,请重新登录");
}
User user = JsonUtils.jsonToObject(userStr, User.class);
if (user != null) {
// 刷新redis缓存时间
redisTool.expire(RedisKeys.AUTHED_USER + cookie.getValue(), 2, TimeUnit.HOURS);
return true;
}
}
}
}
throw new NotLoginException("登录已失效,请重新登录");
}
}
}
package com.infoepoch.pms.dispatchassistant.common.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
/**
* RestTemplate配置
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory simpleClientHttpRequestFactory) {
ResponseErrorHandler responseErrorHandler = new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse clientHttpResponse) {
return false;
}
@Override
public void handleError(ClientHttpResponse clientHttpResponse) {
}
};
RestTemplate restTemplate = new RestTemplate(simpleClientHttpRequestFactory);
restTemplate.setErrorHandler(responseErrorHandler);
return restTemplate;
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(86400000); //单位为ms(一天)
factory.setConnectTimeout(86400000); //单位为ms(一天)
return factory;
}
}
package com.infoepoch.pms.dispatchassistant.common.constant;
public class Constants {
/**
* 省本部组织编码(OA中不存在)
*/
public final static String PROVINCE_ORGANIZATION_OA_CODE = "00230010000000000000";
}
package com.infoepoch.pms.dispatchassistant.common.constant;
/**
* 错误码定义
*/
public class ErrorCodes {
/**
* 默认错误
*/
public static int DEFAULT = -1;
/**
* 未登录
*/
public static int NOT_LOGIN = 1;
/**
* 访问拒绝
*/
public static int ACCESS_FORBIDDEN = 2;
/**
* 验证错误
*/
public static int VALIDATION = 3;
/**
* 服务异常
*/
public static int SERVICE = 4;
/**
* 供应商未登录
*/
public static int SUPPLIER_NOT_LOGIN = 5;
}
package com.infoepoch.pms.dispatchassistant.common.constant;
public class RedisKeys {
public final static String SIGN = "sign";
/**
* 验证码
*/
public final static String CAPTCHA_LOGIN = "DISPATCHASSISTANT:CAPTCHA:LOGIN:";
/**
* 已登录用户
*/
public final static String AUTHED_USER = "DISPATCHASSISTANT:AUTHED:USER:";
/**
* 组织机构缓存KEY
*/
public final static String ROOT_ORGANIZATION_LIST = "DISPATCHASSISTANT-ORGANIZATION-ROOT-LIST";
/**
* 组织机构缓存KEY
*/
public final static String ORGANIZATION_LIST = "DISPATCHASSISTANT-ORGANIZATION-LIST";
/**
* 组织MAP缓存key
*/
public final static String ROOT_ORGANIZATION_MAP = "DISPATCHASSISTANT-ORGANIZATION-MAP";
/**
* 组织缓存KEY
*/
public final static String ORGANIZATION_KEY = "DISPATCHASSISTANT:ORGANIZATION:";
}
package com.infoepoch.pms.dispatchassistant.common.constant;
public class RoleNameConstants {
/**
* 管理员
*/
public final static String ADMIN_NAME = "管理员";
/**
* 培训系统管理员
*/
public final static String TRAIN_SYSTEM_ADMIN_NAME = "培训系统管理员";
/**
* 培训管理员
*/
public final static String TRAIN_ADMIN_NAME = "培训管理员";
/**
* 部门培训管理员
*/
public final static String DEPARTMENT_TRAIN_ADMIN_NAME = "部门培训管理员";
/**
* 培训项目负责人
*/
public final static String TRAIN_PROJECT_MANAGER_NAME = "项目负责人";
/**
* 室经理
*/
public final static String ROOM_MANAGER_NAME = "室经理";
/**
* 部门领导
*/
public final static String DEPARTMENT_LEADER_NAME = "部门领导";
}
package com.infoepoch.pms.dispatchassistant.common.constant;
/**
* Session键定义
*/
public class SessionKeys {
/**
* 验证码
*/
public final static String LOGIN_CAPTCHA = "LOGIN_CAPTCHA";
/**
* 已登录用户
*/
public final static String AUTHED_USER = "AUTHED_USER";
}
package com.infoepoch.pms.dispatchassistant.common.constant;
/**
* KeyValueStore键定义,统一管理防止重复
*/
public class StoreKeys {
/**
* 平台名称
*/
public final static String PLATFORM_NAME = "PLATFORM_NAME";
/**
* 定时任务回调地址
*/
public final static String SCHEDULING_CALL_BACK_URL = "SCHEDULING_CALL_BACK_URL";
/**
* 登录成功后跳转首页地址
*/
public final static String MAIN_PAGE_URI = "MAIN_PAGE_URI";
public final static String GXAPP_MAIN_PAGE_URI = "GXAPP_MAIN_PAGE_URI";
public final static String GXAPP_ASSISTANT_PAGE_URI = "GXAPP_ASSISTANT_PAGE_URI";
/**
* 课程封面
*/
public final static String FILE_TEMPLATE_COURSE_COVER = "FILE_TEMPLATE_COURSE_COVER";
/**
* 培训项目导入模板
*/
public final static String FILE_TEMPLATE_TRAIN_PROJECT = "FILE_TEMPLATE_TRAIN_PROJECT";
/**
* 结算对账明细导入模板
*/
public final static String FILE_TEMPLATE_SETTLEMENT_RECONCILIATION_LINE = "FILE_TEMPLATE_SETTLEMENT_RECONCILIATION_LINE";
/**
* 培训班-除外派培训导入模板
*/
public final static String FILE_TEMPLATE_TRAIN_ROOM_A = "FILE_TEMPLATE_TRAIN_ROOM_A";
/**
* 培训班-外派培训导入模板
*/
public final static String FILE_TEMPLATE_TRAIN_ROOM_B = "FILE_TEMPLATE_TRAIN_ROOM_B";
/**
* OA员工同步地址
*/
public final static String OA_EMPLOYEE_SYNC_URL = "OA_EMPLOYEE_SYNC_URL";
/**
* OA组织同步地址
*/
public final static String OA_ORGANIZATION_SYNC_URL = "OA_ORGANIZATION_SYNC_URL";
/**
* 登录页面地址
*/
public final static String LOGIN_HTML_URL = "LOGIN_HTML_URL_SA";
// region OA
/**
* appId
*/
public final static String APP_ID = "APP_ID";
/**
* appPwd
*/
public final static String APP_PASSWORD = "APP_PASSWORD";
/**
* 待办新增地址
*/
public final static String TODO_SYNC_ADD_TASK = "TODO_SYNC_ADD_TASK";
/**
* 待办更新地址
*/
public final static String TODO_SYNC_UPDATE_TASK = "TODO_SYNC_UPDATE_TASK";
/**
* 待办重定向基础地址
*/
public final static String TODO_REDIRECT_BASE_URL = "TODO_REDIRECT_BASE_URL";
/**
* 项目基础跳转地址
*/
public final static String BASE_URL = "BASE_URL_SA";
/**
* 500报错跳转页面地址
*/
public final static String ERROR_REDIRECT_URI = "ERROR_REDIRECT_URI";
/**
* OA首页
*/
public final static String OA_MAIN_PAGE_URL = "OA_MAIN_PAGE_URL";
/**
* OA登录页面地址
*/
public final static String OA_LOGIN_PAGE_URL = "OA_LOGIN_PAGE_URL";
/**
* OA员工同步入参
*/
public final static String OA_EMPLOYEE_SYNC_CRITERIA = "OA_EMPLOYEE_SYNC_CRITERIA";
/**
* OA组织同步入参
*/
public final static String OA_ORGANIZATION_SYNC_CRITERIA = "OA_ORGANIZATION_SYNC_CRITERIA";
// endregion OA
// region MOA
/**
* MOA待办跳转基础地址
*/
public final static String MOA_TODO_REDIRECT_BASE_URL = "MOA_TODO_REDIRECT_BASE_URL";
// endregion MOA
/**
* PMS_API_URL
*/
public final static String PMS_API_URL = "PMS_API_URL";
/**
* NAS_DATE nas磁盘扩容日期
*/
public final static String NAS_DATE = "NAS_DATE";
/**
* MOA bridge.js加载路径
*/
public final static String MOA_BRIDGE_JS_URL = "MOA_BRIDGE_JS_URL";
// region 短信
/**
* 短信IP
*/
public final static String MOBILE_MESSAGE_IP = "MOBILE_MESSAGE_IP";
/**
* 短端口
*/
public final static String MOBILE_MESSAGE_PORT = "MOBILE_MESSAGE_PORT";
/**
* 短信密码
*/
public final static String MOBILE_MESSAGE_PASSWORD = "MOBILE_MESSAGE_PASSWORD";
/**
* 短信发送人
*/
public final static String MOBILE_MESSAGE_SENDER = "MOBILE_MESSAGE_SENDER";
// endregion 短信
// region
/**
* 人力资源部名称
*/
public final static String HUMAN_RESOURCE_DEPARTMENT_NAME = "HUMAN_RESOURCE_DEPARTMENT_NAME";
/**
* 培训中心室名称
*/
public final static String TRAINING_CENTER_ORGANIZATION_NAME = "TRAINING_CENTER_ORGANIZATION_NAME";
//定时待办发送人ID
public final static String SEND_USER_ID_TIMER="SEND_USER_ID_TIMER";
//定时待办发送人名称
public final static String SEND_USER_TIMER="SEND_USER_TIMER";
// endregion
}
package com.infoepoch.pms.dispatchassistant.common.easyExcel;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CustomHeadWriteHandler extends AbstractColumnWidthStyleStrategy {
private Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
public CustomHeadWriteHandler() {
}
public CustomHeadWriteHandler(Map<Integer, Map<Integer, Integer>> CACHE) {
this.CACHE = CACHE;
}
@Override
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (CACHE.size() > 0) {
Map<Integer, Integer> columnWidthMap = CACHE.get(writeSheetHolder.getSheetNo());
if (columnWidthMap == null) {
columnWidthMap = new HashMap<>();
CACHE.put(writeSheetHolder.getSheetNo(), columnWidthMap);
}
Integer columnWidth = columnWidthMap.get(cell.getColumnIndex());
if(columnWidth == null || columnWidth == 0) {
columnWidth = this.dataLength(cellDataList, cell, isHead);
}
if (columnWidth >= 0) {
if (columnWidth > 255) {
columnWidth = 255;
}
Integer maxColumnWidth = columnWidthMap.get(cell.getColumnIndex());
if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
columnWidthMap.put(cell.getColumnIndex(), columnWidth);
}
writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
}
}
}
private Integer dataLength(List<CellData> cellDataList, Cell cell, Boolean isHead) {
if (isHead) {
return cell.getStringCellValue().getBytes().length;
} else {
CellData cellData = cellDataList.get(0);
CellDataTypeEnum type = cellData.getType();
if (type == null) {
return -1;
} else {
switch (type) {
case STRING:
return cellData.getStringValue().getBytes().length;
case BOOLEAN:
return cellData.getBooleanValue().toString().getBytes().length;
case NUMBER:
return cellData.getNumberValue().toString().getBytes().length;
default:
return -1;
}
}
}
}
}
package com.infoepoch.pms.dispatchassistant.common.easyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.infoepoch.pms.dispatchassistant.common.utils.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class NoModalDataListener extends AnalysisEventListener<Map<Integer, String>> {
private final static Logger logger = LoggerFactory.getLogger(NoModalDataListener.class);
private List<Map<Integer, String>> headList;
private List<Map<Integer, String>> dataList;
public NoModalDataListener() {
this.headList = new ArrayList<>();
this.dataList = new ArrayList<>();
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
logger.info("解析到一条数据:{}", JsonUtils.objectToJson(headMap));
headList.add(headMap);
}
@Override
public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
logger.info("解析到一条数据:{}", JsonUtils.objectToJson(integerStringMap));
dataList.add(integerStringMap);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
logger.info("所有数据解析完成");
}
public List<Map<Integer, String>> getHeadList() {
return headList;
}
public List<Map<Integer, String>> getDataList() {
return dataList;
}
}
package com.infoepoch.pms.dispatchassistant.common.encryption;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;
/**
* AES加密
*/
public class AESTool {
private static Key key;
private static String KEY_STR = "supermarket-xjy-2022-09-23";
private static String KEY_ALGORITHM = "AES";
private static String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
static {
try {
KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(KEY_STR.getBytes(StandardCharsets.UTF_8));
kgen.init(128, random);
key = kgen.generateKey();
kgen = null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取加密后的字符串
*
* @param str
* @return
*/
public static String getEncryptString(String str) {
try {
if (judgeEncryptFlag(str))
return str; // 如果字符串已经加密,不会进行二次加密
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(bytes);
return Base64.getEncoder().encodeToString(doFinal);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取解密后的字符串
*
* @param str
* @return
*/
public static String getDecryptString(String str) {
try {
if (judgeEncryptFlagReverse(str))
return str;// 如果字符串未加密,返回原字符串
byte[] bytes = Base64.getDecoder().decode(str);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(bytes);
return new String(doFinal, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 判断是否已加密
* 原理:加密后的字符串使用Base64编码了,如果进行了编码则是加密后的字符串,否则就是未加密的
*
* @param str
* @return true-已加密 false-未加密
*/
public static boolean judgeEncryptFlag(String str) {
if (StringUtils.isBlank(str))
return true;
try {
byte[] bytes = Base64.getDecoder().decode(str);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(bytes);
return doFinal != null;
} catch (Exception e) {
return false;
}
}
/**
* 判断字符串是否加密(反向标识)
*
* @param str
* @return true-未加密 false-已加密
*/
public static boolean judgeEncryptFlagReverse(String str) {
return !judgeEncryptFlag(str);
}
public static String encryptWithKey(String keyStr, String str) {
try {
if (judgeEncryptWithKey(keyStr, str))
return str; // 如果字符串已经加密,不会进行二次加密
Key key = getKey(keyStr);
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(bytes);
return Base64.getEncoder().encodeToString(doFinal);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String decryptWithKey(String keyStr, String str) {
try {
// if (judgeEncryptWithKeyReverse(keyStr, str))
// return str;// 如果字符串未加密,返回原字符串
Key key = getKey(keyStr);
// byte[] bytes = Base64.getDecoder().decode(str);
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(bytes);
return new String(doFinal, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static boolean judgeEncryptWithKey(String keyStr, String str) {
if (StringUtils.isBlank(str))
return true;
try {
Key key = getKey(keyStr);
byte[] bytes = Base64.getDecoder().decode(str);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(bytes);
return doFinal != null;
} catch (Exception e) {
return false;
}
}
private static boolean judgeEncryptWithKeyReverse(String keyStr, String str) {
return !judgeEncryptWithKey(keyStr, str);
}
private static Key getKey(String keyStr) {
Key key;
try {
KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(keyStr.getBytes(StandardCharsets.UTF_8));
kgen.init(128, random);
key = kgen.generateKey();
kgen = null;
return key;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package com.infoepoch.pms.dispatchassistant.common.enums;
/**
* 枚举接口
*/
public interface EnumBase {
/**
* 枚举值
*/
int getValue();
/**
* 枚举文本
*/
String getText();
}
package com.infoepoch.pms.dispatchassistant.common.enums;
public interface EnumStringBase {
/**
* 枚举值
*/
String getValue();
/**
* 枚举文本
*/
String getText();
}
package com.infoepoch.pms.dispatchassistant.common.enums;
import java.util.Collections;
import java.util.List;
/**
* 枚举树结构
*
* @author liudx
*/
public class EnumTree {
private Integer value;
private String text;
private List<EnumTree> children;
public EnumTree() {
// 无参构造
}
public EnumTree(Integer value, String text) {
this.value = value;
this.text = text;
}
public EnumTree addChildren(List<EnumTree> children){
this.children = children;
return this;
}
public Integer getValue() {
return value;
}
public String getText() {
return text;
}
public List<EnumTree> getChildren() {
return null == children ? Collections.emptyList() : children;
}
}
package com.infoepoch.pms.dispatchassistant.common.enums;
import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import java.util.*;
/**
* 枚举工具类
*/
public class EnumUtils {
/**
* 取枚举的值/文本对
* 示例:
* {
* "0" : "text0",
* "1" : "text1",
* "2" : "text2"
* }
* 前端vue绑定方式:
* <div v-for="(item, index) in Object.keys(enumData)">{{item}} : {{enumData[item]}}</div>
*/
public static <T extends EnumBase> Map<Integer, String> getMap(Class<T> enumType) {
Map<Integer, String> map = new HashMap<>();
for (T t : enumType.getEnumConstants()) {
map.put(t.getValue(), t.getText());
}
return map;
}
public static <T extends EnumBase> List<Map<String, Object>> getList(Class<T> enumType) {
List<Map<String, Object>> mapList = new ArrayList<>();
for (T t : enumType.getEnumConstants()) {
HashMap<String, Object> map = new HashMap<>(4);
map.put("value", t.getValue());
map.put("text", t.getText());
mapList.add(map);
}
return mapList;
}
public static <T extends EnumBase> List<Integer> getValueList(Class<T> enumType) {
List<Integer> values = new ArrayList<>();
for (T t : enumType.getEnumConstants()) {
values.add(t.getValue());
}
return values;
}
public static <T extends EnumBase> String getTextByValues(Class<T> enumType, List<String> values) {
StringBuilder sb = new StringBuilder();
for (T t : enumType.getEnumConstants()) {
if (values.stream().anyMatch(s -> s.equals(String.valueOf(t.getValue())))) {
sb.append(t.getText());
sb.append(",");
}
}
return sb.toString();
}
public static <T extends EnumBase> List<EnumTree> getEnumTreeList(Class<T> enumType) {
List<EnumTree> map = new ArrayList<EnumTree>();
for (T t : enumType.getEnumConstants()) {
map.add(new EnumTree(t.getValue(), t.getText()));
}
return map;
}
/**
* 取枚举项值/文本集合
* 示例:
* [
* { "value" : "0", "text" : "text0" },
* { "value" : "1", "text" : "text1" },
* { "value" : "2", "text" : "text2" }
* ]
* 前端vue绑定方式:
* <div v-for="(item, index) in Object.keys(enumData)">{{item.value}} : {{item.text}}</div>
*/
public static <T extends EnumBase> List<Map<String, Object>> getItems(Class<T> enumType) {
List<Map<String, Object>> list = new ArrayList();
for (T t : enumType.getEnumConstants()) {
Map<String, Object> map = new HashMap<>();
map.put("value", t.getValue());
map.put("text", t.getText());
list.add(map);
}
return list;
}
public static <T extends EnumStringBase> Map<String, String> getEnumMap(Class<T> enumType) {
Map<String, String> resultMap = new HashMap<>();
for (T t : enumType.getEnumConstants()) {
resultMap.put(t.getValue(), t.getText());
}
return resultMap;
}
/**
* 解析枚举值,值非法时返回null
*/
public static <T extends EnumBase> T getByValue(Class<T> enumType, int value) {
for (T t : enumType.getEnumConstants()) {
if (t.getValue() == value)
return t;
}
return null;
}
/**
* 解析枚举值,值非法时抛出异常
*/
public static <T extends EnumBase> T getByValueReq(Class<T> enumType, int value)
throws ValidationException {
for (T t : enumType.getEnumConstants()) {
if (t.getValue() == value)
return t;
}
throw new ValidationException("枚举“" + enumType + "”中没有找到值为“" + value + "”的项。");
}
/**
* 解析枚举值,值非法时返回默认值
*/
public static <T extends EnumBase> T getByValue(Class<T> enumType, int value, T defaultValue) {
for (T t : enumType.getEnumConstants()) {
if (t.getValue() == value)
return t;
}
return defaultValue;
}
/**
* 解析枚举值,值非法时返回null
*/
public static <T extends EnumBase> T getByValue(Class<T> enumType, String value) {
for (T t : enumType.getEnumConstants()) {
if (String.valueOf(t.getValue()).equals(value))
return t;
}
return null;
}
/**
* 解析枚举值,值非法时返回null
*/
public static <T extends EnumStringBase> T getByKey(Class<T> enumType, String key) {
for (T t : enumType.getEnumConstants()) {
if (String.valueOf(t.getValue()).equals(key))
return t;
}
return null;
}
/**
* 解析枚举值,值非法时抛出异常
*/
public static <T extends EnumBase> T getByValueReq(Class<T> enumType, String value)
throws ValidationException {
for (T t : enumType.getEnumConstants()) {
if (String.valueOf(t.getValue()).equals(value))
return t;
}
throw new ValidationException("枚举“" + enumType + "”中没有找到值为“" + value + "”的项。");
}
/**
* 解析枚举值,值非法时返回默认值
*/
public static <T extends EnumBase> T getByValue(Class<T> enumType, String value, T defaultValue) {
for (T t : enumType.getEnumConstants()) {
if (String.valueOf(t.getValue()).equals(value))
return t;
}
return defaultValue;
}
/**
* 解析枚举值,值非法时返回null
*/
public static <T extends EnumStringBase> T getByStringValue(Class<T> enumType, String value) {
for (T t : enumType.getEnumConstants()) {
if (String.valueOf(t.getValue()).equals(value))
return t;
}
return null;
}
/**
* 解析枚举值,值非法时抛出异常
*/
public static <T extends EnumStringBase> T getByStringValueReq(Class<T> enumType, String value)
throws ValidationException {
for (T t : enumType.getEnumConstants()) {
if (String.valueOf(t.getValue()).equals(value))
return t;
}
throw new ValidationException("枚举“" + enumType + "”中没有找到值为“" + value + "”的项。");
}
/**
* 解析枚举值,值非法时返回默认值
*/
public static <T extends EnumStringBase> T getByStringValue(Class<T> enumType, String value, T defaultValue) {
for (T t : enumType.getEnumConstants()) {
if (String.valueOf(t.getValue()).equals(value))
return t;
}
return defaultValue;
}
/**
* 根据文本解析枚举值,值非法时返回null
*/
public static <T extends EnumBase> T getByText(Class<T> enumType, String text) {
for (T t : enumType.getEnumConstants()) {
if (t.getText().equals(text))
return t;
}
return null;
}
public static <T extends EnumBase> List<Integer> getByTexts(Class<T> enumType, List<String> texts) {
List<Integer> values = new ArrayList<>();
for (T t : enumType.getEnumConstants()) {
texts.forEach(s -> {
if (t.getText().equals(s)) {
values.add(t.getValue());
}
});
}
return values;
}
public static <T extends EnumBase> List<String> getTextList(Class<T> enumType) {
List<String> texts = new ArrayList<>();
for (T t : enumType.getEnumConstants()) {
texts.add(t.getText());
}
return texts;
}
/**
* 根据value返回 text值,如不存在返回默认值
*
* @param value value值
* @param defaultText 默认text
*/
public static <T extends EnumBase> String getTextByValue(Class<T> enumType, Integer value, String defaultText) {
if (Objects.isNull(value)) {
return defaultText;
}
for (T t : enumType.getEnumConstants()) {
if (t.getValue() == value) {
return t.getText();
}
}
return defaultText;
}
}
package com.infoepoch.pms.dispatchassistant.common.exception;
import com.infoepoch.pms.dispatchassistant.common.component.Result;
import com.infoepoch.pms.dispatchassistant.common.constant.ErrorCodes;
import com.infoepoch.pms.dispatchassistant.common.constant.StoreKeys;
import com.infoepoch.pms.dispatchassistant.common.utils.StringUtils;
import com.infoepoch.pms.dispatchassistant.common.utils.UrlTool;
import com.infoepoch.pms.dispatchassistant.domain.basic.store.KeyValueStoreService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 全局异常处理器
*/
@ControllerAdvice
public class GlobalExceptionHandler {
protected static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@Autowired
private KeyValueStoreService keyValueStoreService;
@Value("${spring.application.name}")
private String applicationName;
/**
* 上传文件大小超过限制异常处理器,此异常在上传方法中无法捕捉,只能在此捕捉
*/
@ExceptionHandler(value = MaxUploadSizeExceededException.class)
@ResponseBody
public Result maxUploadSizeExceededExceptionHandler(HttpServletResponse response, MaxUploadSizeExceededException e) {
return Result.error(ErrorCodes.DEFAULT, "上传文件大小超过限制。");
}
/**
* 未登录异常处理器
*/
@ExceptionHandler(value = NotLoginException.class)
@ResponseBody
public Result notLoginExceptionHandler(HttpServletResponse response, NotLoginException e) {
if (e.getCode() == ErrorCodes.SUPPLIER_NOT_LOGIN)
return Result.error(e.getCode(), "请重新登录。");
return Result.error(ErrorCodes.NOT_LOGIN, "请重新登录。");
}
/**
* 验证异常处理器
*/
@ExceptionHandler(value = ValidationException.class)
@ResponseBody
public Result validationExceptionHandler(HttpServletResponse response, Exception e) {
// logger.info("捕获到验证异常。", e);
return Result.error(ErrorCodes.VALIDATION, e.getMessage());
}
/**
* 默认异常处理器,返回JSON
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result defaultExceptionHandler(HttpServletResponse response, Exception e) {
logger.info("捕捉到未处理的异常。", e);
return Result.error(ErrorCodes.DEFAULT, "服务器异常,请联系管理员。");
}
}
package com.infoepoch.pms.dispatchassistant.common.exception;
import com.infoepoch.pms.dispatchassistant.common.constant.ErrorCodes;
/**
* 未登录异常
*/
public class NotLoginException extends Exception {
private int code = ErrorCodes.NOT_LOGIN;
/**
* 构造函数
*/
public NotLoginException() {
super();
}
/**
* 构造函数
*/
public NotLoginException(int code) {
super();
this.code = code;
}
/**
* 构造函数
*/
public NotLoginException(String message) {
super(message);
}
/**
* 构造函数
*/
public NotLoginException(int code, String message) {
super(message);
this.code = code;
}
/**
* 构造函数
*/
public NotLoginException(String message, Throwable cause) {
super(message, cause);
}
/**
* 构造函数
*/
public NotLoginException(Throwable cause) {
super(cause);
}
public int getCode() {
return code;
}
}
package com.infoepoch.pms.dispatchassistant.common.exception;
/**
* 验证异常
*/
public class ValidationException extends RuntimeException {
/**
* 构造函数
*/
public ValidationException() {
super();
}
/**
* 构造函数
*/
public ValidationException(String message) {
super(message);
}
/**
* 构造函数
*/
public ValidationException(String message, Throwable cause) {
super(message, cause);
}
/**
* 构造函数
*/
public ValidationException(Throwable cause) {
super(cause);
}
}
package com.infoepoch.pms.dispatchassistant.common.tuple;
/**
* 元组,包含2个元素
*
* @param <A>
* @param <B>
*/
public class TupleTwo<A, B> {
private final A first; //元组中第1个元素
private final B second; //元组中第2个元素
public TupleTwo() {
this.first = null;
this.second = null;
}
/**
* 构造函数
*/
public TupleTwo(A a, B b) {
this.first = a;
this.second = b;
}
/**
* 取元组中第1个元素
*/
public A getFirst() {
return this.first;
}
/**
* 取元组中第2个元素
*/
public B getSecond() {
return this.second;
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextTool implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextTool.applicationContext = applicationContext;
}
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import com.infoepoch.pms.dispatchassistant.common.encryption.AESTool;
import java.util.Base64;
public class Base64Utils {
/**
* 加密
*
* @param str
* @return
*/
public static String encode(String str) {
return AESTool.getEncryptString(str);
}
/**
* 解密
*
* @param str
* @return
*/
public static String decode(String str) {
return new String(Base64.getDecoder().decode(str));
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
if (BeanUtil.applicationContext == null) {
BeanUtil.applicationContext = applicationContext;
}
}
/**
* 获取applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import java.math.BigDecimal;
import java.util.Optional;
public class BigDecimalUtils {
// 百
public final static BigDecimal HUNDRED = new BigDecimal("100");
// 千
public final static BigDecimal THOUSAND = new BigDecimal("1000");
// 万
public final static BigDecimal WAN = new BigDecimal("10000");
// 亿
public final static BigDecimal YI = new BigDecimal("100000000");
// 默认统一精度——4
public final static int SCALE = 4;
// 默认精度取舍类型——四舍五入
public final static int ROUND_TYPE = BigDecimal.ROUND_HALF_UP;
public final static BigDecimal five = new BigDecimal("0.5");
/**
* String字符串转换成BigDecimal
*
* @param str
* @return
*/
public static BigDecimal transferString(String str) {
try {
return new BigDecimal(str);
} catch (Exception e) {
return BigDecimal.ZERO;
}
}
/**
* 乘以一百
* 入参为null时返回0
*
* @param decimal
* @return
*/
public static BigDecimal multiplyHundred(BigDecimal decimal) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.multiply(HUNDRED).setScale(SCALE, ROUND_TYPE);
return BigDecimal.ZERO;
}
/**
* 乘以一千
* 入参为null时返回0
*
* @param decimal
* @return
*/
public static BigDecimal multiplyThousand(BigDecimal decimal) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.multiply(THOUSAND).setScale(SCALE, ROUND_TYPE);
return BigDecimal.ZERO;
}
/**
* 乘以一万
* 入参为null时返回0
*
* @param decimal
* @return
*/
public static BigDecimal multiplyWan(BigDecimal decimal) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.multiply(WAN).setScale(SCALE, ROUND_TYPE);
return BigDecimal.ZERO;
}
/**
* 乘以一亿
*
* @param decimal
* @return
*/
public static BigDecimal multiplyYi(BigDecimal decimal) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.multiply(YI).setScale(SCALE, ROUND_TYPE);
return BigDecimal.ZERO;
}
/**
* 除以一百
* 入参为null时返回0
*
* @param decimal
* @return
*/
public static BigDecimal divideHundred(BigDecimal decimal, int roundType) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.divide(HUNDRED, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
return BigDecimal.ZERO;
}
/**
* 除以一千
* 入参为null时返回0
*
* @param decimal
* @return
*/
public static BigDecimal divideThousand(BigDecimal decimal, int roundType) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.divide(THOUSAND, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
return BigDecimal.ZERO;
}
/**
* 除以一万
* 入参为null时返回0
*
* @param decimal
* @return
*/
public static BigDecimal divideWan(BigDecimal decimal, int roundType) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.divide(WAN, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
return BigDecimal.ZERO;
}
/**
* 除以一亿
*
* @param decimal
* @param roundType
* @return
*/
public static BigDecimal divideYi(BigDecimal decimal, int roundType) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.divide(YI, SCALE, roundType < 0 ? ROUND_TYPE : roundType);
return BigDecimal.ZERO;
}
/**
* bigdecimal转换成String
*
* @param decimal
* @return
*/
public static String decimalToString(BigDecimal decimal) {
if (Optional.ofNullable(decimal).isPresent())
return decimal.toString();
return "";
}
public static BigDecimal getDecimal(Object object) {
if(object == null)
return BigDecimal.ZERO;
BigDecimal decimal;
try {
decimal = (BigDecimal) object;
} catch (Exception e) {
decimal = new BigDecimal(String.valueOf(object));
}
return decimal;
}
/**
* 获取BigDecimal类型对象,为null时返回BigDecimal.ZERO
*
* @param integer
* @return
*/
public static BigDecimal getDecimal(Integer integer) {
return integer == null ? BigDecimal.ZERO : new BigDecimal(String.valueOf(integer));
}
/**
* 获取BigDecimal类型对象,为null时返回BigDecimal.ZERO
*
* @param decimal
* @return
*/
public static BigDecimal getDecimal(BigDecimal decimal) {
return decimal == null ? BigDecimal.ZERO : decimal;
}
/**
* 获取BigDecimal对象
*
* @param object
* @return
*/
public static BigDecimal getDecimalByObject(Object object) {
return getDecimalByObject(object, BigDecimal.ZERO);
}
/**
* 获取BigDecimal对象
*
* @param object
* @param defaultDecimal 默认值
* @return
*/
public static BigDecimal getDecimalByObject(Object object, BigDecimal defaultDecimal) {
try {
return object == null ? BigDecimal.ZERO : new BigDecimal(String.valueOf(object));
} catch (Exception e) {
return defaultDecimal;
}
}
/**
* 获取bigDecimal的绝对值
*
* @param decimal
* @return
*/
public static BigDecimal getAbsoluteDecimal(BigDecimal decimal) {
return decimal == null ? BigDecimal.ZERO : decimal.abs();
}
/**
* 获取BigDecimal类型对象,异常时返回BigDecimal.ZERO
*
* @param decimalStr
* @return
*/
public static BigDecimal getDecimal(String decimalStr) {
BigDecimal decimal;
try {
decimal = new BigDecimal(decimalStr);
} catch (Exception e) {
decimal = BigDecimal.ZERO;
}
return decimal;
}
public static BigDecimal getDecimal(String decimalStr, BigDecimal defaultDecimal) {
BigDecimal decimal;
try {
decimal = new BigDecimal(decimalStr);
} catch (Exception e) {
decimal = defaultDecimal;
}
return decimal;
}
public static BigDecimal addTwoBigDecimal(BigDecimal thisDecimal, BigDecimal thatDecimal) {
return Optional.ofNullable(thisDecimal).orElse(BigDecimal.ZERO).add(Optional.ofNullable(thatDecimal).orElse(BigDecimal.ZERO));
}
public static String addTwoBigDecimalTwo(String thisDecimalStr, String thatDecimalStr) {
BigDecimal thisDecimal = new BigDecimal(thisDecimalStr);
BigDecimal thatDecimal = new BigDecimal(thatDecimalStr);
return addTwoBigDecimal(thisDecimal, thatDecimal).toString();
}
public static BigDecimal subtractTwoBigDecimal(BigDecimal total, BigDecimal subtract) {
return getDecimal(total).subtract(getDecimal(subtract));
}
/**
* 处理两个BigDecimal对象的除法
*
* @param molecule
* @param denominator
* @param scale
* @param roundType
* @return
*/
public static BigDecimal divideTwoDecimal(BigDecimal molecule, BigDecimal denominator, int scale, int roundType) {
if (molecule == null || denominator == null)
return BigDecimal.ZERO;
if (denominator.compareTo(BigDecimal.ZERO) == 0)
return BigDecimal.ZERO;
return molecule.divide(denominator, scale, roundType);
}
/**
* 获取BigDecimal列表中的最大值
*
* @param decimals
* @return
*/
public static BigDecimal getMaxBigDecimal(BigDecimal... decimals) {
BigDecimal max = BigDecimal.ZERO;
for (BigDecimal decimal : decimals) {
if (max.compareTo(decimal) < 0) {
max = decimal;
}
}
return max;
}
/**
* 校验value是否是0.5的倍数
* @param value
* @return
*/
public static boolean checkFiveMultiple(BigDecimal value){
// 计算value除以0.5后的余数
BigDecimal remainder = value.remainder(five);
// 如果余数为0,则value是0.5的倍数
return remainder.compareTo(BigDecimal.ZERO) == 0;
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
public class BooleanTool {
public static String getText(Boolean b) {
return getText(b, "是", "否");
}
public static String getText(Boolean b, String t1, String t2) {
if (b == null)
return t2;
else
return b ? t1 : t2;
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class CaptcaUtils {
/**
* 算术表达式验证码
*
* 1:干扰线的产生
* 2: 范围随机颜色,随机数
*
* @param response
* @return
*/
public static Map<String,Object> drawImageVerificate(HttpServletResponse response){
Random random = new Random();
//开始进行对算术验证码表达式的拼接
int num1 = (int)(Math.random()*10 + 1);
int num2 = (int)(Math.random()*10 + 1);
int fuhao = random.nextInt(3);//产生一个[0,2]之间的随机整数
//记录符号
String fuhaostr = null;
int result = 0;
switch (fuhao){
case 0 : fuhaostr = "+";result = num1 + num2;break;
case 1: fuhaostr = "-";result = num1 - num2;break;
case 2 : fuhaostr = "x";result = num1 * num2;break;
//case 3 : fuhaostr = "/";result = num1 / num2;break;
}
//拼接算术表达式,用户图片显示。
String calc = num1 + " " + fuhaostr +" "+ num2 +" = ?";
try {
//输出图片到页面
// ImageIO.write(image,"JPEG",response.getOutputStream());
Map<String,Object> map = new HashMap<>();
map.put("calc",calc);
map.put("result",result);
return map;
}catch (Exception ex){
ex.printStackTrace();
return null;
}
}
/**
* 范围随机颜色
* @param fc
* @param bc
* @return
*/
public static Color getRandomColor(int fc,int bc){
//利用随机数
Random random = new Random();
//随机颜色,了解颜色-Color(red,green,blue).rgb三元色 0-255
if(fc>255)fc = 255;
if(bc>255)bc = 255;
int r = fc+random.nextInt(bc-fc);
int g = fc+random.nextInt(bc-fc);
int b = fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
/**
* 此方法用户产生随机数字母和数字
* @return
*/
private static char randomChar(){
//1:定义验证需要的字母和数字
String string = "QWERTYUIOPASDFGHJKLZXCVBNM0123456789";
//2:定义随机对象
Random random = new Random();
return string.charAt(random.nextInt(string.length()));
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import java.lang.reflect.Field;
public class ClassUtils {
public static Object getPropertyValue(Object obj, String propertyName) throws IllegalAccessException {
Class<?> Clazz = obj.getClass();
Field field;
if ((field = getField(Clazz, propertyName)) == null)
return null;
field.setAccessible(true);
return field.get(obj);
}
public static Field getField(Class<?> clazz, String propertyName) {
if (clazz == null)
return null;
try {
return clazz.getDeclaredField(propertyName);
} catch (NoSuchFieldException e) {
return getField(clazz.getSuperclass(), propertyName);
}
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
public class CommonTool {
/**
* 部门名称裁剪
*
* @param departmentName
* @return
*/
public static String departmentNameCutOut(String departmentName) {
return departmentNameCutOut(departmentName, "江苏\\");
}
/**
* 部门名称裁剪
*
* @param departmentName
* @param cutOutStr
* @return
*/
public static String departmentNameCutOut(String departmentName, String cutOutStr) {
return departmentNameCutOut(departmentName, cutOutStr, "");
}
/**
* 部门名称裁剪
*
* @param departmentName
* @param cutOutStr
* @param defaultStr
* @return
*/
public static String departmentNameCutOut(String departmentName, String cutOutStr, String defaultStr) {
if (StringUtils.isBlank(departmentName))
return defaultStr;
if (StringUtils.isBlank(cutOutStr))
return departmentName;
if (departmentName.startsWith(cutOutStr)) {
return departmentName.substring(cutOutStr.length());
}
return departmentName.replace(cutOutStr, "");
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class CopyTool {
public static <S, T> List<T> copyList(List<S> sources, Supplier<T> target) {
List<T> list = new ArrayList<>(sources.size());
for(S source : sources) {
T t = target.get();
BeanUtils.copyProperties(source, t);
list.add(t);
}
return list;
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
;
/**
* 数据处理工具类
*/
public class DataUtils {
/**
* 解析int,解析不成功时返回默认值
*/
public static int toInt(String s, int defaultValue) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 解析Integer,解析不成功时返回null
*/
public static Integer toInt(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return null;
}
}
/**
* 解析int,解析不成功时抛出异常
*/
public static int toIntReq(String s, String message) throws ValidationException {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new ValidationException(message);
}
}
//-------------------------------------------------------------------------
/**
* 解析long,解析不成功时返回默认值
*/
public static long toLong(String s, long defaultValue) {
try {
return Long.parseLong(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 解析Long,解析不成功时返回null
*/
public static Long toLong(String s) {
try {
return Long.parseLong(s);
} catch (NumberFormatException e) {
return null;
}
}
/**
* 解析long,解析不成功时抛出异常
*/
public static long toLongReq(String s, String message) throws ValidationException {
try {
return Long.parseLong(s);
} catch (NumberFormatException e) {
throw new ValidationException(message);
}
}
//-------------------------------------------------------------------------
/**
* 解析boolean,内部调用Boolean.parseBoolean方法
* Boolean.parseBoolean兼容性极强,非true字符串都会解析成false,
* 永远不会解析失败,故只保留一个方法
* 详细测试用例可参考DataUtilsTest.testBoolean方法
*/
public static boolean toBoolean(String s) {
return Boolean.parseBoolean(s);
}
//-------------------------------------------------------------------------
/**
* 解析BigDecimal,解析不成功时返回默认值
*/
public static BigDecimal toBigDecimal(String s, BigDecimal defaultValue) {
if (StringUtils.isBlank(s))
return defaultValue;
try {
return new BigDecimal(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 解析BigDecimal,解析不成功时返回null
*/
public static BigDecimal toBigDecimal(String s) {
if (StringUtils.isBlank(s))
return null;
try {
return new BigDecimal(s);
} catch (NumberFormatException e) {
return null;
}
}
/**
* 解析BigDecimal,解析不成功时抛出异常
*/
public static BigDecimal toBigDecimalReq(String s, String message) throws ValidationException {
if (StringUtils.isBlank(s))
throw new ValidationException(message);
try {
return new BigDecimal(s);
} catch (NumberFormatException e) {
throw new ValidationException(message);
}
}
//-------------------------------------------------------------------------
/**
* 解析Date,格式为:yyyy-MM-dd,丢弃时间部分,解析不成功时返回默认值
*/
public static Date toDate(String s, Date defaultValue) {
try {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
return f.parse(s);
} catch (ParseException e) {
return defaultValue;
}
}
/**
* 解析Date,格式为:yyyy-MM-dd,丢弃时间部分,解析不成功时返回null
*/
public static Date toDate(String s) {
try {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
return f.parse(s);
} catch (ParseException e) {
return null;
}
}
/**
* 解析Date,格式为:yyyy-MM-dd,丢弃时间部分,解析不成功时抛出异常
*/
public static Date toDateReq(String s, String message) throws ValidationException {
try {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
return f.parse(s);
} catch (ParseException e) {
throw new ValidationException(message);
}
}
//-------------------------------------------------------------------------
/**
* 解析DateTime,格式为:yyyy-MM-dd HH:mm:ss,丢弃毫秒部分,解析不成功时返回默认值
*/
public static Date toDateTime(String s, Date defaultValue) {
try {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return f.parse(s);
} catch (ParseException e) {
return defaultValue;
}
}
/**
* 解析DateTime,格式为:yyyy-MM-dd HH:mm:ss,丢弃毫秒部分,解析不成功时返回null
*/
public static Date toDateTime(String s) {
try {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return f.parse(s);
} catch (ParseException e) {
return null;
}
}
/**
* 解析DateTime,格式为:yyyy-MM-dd HH:mm:ss,丢弃毫秒部分,解析不成功时抛出异常
*/
public static Date toDateTimeReq(String s, String message) throws ValidationException {
try {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return f.parse(s);
} catch (ParseException e) {
throw new ValidationException(message);
}
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import javax.sql.rowset.serial.SerialClob;
import javax.sql.rowset.serial.SerialException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
/**
* 数据库工具类
*/
public class DatabaseUtils {
public static String getBigField(ResultSet rs, String columnName) {
try {
String text = ClobToString(rs.getObject(columnName));
if (StringUtils.isBlank(text))
return "";
return text;
} catch (Exception e) {
return "";
}
}
/**
* 取Oracle nclob字段
*/
public static String getBigField(SqlRowSet sqlRowSet, String columnName) {
try {
String text = ClobToString(sqlRowSet.getObject(columnName));
if (StringUtils.isBlank(text))
return "";
return text;
} catch (Exception e) {
return "";
}
}
/**
* 将字Clob转成String类型
*/
private static String ClobToString(Object obj) {
try {
SerialClob sc = (SerialClob) obj;
String reString = "";
// 得到流
Reader is = sc.getCharacterStream();
BufferedReader br = new BufferedReader(is);
String s = br.readLine();
StringBuffer sb = new StringBuffer();
while (s != null) {
// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING
sb.append(s);
s = br.readLine();
}
reString = sb.toString();
return reString;
} catch (SerialException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* 取Mysql TIMESTAMP字段,有异常抛出
*/
public static Date getTimestampReq(SqlRowSet sqlRowSet, String columnName) throws SQLException {
Object obj = sqlRowSet.getObject(columnName);
if (!(obj instanceof Timestamp))
throw new SQLException("无法解析TIMESTAMP字段:" + columnName);
Timestamp ts = (Timestamp) obj;
Date date = ts;
return date;
}
/**
* 取Mysql TIMESTAMP字段,有异常返回null
*/
public static Date getTimestamp(SqlRowSet sqlRowSet, String columnName) {
Object obj = sqlRowSet.getObject(columnName);
if (!(obj instanceof Timestamp))
return null;
Timestamp ts = (Timestamp) obj;
try {
return new Date(ts.getTime());
} catch (Exception e) {
return null;
}
}
/**
* java.util.Date转为java.sql.Date
*/
public static java.sql.Date toSqlDate(Date date) {
if (date == null)
return null;
return new java.sql.Date(date.getTime());
}
/**
* Mysql.sql.TIMESTAMP转为java.sql.Timestamp
*/
public static Timestamp toSqlTimestamp(Object obj) {
if (!(obj instanceof Timestamp))
return null;
try {
return (Timestamp) obj;
} catch (Exception e) {
throw new RuntimeException("转换java.sql.Timestamp时发生异常。");
}
}
/**
* java.util时间类型转换为java.sql.Timestamp
*/
public static <T extends Date> Timestamp toSqlTimestamp(T date) {
if (null == date) {
return null;
}
return new Timestamp(date.getTime());
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.infoepoch.pms.dispatchassistant.common.constant.StoreKeys;
import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import com.infoepoch.pms.dispatchassistant.domain.basic.store.KeyValueStoreService;
import com.infoepoch.pms.dispatchassistant.domain.basic.user.IUserRepository;
import com.infoepoch.pms.dispatchassistant.domain.basic.user.User;
import com.infoepoch.pms.dispatchassistant.domain.oa.SSOResponse;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @author guoshun
* @description:
* @date 2022/4/1316:45
*/
@Component
public class DecodeJWTToken {
private final static Logger logger = LoggerFactory.getLogger(DecodeJWTToken.class);
private static Map<String, JWTVerifier> verifierMap = new HashMap();
private String signSecret = "infoepoch";
@Autowired
private RestTemplateUtils restTemplateUtils;
@Autowired
private KeyValueStoreService keyValueStoreService;
@Autowired
private IUserRepository userRepository;
public String getUserName(HttpServletRequest request) {
String userId = getUserIdByDecodeToken(request);
return userId;
}
public String getUserIdByDecodeToken(HttpServletRequest request) {
String userId = null;
Cookie[] cookies = request.getCookies();
logger.info("cookie = " +cookies );
if (cookies != null && cookies.length != 0) {
Cookie pmsWebCookie = Arrays.stream(cookies).filter((cookie) -> {
return "pms-web".equals(cookie.getName());
}).findAny().orElse(null);
Cookie ObSSOCookie = Arrays.stream(cookies).filter((cookie) -> {
return "ObSSOCookie".equals(cookie.getName());
}).findAny().orElse(null);
if (pmsWebCookie != null) {
String token = pmsWebCookie.getValue();
logger.info(" pms-web cookie " + token);
DecodedJWT decodedJWT = verifySessionToken(token, signSecret);
userId = decodedJWT.getClaim("accountName").asString();
} else if (ObSSOCookie != null) {
String token = ObSSOCookie.getValue();
logger.info(" ObSSOCookie cookie " + token);
User user = getUserByToken(token);
// JsonNode result = restTemplateUtils.postForLinkedMultiValueMap(keyValueStoreService.queryValueByKey(StoreKeys.PMS_API_URL), param);
userId = user.getId();
}
return userId;
} else {
return null;
}
}
/**
* 根据token获取用户信息
*
* @param token
* @return
*/
private User getUserByToken(String token) {
try {
URL httpUrl = new URL(keyValueStoreService.queryValueByKey(StoreKeys.OA_LOGIN_PAGE_URL));
logger.info("ssoLogin createSsoSession url: " + httpUrl.toString());
HttpHeaders requestHeader = new HttpHeaders();
requestHeader.setContentType(MediaType.APPLICATION_XML);
StringBuffer xmlString = new StringBuffer();
xmlString.append("<request><token>")
.append(token)
.append("</token></request>");
// 创建 HttpEntity
String url = httpUrl.toString();
HttpEntity<String> requestEntity = new HttpEntity<>(xmlString.toString(), requestHeader);
String responseEntity = invokeUrl(url, requestEntity);
logger.info("responseEntity: " + responseEntity);
//构造输入流
InputStream is = IOUtils.toInputStream(responseEntity);
SSOResponse response = (SSOResponse) XMLProxy.getInstance().fromResponseXML(is);// 从SSO获取响应结果
String status = response.getStatus();
logger.info("SSOResponse 信息:" + JsonUtils.objectToJson(response));
if ("ok".equals(status)) {
String username = response.getUid();
User user = userRepository.selectByUsername(StringTool.getString(username, "").toLowerCase());
if (user == null) {
logger.info("用户信息为空。location:TodoService.getUserByToken");
}
return user;
} else {
logger.info("OA获取用户信息失败: " + response.getMessage());
throw new ValidationException("OA获取用户信息失败");
}
} catch (MalformedURLException e) {
e.printStackTrace();
logger.info("生成OA登录地址URL报错: " + e.getMessage());
return null;
} catch (Exception e) {
e.printStackTrace();
logger.info("获取用户信息失败: " + e.getMessage());
return null;
}
}
/*
*
* 功能描述: 注册集成RestTemplate
* @Param: [url, requestEntity]
* @Return: org.springframework.http.ResponseEntity<java.lang.String>
* @Author: jill
* @Date: 2020/3/31 18:27
*/
private String invokeUrl(String url, HttpEntity<String> requestEntity) {
StringHttpMessageConverter m = new StringHttpMessageConverter(Charset.forName("UTF-8"));
RestTemplate restTemplate = new RestTemplateBuilder().additionalMessageConverters(m).build();
return restTemplate.postForObject(url, requestEntity, String.class);
}
public static DecodedJWT verifySessionToken(String tokenString, String signingToken) {
return verifyToken(tokenString, signingToken);
}
static DecodedJWT verifyToken(String tokenString, String signingToken) {
JWTVerifier verifier = (JWTVerifier) verifierMap.get(signingToken);
if (verifier == null) {
synchronized (verifierMap) {
verifier = (JWTVerifier) verifierMap.get(signingToken);
if (verifier == null) {
Algorithm algorithm = Algorithm.HMAC512(signingToken);
verifier = JWT.require(algorithm).build();
verifierMap.put(signingToken, verifier);
}
}
}
DecodedJWT jwt = verifier.verify(tokenString);
return jwt;
}
}
class OALoginInfoDto {
// 用户id
private String userId;
//员工编号
private String employeeNumber;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getEmployeeNumber() {
return employeeNumber;
}
public void setEmployeeNumber(String employeeNumber) {
this.employeeNumber = employeeNumber;
}
@Override
public String toString() {
return "OALoginInfoDto{" +
"userId='" + userId + '\'' +
", employeeNumber='" + employeeNumber + '\'' +
'}';
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import org.springframework.web.multipart.MultipartFile;
public class FileCheckTool {
private static final String allowedExtensions = ".jpg,.jpeg,.gif,.png,.bmp,.tif,.tiff,.psd,.ai,.pdf,.rtf,.doc,.docx,.csv,.xls,.xlsx,.ppt,.pptx,.vsd,.vsdx,.mpp,.rp,.zip,.rar,.7z,.tar,.tgz,.gz,.iso,.fla,.flv,.swf,.mp4";
public static String checkFileExtensionAndSize(MultipartFile file) {
String resultStr = "success";
String fullname = file.getOriginalFilename();
String extension = "";
int i = fullname.lastIndexOf(46);
if (i > 0) {
extension = "." + fullname.substring(i + 1);
}
if (file.isEmpty()) {
resultStr = fullname + "上传失败,不能上传空文件。";
throw new ValidationException(resultStr);
} else if (".".equals(extension)) {
resultStr = "上传失败:不允许上传此类型文件,允许上传的文件扩展名为:.jpg,.jpeg,.gif,.png,.bmp,.tif,.tiff,.psd,.ai,.pdf,.rtf,.doc,.docx,.csv,.xls,.xlsx,.ppt,.pptx,.vsd,.vsdx,.mpp,.rp,.zip,.rar,.7z,.tar,.tgz,.gz,.iso,.fla,.flv,.swf,.mp4";
throw new ValidationException(resultStr);
} else if (!".jpg,.jpeg,.gif,.png,.bmp,.tif,.tiff,.psd,.ai,.pdf,.rtf,.doc,.docx,.csv,.xls,.xlsx,.ppt,.pptx,.vsd,.vsdx,.mpp,.rp,.zip,.rar,.7z,.tar,.tgz,.gz,.iso,.fla,.flv,.swf,.mp4".contains(extension.toLowerCase())) {
resultStr = "上传失败:不允许上传此类型文件,允许上传的文件扩展名为:.jpg,.jpeg,.gif,.png,.bmp,.tif,.tiff,.psd,.ai,.pdf,.rtf,.doc,.docx,.csv,.xls,.xlsx,.ppt,.pptx,.vsd,.vsdx,.mpp,.rp,.zip,.rar,.7z,.tar,.tgz,.gz,.iso,.fla,.flv,.swf,.mp4";
throw new ValidationException(resultStr);
} else {
long maxSize = 1073741824L;
if (file.getSize() > maxSize) {
resultStr = "上传失败,文件大小不能超过" + autoUnitSize(maxSize) + "。";
throw new ValidationException(resultStr);
} else {
return resultStr;
}
}
}
private static String autoUnitSize(long size) {
if (size < 1024L) {
return size + "B";
} else if (size < 1048576L) {
return size / 1024L + "KB";
} else {
return size < 1073741824L ? size / 1048576L + "MB" : size / 1073741824L + "GB";
}
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* 文件工具类
*/
public class FileUtil {
/**
* 获取classPath路径下的模板文件
*
* @param request 请求
* @param templateFilePath 模板文件路径(示例:"static/template/demo.docx")
* @return
* @throws IOException
*/
public static File getFile(HttpServletRequest request, String templateFilePath) throws IOException {
File newFile;
InputStream inputStream = null;
try {
Resource resource = new ClassPathResource(templateFilePath);
inputStream = resource.getInputStream();
String realPath = request.getSession().getServletContext().getRealPath("");
String filePath = realPath + resource.getFilename();
newFile = new File(filePath);
//判断目标文件所在目录是否存在
if (!newFile.getParentFile().exists()) {
//如果目标文件所在的目录不存在,则创建父目录
newFile.getParentFile().mkdirs();
}
FileUtils.copyInputStreamToFile(inputStream, newFile);
} catch (IOException e) {
throw new IOException("未找到文件,报错:" + e.getMessage());
} finally {
if (inputStream != null)
inputStream.close();
}
return newFile;
}
/**
* 获取classPath路径下的模板文件
*
* @param templateFilePath 模板文件路径(示例:"static/template/demo.docx")
* @return
* @throws IOException
*/
public static File getFile(String templateFilePath) throws IOException {
File newFile;
InputStream inputStream = null;
try {
Resource resource = new ClassPathResource(templateFilePath);
inputStream = resource.getInputStream();
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpSession session = attr.getRequest().getSession();
String realPath = session.getServletContext().getRealPath("");
String filePath = realPath + resource.getFilename();
newFile = new File(filePath);
//判断目标文件所在目录是否存在
if (!newFile.getParentFile().exists()) {
//如果目标文件所在的目录不存在,则创建父目录
newFile.getParentFile().mkdirs();
}
FileUtils.copyInputStreamToFile(inputStream, newFile);
} catch (IOException e) {
throw new IOException("未找到文件,报错:" + e.getMessage());
} finally {
if (inputStream != null)
inputStream.close();
}
return newFile;
}
public static File getAbsFile(String absFilePath) {
return new File(absFilePath);
}
/**
* @Description: 获取临时文件路径(使用完成后,需删除文件)
* @Param: [fileName]
* @Author: zhangyd
*/
public static String getTempAbsPath(String fileName) {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpSession session = attr.getRequest().getSession();
String realPath = session.getServletContext().getRealPath("");
return realPath + fileName;
}
/**
* 下载文件
*
* @param fileAbsPath
* @throws FileNotFoundException
*/
public static void download(String fileAbsPath) {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletResponse response = attr.getResponse();
File file = new File(fileAbsPath);
// 取得文件名。
String filename = file.getName();
// 设置输出的格式
response.reset();
response.setCharacterEncoding("UTF-8");
response.addHeader("Content-Disposition", "attachment; filename=\"" + new String(filename.getBytes()) + "\"");
response.addHeader("Content-Length", "" + file.length());
try (OutputStream out = response.getOutputStream()){
Path path = file.toPath();
Files.copy(path, out);
out.flush();
}catch(IOException e){
e.printStackTrace();
}
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
public class IntegerTool {
/**
* @param one
* @param two
* @return
*/
public static int addTwoInt(Object one, Object two) {
return getInt(one) + getInt(two);
}
/**
* @param integers
* @return
*/
public static int getMaxInt(Integer... integers) {
int max = 0;
for (Integer integer : integers) {
if (max < integer) {
max = integer;
}
}
return max;
}
/**
* 获取最小值
*
* @param integers
* @return
*/
public static int getMinInt(Integer... integers) {
Integer min = null;
for (Integer integer : integers) {
if (min == null) {
min = integer;
} else if (min > integer) {
min = integer;
}
}
if (min == null) min = 0;
return min;
}
/**
* 获取最小值
*
* @param integerList
* @return
*/
public static int getMinInt(List<Integer> integerList) {
Integer min = null;
for (Integer integer : integerList) {
if (min == null) {
min = integer;
} else if (min > integer) {
min = integer;
}
}
if (min == null) min = 0;
return min;
}
/**
* 最大值向上取整
*
* @param max
* @return
*/
public static int maxIntRoundUp(int max) {
String maxStr = String.valueOf(max);
String[] arr = maxStr.split("");
if (maxStr.length() == 1) {
return 10;
}
if (maxStr.length() == 2) {
if (Integer.parseInt(arr[0]) == 9) {
return 100;
} else {
arr[0] = String.valueOf(Integer.parseInt(arr[0]) + 1);
}
arr[1] = String.valueOf(0);
}
if (maxStr.length() == 3) {
if (Integer.parseInt(arr[1]) == 9) {
if (Integer.parseInt(arr[0]) == 9) {
return 1000;
} else {
arr[0] = String.valueOf(Integer.parseInt(arr[0]) + 1);
arr[1] = String.valueOf(0);
}
} else {
arr[1] = String.valueOf(Integer.parseInt(arr[1]) + 1);
}
arr[2] = String.valueOf(0);
}
if (maxStr.length() == 4) {
if (Integer.parseInt(arr[1]) == 9) {
if (Integer.parseInt(arr[0]) == 9) {
return 100000;
} else {
arr[0] = String.valueOf(Integer.parseInt(arr[0]) + 1);
arr[1] = String.valueOf(0);
}
} else {
arr[1] = String.valueOf(Integer.parseInt(arr[1]) + 1);
}
arr[2] = String.valueOf(0);
arr[3] = String.valueOf(0);
}
if (maxStr.length() > 4) {
if (Integer.parseInt(arr[1]) == 9) {
if (Integer.parseInt(arr[0]) == 9) {
String[] tempArr = new String[arr.length + 1];
tempArr[0] = String.valueOf(1);
for (int i = 0; i < arr.length; i++) {
tempArr[i + 1] = String.valueOf(0);
}
return Integer.parseInt(StringUtils.join(tempArr));
} else {
arr[0] = String.valueOf(Integer.parseInt(arr[0]) + 1);
arr[1] = String.valueOf(0);
}
} else {
arr[1] = String.valueOf(Integer.parseInt(arr[1]) + 1);
}
for (int i = 2; i < arr.length; i++) {
arr[i] = String.valueOf(0);
}
}
return Integer.parseInt(StringUtils.join(arr));
}
/**
* 获取int
*
* @param o
* @return
*/
public static int getInt(Object o) {
return getInt(o, 0);
}
/**
* 获取int
*
* @param o
* @param defaultValue
* @return
*/
public static int getInt(Object o, int defaultValue) {
if (o == null)
return defaultValue;
if (o instanceof Integer) {
return (int) o;
}
try {
return Integer.parseInt(String.valueOf(o));
} catch (Exception e2) {
return defaultValue;
}
}
public static int getInt(Boolean b) {
return getInt(b, 0);
}
public static int getInt(Boolean b, int defaultValue) {
if (b == null)
return defaultValue;
if (b) {
return 1;
} else {
return 0;
}
}
/**
* 获取Integer对象
*
* @param str
* @return
*/
public static Integer getInteger(String str) {
try {
return Integer.parseInt(str);
} catch (Exception e) {
return null;
}
}
/**
* @param str
* @return
*/
public static boolean isNumber(String str) {
try {
Double.parseDouble(str);
return true;
} catch (Exception e) {
return false;
}
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Json工具类
*
* @author 余浩
* @date 2019-07-02
* @vision 1.0
*/
public class JsonUtils {
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
// 定义 ObjectMappe 对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 私有构造器,禁止外部实例化。
*/
private JsonUtils() {
}
/**
* java 对象转换为 json 字符串
*
* @param objectData java 对象
* @return String json 字符串
*/
public static String objectToJson(Object objectData) {
try {
String string = MAPPER.writeValueAsString(objectData);
return string;
} catch (JsonProcessingException e) {
logger.info("java 对象转换为 json 字符串 出错:{}", e);
e.printStackTrace();
}
return null;
}
/**
* json 字符串转换为 java 对象
*
* @param jsonData json 字符串
* @param beanType java 对象类型
* @return T
*/
public static <T> T jsonToObject(String jsonData, Class<T> beanType) {
// 配置忽略 json 字符串中多余的字段
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
logger.info("json 字符串转换为 java 对象 出错:", e);
throw new RuntimeException("JSON字符转换失败!");
}
}
public static <T> T jsonToObject(String jsonData, TypeReference<T> typeReference) {
// 配置忽略 json 字符串中多余的字段
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
T t = MAPPER.readValue(jsonData, typeReference);
return t;
} catch (Exception e) {
e.printStackTrace();
logger.info("json 字符串转换为 java 对象 出错:", e);
throw new RuntimeException("JSON字符转换失败!");
}
}
/**
* jsonNode 转换为 java 对象
*
* @param jsonNode jsonNode对象
* @param beanType java 对象类型
* @param <T>
* @return
*/
public static <T> T jsonNodeToObject(JsonNode jsonNode, Class<T> beanType) {
String jsonData = objectToJson(jsonNode);
return jsonToObject(jsonData, beanType);
}
/**
* java 对象转换为 JsonNode
*
* @param data java 对象
* @return JsonNode
*/
public static JsonNode objectToJsonNode(Object data) {
JsonNode jsonNode = MAPPER.valueToTree(data);
return jsonNode;
}
/**
* json 字符串转换为 JsonNode
*
* @param jsonData json 字符串
* @return JsonNode
*/
public static JsonNode jsonToJsonNode(String jsonData) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
return jsonNode;
} catch (IOException e) {
logger.info("json 字符串转换为 JsonNode 出错:{}", e);
}
return null;
}
/**
* json 字符串转换为包含 java 对象的 List
*
* @param jsonData json 字符串
* @param beanType java 对象类型
* @return List<T>
*/
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
logger.info("json 字符串转换为包含 java 对象的 List 出错:{}", e);
e.printStackTrace();
}
return null;
}
/**
* JsonNode 对象转换为包含 java 对象的 List
*
* @param jsonNode JsonNode 对象
* @param beanType java 对象类型
* @return List<T>
*/
public static <T> List<T> jsonNodeToList(JsonNode jsonNode, Class<T> beanType) {
String jsonData = objectToJson(jsonNode);
return jsonToList(jsonData, beanType);
}
// region 包含头信息json序列化
private final static String JSON_HEAD = "version";
private final static String JSON_HEAD_MESSAGE = "v1";
private final static String JSON_BODY = "item";
/**
* 将json格式化
*/
public static String formatToJson(String jsonStr) {
return "{\"" + JSON_HEAD + "\":\"" + JSON_HEAD_MESSAGE + "\",\"" + JSON_BODY + "\":" + (StringUtils.isNotBlank(jsonStr) ? jsonStr : "[]") + "}";
}
/**
* 将集合转为json
*
* @param <T> 对象类型
*/
public static <T> String toJson(List<T> items) {
ObjectNode objectNode = new ObjectNode(JsonNodeFactory.instance);
objectNode.put(JSON_HEAD, JSON_HEAD_MESSAGE);
objectNode.set(JSON_BODY, new ObjectMapper().valueToTree(items));
return JsonUtils.objectToJson(objectNode);
}
/**
* 将json转为行集合
*
* @param <T> 对象类型
*/
public static <T> List<T> parseJson(String jsonStr, Class<T> tClass) {
JsonNode jsonNode = jsonToJsonNode(jsonStr);
if (jsonNode == null || jsonNode.get(JSON_HEAD) == null)
return null;
String version = jsonNode.get(JSON_HEAD).asText();
return JSON_HEAD_MESSAGE.equalsIgnoreCase(version) ? jsonNodeToList(jsonNode.get(JSON_BODY), tClass) : null;
}
// endregion
public static String filterToString(SimpleFilterProvider simpleFilterProvider, Object object) {
MAPPER.setFilterProvider(simpleFilterProvider);
try {
return MAPPER.writeValueAsString(object);
} catch (JsonProcessingException e) {
logger.info("序列化过滤错误!\n{}", printToJsonString(object));
e.printStackTrace();
}
return "";
}
/**
* 美化JSON输出
*/
public static String printToJsonString(Object object) {
try {
return "\n" + MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
} catch (JsonProcessingException e) {
logger.info("JSON打印异常。");
e.printStackTrace();
}
return "";
}
public static Map<String, Object> jsonToMap(String jsonStr) {
Map<String, Object> tmpMap = new HashMap<>();
try {
tmpMap = MAPPER.readValue(jsonStr, Map.class);
} catch (Exception ex) {
logger.info("JSON转换异常。");
ex.printStackTrace();
}
return tmpMap;
}
public static List<Map<String, Object>> jsonToMapList(String jsonStr) {
List<Map<String, Object>> mapList = new ArrayList<>();
try {
mapList = MAPPER.readValue(jsonStr, new TypeReference<List<Map<String, Object>>>() {
@Override
public Type getType() {
return super.getType();
}
});
} catch (Exception ex) {
logger.info("JSON转换异常。");
ex.printStackTrace();
}
return mapList;
}
}
package com.infoepoch.pms.dispatchassistant.common.utils;
import java.util.Map;
import java.util.stream.Collectors;
public class MapTool {
/**
* MAP反转
*
* @param map
* @param <K>
* @param <V>
* @return
*/
public static <K, V> Map<V, K> mapReverse(Map<K, V> map) {
return map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
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