Merge branch 'master-stander' into master-jiayan
New file |
| | |
| | | # Compiled class file |
| | | *.class |
| | | |
| | | # Log file |
| | | *.log |
| | | |
| | | # BlueJ files |
| | | *.ctxt |
| | | |
| | | # Mobile Tools for Java (J2ME) |
| | | .mtj.tmp/ |
| | | |
| | | # Package Files # |
| | | *.jar |
| | | *.war |
| | | *.nar |
| | | *.ear |
| | | *.zip |
| | | *.tar.gz |
| | | *.rar |
| | | |
| | | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
| | | hs_err_pid* |
| | | /target |
| | | /.idea |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <parent> |
| | | <groupId>com.hx.gitee</groupId> |
| | | <artifactId>hx-parent</artifactId> |
| | | <version>stander</version> |
| | | </parent> |
| | | |
| | | <artifactId>hx-redisson</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <dependencies> |
| | | |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>commons-collections</groupId> |
| | | <artifactId>commons-collections</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.dtflys.forest</groupId> |
| | | <artifactId>spring-boot-starter-forest</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter --> |
| | | <dependency> |
| | | <groupId>org.redisson</groupId> |
| | | <artifactId>redisson-spring-boot-starter</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- redis --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-redis</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | | <finalName>hx-redisson</finalName> |
| | | <resources> |
| | | <resource> |
| | | <directory>src/main/java</directory> |
| | | <includes> |
| | | <include>**/*.properties</include> |
| | | <include>**/*.xml</include> |
| | | <include>**/*.tld</include> |
| | | <include>**/*.tpl</include> |
| | | </includes> |
| | | <filtering>false</filtering> |
| | | </resource> |
| | | <resource> |
| | | <directory>src/main/resources</directory> |
| | | <excludes> |
| | | <exclude>profile-active/**</exclude> |
| | | </excludes> |
| | | </resource> |
| | | <resource> |
| | | <directory>${runtime.env}</directory> |
| | | </resource> |
| | | </resources> |
| | | </build> |
| | | |
| | | </project> |
New file |
| | |
| | | package com.hx.redisson.bean.annotations; |
| | | |
| | | import com.hx.redisson.config.RedisBeanInit; |
| | | import com.hx.redisson.config.RedissonConfig; |
| | | import com.hx.redisson.config.RedissonUtil; |
| | | import com.hx.redisson.register.RedisRegister; |
| | | import org.springframework.context.annotation.Import; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /**使用redis链接 |
| | | *这里的Import的两个类就是需要加载的bean,这样就可以通过简单的添加一个注解来加载自己自定义的bean了,而且可 |
| | | *以是很多个,可以打到jar包里面通过Maven引入都是ok的; |
| | | * @author CJH |
| | | * @date 202-06-17 |
| | | */ |
| | | @Target(ElementType.TYPE) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | @Import({RedisBeanInit.class,RedisRegister.class, RedissonUtil.class, RedissonConfig.class}) |
| | | public @interface RedissonClient { |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.redisson.config; |
| | | |
| | | import com.hx.redisson.entity.RedissondbConfigEntity; |
| | | import com.hx.redisson.manager.RedisManager; |
| | | import org.apache.commons.collections.CollectionUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.boot.autoconfigure.AutoConfigureBefore; |
| | | import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; |
| | | import org.springframework.boot.context.properties.bind.Binder; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.context.EnvironmentAware; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.core.env.Environment; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | |
| | | import javax.annotation.PostConstruct; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | /** |
| | | * RedisTemplate 初始化类 |
| | | * |
| | | * @author CJH |
| | | * @date 2020年12月16日22:38:46 |
| | | */ |
| | | /**要在RedisAutoConfiguration 自动配置前执行*/ |
| | | @AutoConfigureBefore({RedisAutoConfiguration.class}) |
| | | /**实现 EnvironmentAware 用于获取全局环境 |
| | | 实现 ApplicationContextAware 用于获取Spring Context 上下文*/ |
| | | public class RedisBeanInit implements EnvironmentAware, ApplicationContextAware { |
| | | private Logger logger = LoggerFactory.getLogger(RedisBeanInit.class); |
| | | |
| | | /**用于获取环境配置*/ |
| | | private Environment environment; |
| | | /**用于绑定对象*/ |
| | | private Binder binder; |
| | | /**Spring context*/ |
| | | private ApplicationContext applicationContext; |
| | | /**线程安全的hashmap*/ |
| | | private Map<String, RedisTemplate> redisTemplateMap = new ConcurrentHashMap<>(); |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
| | | this.applicationContext = applicationContext; |
| | | } |
| | | /** |
| | | * 设置环境 |
| | | * |
| | | * @param environment |
| | | */ |
| | | @Override |
| | | public void setEnvironment(Environment environment) { |
| | | this.environment = environment; |
| | | this.binder = Binder.get(environment); |
| | | } |
| | | |
| | | |
| | | @PostConstruct // Constructor >> @Autowired >> @PostConstruct 用于执行一个 非静态的void 方法,常应用于初始化资源 |
| | | public void initAllRedisTemlate() { |
| | | logger.info("<<<初始化系统的RedisTemlate开始>>>"); |
| | | RedissondbConfigEntity redissondb; |
| | | try { |
| | | redissondb = binder.bind("redissondb", RedissondbConfigEntity.class).get(); |
| | | } catch (Exception e) { |
| | | logger.error("读取redissondb环境配置失败", e); |
| | | return; |
| | | } |
| | | List<Integer> databases = redissondb.getDatabases(); |
| | | if (CollectionUtils.isNotEmpty(databases)) { |
| | | databases.forEach(db -> { |
| | | Object bean = applicationContext.getBean("redisTemplate" + db); |
| | | if (bean != null && bean instanceof RedisTemplate) { |
| | | redisTemplateMap.put("redisTemplate" + db, (RedisTemplate) bean); |
| | | } else { |
| | | throw new RuntimeException("初始化RedisTemplate" + db + "失败,请检查配置"); |
| | | } |
| | | }); |
| | | } |
| | | logger.info("已经装配的redistempleate,map:{}", redisTemplateMap); |
| | | logger.info("<<<初始化系统的RedisTemlate完毕>>>"); |
| | | } |
| | | |
| | | @Bean |
| | | public RedisManager getRedisManager() { |
| | | return new RedisManager(redisTemplateMap); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.redisson.config; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonAutoDetect; |
| | | import com.fasterxml.jackson.annotation.PropertyAccessor; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.data.redis.connection.RedisConnectionFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; |
| | | import org.springframework.data.redis.serializer.StringRedisSerializer; |
| | | |
| | | /**配置实例化 |
| | | * CJH |
| | | */ |
| | | @Configuration |
| | | public class RedissonConfig { |
| | | @Bean |
| | | public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { |
| | | RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); |
| | | template.setConnectionFactory(factory); |
| | | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); |
| | | ObjectMapper om = new ObjectMapper(); |
| | | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); |
| | | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); |
| | | jackson2JsonRedisSerializer.setObjectMapper(om); |
| | | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); |
| | | template.setKeySerializer(stringRedisSerializer); |
| | | template.setHashKeySerializer(stringRedisSerializer); |
| | | template.setValueSerializer(jackson2JsonRedisSerializer); |
| | | template.setHashValueSerializer(jackson2JsonRedisSerializer); |
| | | template.afterPropertiesSet(); |
| | | return template; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.redisson.config; |
| | | |
| | | import com.hx.redisson.manager.RedisManager; |
| | | import org.redisson.api.RLock; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.core.ZSetOperations; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * <h1>RedisUtil 操作工具类</h1> |
| | | * @author CJH |
| | | */ |
| | | public class RedissonUtil { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(RedissonUtil.class); |
| | | |
| | | @Autowired |
| | | private RedisManager redisManager; |
| | | |
| | | @Autowired |
| | | private RedisTemplate redisTemplate; |
| | | |
| | | /** |
| | | * 指定缓存失效时间 |
| | | * @param key 键 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean expire(String key, long time) { |
| | | try { |
| | | if (time < 0) { |
| | | throw new RuntimeException("设置时间不能为负数:"+time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 指定缓存失效时间 |
| | | * |
| | | * @param key 键 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean expire(String key, long time,int db) { |
| | | try { |
| | | if (time < 0) { |
| | | throw new RuntimeException("设置时间不能为负数:"+time); |
| | | } |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.expire(key, time, TimeUnit.SECONDS); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 指定缓存失效时间 |
| | | * |
| | | * @param key 键 |
| | | * @param time 时间 |
| | | * @param timeUnit 时间类型 |
| | | * @return |
| | | */ |
| | | public boolean expire(String key, long time, TimeUnit timeUnit) { |
| | | try { |
| | | if (time < 0) { |
| | | throw new RuntimeException("设置时间不能为负数:"+time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 指定缓存失效时间 |
| | | * |
| | | * @param key 键 |
| | | * @param time 时间 |
| | | * @param timeUnit 时间类型 |
| | | * @return |
| | | */ |
| | | public boolean expire(String key, long time, TimeUnit timeUnit,int db) { |
| | | try { |
| | | if (time < 0) { |
| | | throw new RuntimeException("设置时间不能为负数:"+time); |
| | | } |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.expire(key, time, timeUnit); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据key 获取过期时间 |
| | | * |
| | | * @param key 键 不能为null |
| | | * @return 时间(秒) 返回0代表为永久有效 |
| | | */ |
| | | public long getExpire(String key) { |
| | | return redisTemplate.getExpire(key, TimeUnit.SECONDS); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据key 获取过期时间 |
| | | * |
| | | * @param key 键 不能为null |
| | | * @return 时间(秒) 返回0代表为永久有效 |
| | | */ |
| | | public long getExpire(String key,int db) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.getExpire(key, TimeUnit.SECONDS); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断key是否存在 |
| | | * |
| | | * @param key 键 |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean hasKey(String key) { |
| | | try { |
| | | return redisTemplate.hasKey(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 判断key是否存在 |
| | | * |
| | | * @param key 键 |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean hasKey(String key,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.hasKey(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除缓存 |
| | | * |
| | | * @param key 可以传一个值 或多个 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public void del(String... key) { |
| | | if (key != null && key.length > 0) { |
| | | if (key.length == 1) { |
| | | redisTemplate.delete(key[0]); |
| | | } else { |
| | | redisTemplate.delete(CollectionUtils.arrayToList(key)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除缓存 |
| | | * |
| | | * @param key 可以传一个值 或多个 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public void del(int db,String... key) { |
| | | if (key != null && key.length > 0) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | if (key.length == 1) { |
| | | redisTemplate.delete(key[0]); |
| | | } else { |
| | | redisTemplate.delete(CollectionUtils.arrayToList(key)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // ============================String============================= |
| | | |
| | | /** |
| | | * 普通缓存获取 |
| | | * |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | public Object get(String key) { |
| | | return key == null ? null : redisTemplate.opsForValue().get(key); |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存获取 |
| | | * |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | public Object get(String key,int db) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return key == null ? null : redisTemplate.opsForValue().get(key); |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return true成功 false失败 |
| | | */ |
| | | public boolean set(String key, Object value) { |
| | | try { |
| | | redisTemplate.opsForValue().set(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return true成功 false失败 |
| | | */ |
| | | public boolean set(String key, Object value,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForValue().set(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 普通缓存放入并设置时间 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public boolean set(String key, Object value, long time) { |
| | | try { |
| | | if (time > 0) { |
| | | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); |
| | | } else { |
| | | set(key, value); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入并设置时间 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public boolean set(String key, Object value, long time,int db) { |
| | | try { |
| | | if (time > 0) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); |
| | | } else { |
| | | set(key, value,db); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入并设置时间,并增加时间类型选择 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间 time要大于0 如果time小于等于0 将设置无限期 |
| | | * @param timeUnit 时间类型 |
| | | * @return |
| | | */ |
| | | public boolean set(String key, Object value, long time, TimeUnit timeUnit) { |
| | | try { |
| | | if (time > 0) { |
| | | redisTemplate.opsForValue().set(key, value, time, timeUnit); |
| | | } else { |
| | | set(key, value); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入并设置时间,并增加时间类型选择 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间 time要大于0 如果time小于等于0 将设置无限期 |
| | | * @param timeUnit 时间类型 |
| | | * @return |
| | | */ |
| | | public boolean set(String key, Object value, long time, TimeUnit timeUnit,int db) { |
| | | try { |
| | | if (time > 0) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForValue().set(key, value, time, timeUnit); |
| | | } else { |
| | | set(key, value,db); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 递增 |
| | | * |
| | | * @param key 键 |
| | | * @param delta 要增加几(大于0) |
| | | * @return |
| | | */ |
| | | public long incr(String key, long delta) { |
| | | if (delta < 0) { |
| | | throw new RuntimeException("递增因子必须大于0"); |
| | | } |
| | | return redisTemplate.opsForValue().increment(key, delta); |
| | | } |
| | | |
| | | /** |
| | | * 递增 |
| | | * |
| | | * @param key 键 |
| | | * @param delta 要增加几(大于0) |
| | | * @return |
| | | */ |
| | | public long incr(String key, long delta,int db) { |
| | | if (delta < 0) { |
| | | throw new RuntimeException("递增因子必须大于0"); |
| | | } |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForValue().increment(key, delta); |
| | | } |
| | | |
| | | /** |
| | | * 递减 |
| | | * |
| | | * @param key 键 |
| | | * @param delta 要减少几(小于0) |
| | | * @return |
| | | */ |
| | | public long decr(String key, long delta) { |
| | | if (delta < 0) { |
| | | throw new RuntimeException("递减因子必须大于0"); |
| | | } |
| | | return redisTemplate.opsForValue().increment(key, -delta); |
| | | } |
| | | |
| | | /** |
| | | * 递减 |
| | | * |
| | | * @param key 键 |
| | | * @param delta 要减少几(小于0) |
| | | * @return |
| | | */ |
| | | public long decr(String key, long delta,int db) { |
| | | if (delta < 0) { |
| | | throw new RuntimeException("递减因子必须大于0"); |
| | | } |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForValue().increment(key, -delta); |
| | | } |
| | | |
| | | |
| | | /**如果值存在就不存入,如果不存在就存入 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param timeOut 时间 |
| | | * @param unit 时间单位 |
| | | */ |
| | | public Boolean setIfAbsent(String key, Object value, long timeOut, TimeUnit unit) { |
| | | try { |
| | | return redisTemplate.opsForValue().setIfAbsent(key, value, timeOut, unit); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /**如果值存在就不存入,如果不存在就存入 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param timeOut 时间 |
| | | * @param unit 时间单位 |
| | | */ |
| | | public Boolean setIfAbsent(String key, Object value, long timeOut, TimeUnit unit,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForValue().setIfAbsent(key, value, timeOut, unit); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | // ================================Map================================= |
| | | |
| | | /** |
| | | * HashGet |
| | | * |
| | | * @param key 键 不能为null |
| | | * @param item 项 不能为null |
| | | * @return 值 |
| | | */ |
| | | public Object hget(String key, String item) { |
| | | return redisTemplate.opsForHash().get(key, item); |
| | | } |
| | | |
| | | /** |
| | | * HashGet |
| | | * |
| | | * @param key 键 不能为null |
| | | * @param item 项 不能为null |
| | | * @return 值 |
| | | */ |
| | | public Object hget(String key, String item,int db) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForHash().get(key, item); |
| | | } |
| | | |
| | | /** |
| | | * 获取hashKey对应的所有键值 |
| | | * |
| | | * @param key 键 |
| | | * @return 对应的多个键值 |
| | | */ |
| | | public Map<Object, Object> hmget(String key) { |
| | | return redisTemplate.opsForHash().entries(key); |
| | | } |
| | | |
| | | /** |
| | | * 获取hashKey对应的所有键值 |
| | | * |
| | | * @param key 键 |
| | | * @return 对应的多个键值 |
| | | */ |
| | | public Map<Object, Object> hmget(String key,int db) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForHash().entries(key); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * HashSet |
| | | * |
| | | * @param key 键 |
| | | * @param map 对应多个键值 |
| | | * @return true 成功 false 失败 |
| | | */ |
| | | public boolean hmset(String key, Map<String, Object> map) { |
| | | try { |
| | | redisTemplate.opsForHash().putAll(key, map); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * HashSet |
| | | * |
| | | * @param key 键 |
| | | * @param map 对应多个键值 |
| | | * @return true 成功 false 失败 |
| | | */ |
| | | public boolean hmset(String key, Map<String, Object> map,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForHash().putAll(key, map); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * HashSet 并设置时间 |
| | | * |
| | | * @param key 键 |
| | | * @param map 对应多个键值 |
| | | * @param time 时间(秒) |
| | | * @return true成功 false失败 |
| | | */ |
| | | public boolean hmset(String key, Map<String, Object> map, long time) { |
| | | try { |
| | | redisTemplate.opsForHash().putAll(key, map); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * HashSet 并设置时间 |
| | | * |
| | | * @param key 键 |
| | | * @param map 对应多个键值 |
| | | * @param time 时间(秒) |
| | | * @return true成功 false失败 |
| | | */ |
| | | public boolean hmset(String key, Map<String, Object> map, long time,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForHash().putAll(key, map); |
| | | if (time > 0) { |
| | | expire(key, time,db); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 向一张hash表中放入数据,如果不存在将创建 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param value 值 |
| | | * @return true 成功 false失败 |
| | | */ |
| | | public boolean hset(String key, String item, Object value) { |
| | | try { |
| | | redisTemplate.opsForHash().put(key, item, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 向一张hash表中放入数据,如果不存在将创建 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param value 值 |
| | | * @return true 成功 false失败 |
| | | */ |
| | | public boolean hset(String key, String item, Object value,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForHash().put(key, item, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 向一张hash表中放入数据,如果不存在将创建 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param value 值 |
| | | * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 |
| | | * @return true 成功 false失败 |
| | | */ |
| | | public boolean hset(String key, String item, Object value, long time) { |
| | | try { |
| | | redisTemplate.opsForHash().put(key, item, value); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 向一张hash表中放入数据,如果不存在将创建 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param value 值 |
| | | * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 |
| | | * @return true 成功 false失败 |
| | | */ |
| | | public boolean hset(String key, String item, Object value, long time,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForHash().put(key, item, value); |
| | | if (time > 0) { |
| | | expire(key, time,db); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除hash表中的值 |
| | | * |
| | | * @param key 键 不能为null |
| | | * @param item 项 可以使多个 不能为null |
| | | */ |
| | | public void hdel(String key, Object... item) { |
| | | redisTemplate.opsForHash().delete(key, item); |
| | | } |
| | | |
| | | /** |
| | | * 删除hash表中的值 |
| | | * |
| | | * @param key 键 不能为null |
| | | * @param item 项 可以使多个 不能为null |
| | | */ |
| | | public void hdel(int db,String key, Object... item) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForHash().delete(key, item); |
| | | } |
| | | |
| | | /** |
| | | * 判断hash表中是否有该项的值 |
| | | * |
| | | * @param key 键 不能为null |
| | | * @param item 项 不能为null |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean hHasKey(String key, String item) { |
| | | return redisTemplate.opsForHash().hasKey(key, item); |
| | | } |
| | | |
| | | /** |
| | | * 判断hash表中是否有该项的值 |
| | | * |
| | | * @param key 键 不能为null |
| | | * @param item 项 不能为null |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean hHasKey(String key, String item,int db) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForHash().hasKey(key, item); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * hash递增 如果不存在,就会创建一个 并把新增后的值返回 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param by 要增加几(大于0) |
| | | * @return |
| | | */ |
| | | public double hincr(String key, String item, double by) { |
| | | return redisTemplate.opsForHash().increment(key, item, by); |
| | | } |
| | | |
| | | /** |
| | | * hash递增 如果不存在,就会创建一个 并把新增后的值返回 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param by 要增加几(大于0) |
| | | * @return |
| | | */ |
| | | public double hincr(String key, String item, double by,int db) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForHash().increment(key, item, by); |
| | | } |
| | | |
| | | /** |
| | | * hash递减 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param by 要减少记(小于0) |
| | | * @return |
| | | */ |
| | | public double hdecr(String key, String item, double by) { |
| | | return redisTemplate.opsForHash().increment(key, item, -by); |
| | | } |
| | | |
| | | /** |
| | | * hash递减 |
| | | * |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param by 要减少记(小于0) |
| | | * @return |
| | | */ |
| | | public double hdecr(String key, String item, double by,int db) { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForHash().increment(key, item, -by); |
| | | } |
| | | |
| | | // ============================set============================= |
| | | |
| | | /** |
| | | * 根据key获取Set中的所有值 |
| | | * |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | public Set<Object> sGet(String key) { |
| | | try { |
| | | return redisTemplate.opsForSet().members(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据key获取Set中的所有值 |
| | | * |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | public Set<Object> sGet(String key,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForSet().members(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据key获取Set中的指定几个随机内容 |
| | | * |
| | | * @param key 键 |
| | | * @param size 个数 |
| | | * @return |
| | | */ |
| | | public List sRandomGet(String key, Integer size) { |
| | | try { |
| | | return redisTemplate.opsForSet().randomMembers(key, size); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据key获取Set中的指定几个随机内容 |
| | | * |
| | | * @param key 键 |
| | | * @param size 个数 |
| | | * @return |
| | | */ |
| | | public List sRandomGet(String key, Integer size,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForSet().randomMembers(key, size); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据value从一个set中查询,是否存在 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean sHasKey(String key, Object value) { |
| | | try { |
| | | return redisTemplate.opsForSet().isMember(key, value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据value从一个set中查询,是否存在 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean sHasKey(String key, Object value,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForSet().isMember(key, value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将数据放入set缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param values 值 可以是多个 |
| | | * @return 成功个数 |
| | | */ |
| | | public long sSet(String key, Object... values) { |
| | | try { |
| | | return redisTemplate.opsForSet().add(key, values); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将数据放入set缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param values 值 可以是多个 |
| | | * @return 成功个数 |
| | | */ |
| | | public long sSet(int db,String key, Object... values) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForSet().add(key, values); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将set数据放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param time 时间(秒) |
| | | * @param values 值 可以是多个 |
| | | * @return 成功个数 |
| | | */ |
| | | public long sSetAndTime(String key, long time, Object... values) { |
| | | try { |
| | | Long count = redisTemplate.opsForSet().add(key, values); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将set数据放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param time 时间(秒) |
| | | * @param values 值 可以是多个 |
| | | * @return 成功个数 |
| | | */ |
| | | public long sSetAndTime(int db,String key, long time, Object... values) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | Long count = redisTemplate.opsForSet().add(key, values); |
| | | if (time > 0) { |
| | | expire(key, time,db); |
| | | } |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取set缓存的长度 |
| | | * |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | public long sGetSetSize(String key) { |
| | | try { |
| | | return redisTemplate.opsForSet().size(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取set缓存的长度 |
| | | * |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | public long sGetSetSize(String key,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForSet().size(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 移除值为value的 |
| | | * |
| | | * @param key 键 |
| | | * @param values 值 可以是多个 |
| | | * @return 移除的个数 |
| | | */ |
| | | public long setRemove(String key, Object... values) { |
| | | try { |
| | | Long count = redisTemplate.opsForSet().remove(key, values); |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 移除值为value的 |
| | | * |
| | | * @param key 键 |
| | | * @param values 值 可以是多个 |
| | | * @return 移除的个数 |
| | | */ |
| | | public long setRemove(int db,String key, Object... values) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | Long count = redisTemplate.opsForSet().remove(key, values); |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | // ===============================list================================= |
| | | |
| | | /** |
| | | * 获取list缓存的内容 |
| | | * |
| | | * @param key 键 |
| | | * @param start 开始 |
| | | * @param end 结束 0 到 -1代表所有值 |
| | | * @return |
| | | */ |
| | | public List<Object> lGet(String key, long start, long end) { |
| | | try { |
| | | return redisTemplate.opsForList().range(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取list缓存的内容 |
| | | * |
| | | * @param key 键 |
| | | * @param start 开始 |
| | | * @param end 结束 0 到 -1代表所有值 |
| | | * @return |
| | | */ |
| | | public List<Object> lGet(String key, long start, long end,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForList().range(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取list缓存的长度 |
| | | * |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | public long lGetListSize(String key) { |
| | | try { |
| | | return redisTemplate.opsForList().size(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取list缓存的长度 |
| | | * |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | public long lGetListSize(String key,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForList().size(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引 获取list中的值 |
| | | * |
| | | * @param key 键 |
| | | * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 |
| | | * @return |
| | | */ |
| | | public Object lGetIndex(String key, long index) { |
| | | try { |
| | | return redisTemplate.opsForList().index(key, index); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引 获取list中的值 |
| | | * |
| | | * @param key 键 |
| | | * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 |
| | | * @return |
| | | */ |
| | | public Object lGetIndex(String key, long index,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForList().index(key, index); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, Object value) { |
| | | try { |
| | | redisTemplate.opsForList().rightPush(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, Object value,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForList().rightPush(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, Object value, long time) { |
| | | try { |
| | | redisTemplate.opsForList().rightPush(key, value); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, Object value, long time,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForList().rightPush(key, value); |
| | | if (time > 0) { |
| | | expire(key, time,db); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lSetAll(String key, List<Object> value) { |
| | | try { |
| | | redisTemplate.opsForList().rightPushAll(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lSetAll(String key, List<Object> value,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForList().rightPushAll(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean lSetAll(String key, List<Object> value, long time) { |
| | | try { |
| | | // 设置超时时间 原子化 |
| | | redisTemplate.opsForList().rightPushAll(key, value); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean lSetAll(String key, List<Object> value, long time,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | // 设置超时时间 原子化 |
| | | redisTemplate.opsForList().rightPushAll(key, value); |
| | | if (time > 0) { |
| | | expire(key, time,db); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据索引修改list中的某条数据 |
| | | * |
| | | * @param key 键 |
| | | * @param index 索引 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lUpdateIndex(String key, long index, Object value) { |
| | | try { |
| | | redisTemplate.opsForList().set(key, index, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据索引修改list中的某条数据 |
| | | * |
| | | * @param key 键 |
| | | * @param index 索引 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lUpdateIndex(String key, long index, Object value,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | redisTemplate.opsForList().set(key, index, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 移除N个值为value |
| | | * |
| | | * @param key 键 |
| | | * @param count 移除多少个 |
| | | * @param value 值 |
| | | * @return 移除的个数 |
| | | */ |
| | | public long lRemove(String key, long count, Object value) { |
| | | try { |
| | | Long remove = redisTemplate.opsForList().remove(key, count, value); |
| | | return remove; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 移除N个值为value |
| | | * |
| | | * @param key 键 |
| | | * @param count 移除多少个 |
| | | * @param value 值 |
| | | * @return 移除的个数 |
| | | */ |
| | | public long lRemove(String key, long count, Object value,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | Long remove = redisTemplate.opsForList().remove(key, count, value); |
| | | return remove; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据给定的布隆过滤器添加值 |
| | | * |
| | | * @param bloomFilterHelper bloom布隆过滤器解析类 |
| | | * @param key redis 的key |
| | | * @param value redis 的value |
| | | * @param <T> 值的类型 |
| | | */ |
| | | /*public <T> void addByBloomFilter(BloomFilterHelper<T> bloomFilterHelper, String key, T value) { |
| | | Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空"); |
| | | int[] offset = bloomFilterHelper.murmurHashOffset(value); |
| | | for (int i : offset) { |
| | | redisTemplate.opsForValue().setBit(key, i, true); |
| | | } |
| | | }*/ |
| | | |
| | | |
| | | /** |
| | | * 根据给定的布隆过滤器判断值是否存在 |
| | | * |
| | | * @param bloomFilterHelper bloom布隆过滤器解析类 |
| | | * @param key redis 的key |
| | | * @param value redis 的value |
| | | * @param <T> 值的类型 |
| | | * @return 存在 true |
| | | */ |
| | | /* public <T> boolean includeByBloomFilter(BloomFilterHelper<T> bloomFilterHelper, String key, T value) { |
| | | Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空"); |
| | | int[] offset = bloomFilterHelper.murmurHashOffset(value); |
| | | for (int i : offset) { |
| | | if (!redisTemplate.opsForValue().getBit(key, i)) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | }*/ |
| | | |
| | | |
| | | /** |
| | | * zset 添加元素 |
| | | * |
| | | * @param key |
| | | * @param time |
| | | * @param tuples |
| | | * @return |
| | | */ |
| | | public long zsSetAndTime(String key, long time, Set<ZSetOperations.TypedTuple<Object>> tuples) { |
| | | try { |
| | | Long count = redisTemplate.opsForZSet().add(key, tuples); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * zset 添加元素 |
| | | * |
| | | * @param key |
| | | * @param time |
| | | * @param tuples |
| | | * @return |
| | | */ |
| | | public long zsSetAndTime(String key, long time, Set<ZSetOperations.TypedTuple<Object>> tuples,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | Long count = redisTemplate.opsForZSet().add(key, tuples); |
| | | if (time > 0) { |
| | | expire(key, time,db); |
| | | } |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * zset 添加元素 |
| | | * |
| | | * @param key |
| | | * @param tuples |
| | | * @return |
| | | */ |
| | | public long zsSet(String key, Set<ZSetOperations.TypedTuple<Object>> tuples) { |
| | | try { |
| | | Long count = redisTemplate.opsForZSet().add(key, tuples); |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * zset 添加元素 |
| | | * |
| | | * @param key |
| | | * @param tuples |
| | | * @return |
| | | */ |
| | | public long zsSet(String key, Set<ZSetOperations.TypedTuple<Object>> tuples,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | Long count = redisTemplate.opsForZSet().add(key, tuples); |
| | | return count; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * zs 移除元素 |
| | | * |
| | | * @param key |
| | | * @param values |
| | | * @return |
| | | */ |
| | | public long zsRemove(String key, Object... values) { |
| | | try { |
| | | Long remove = redisTemplate.opsForZSet().remove(key, values); |
| | | return remove; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * zs 移除元素 |
| | | * |
| | | * @param key |
| | | * @param values |
| | | * @return |
| | | */ |
| | | public long zsRemove(int db,String key, Object... values) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | Long remove = redisTemplate.opsForZSet().remove(key, values); |
| | | return remove; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合 仅返回 key |
| | | */ |
| | | public Set zsGet(String key, long start, long end) { |
| | | try { |
| | | return redisTemplate.opsForZSet().range(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合 仅返回 key |
| | | */ |
| | | public Set zsGet(String key, long start, long end,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForZSet().range(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合,返回成员对象 |
| | | */ |
| | | public Set zsGetWithScores(String key, long start, long end) { |
| | | try { |
| | | return redisTemplate.opsForZSet().rangeWithScores(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合,返回成员对象 |
| | | */ |
| | | public Set zsGetWithScores(String key, long start, long end,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForZSet().rangeWithScores(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递减(从大到小)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合 仅返回 key |
| | | */ |
| | | public Set zsGetReverse(String key, long start, long end) { |
| | | try { |
| | | return redisTemplate.opsForZSet().reverseRange(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递减(从大到小)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合 仅返回 key |
| | | */ |
| | | public Set zsGetReverse(String key, long start, long end,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForZSet().reverseRange(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员对象,其中有序集成员按分数值递减(从大到小)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合,返回成员对象 |
| | | */ |
| | | public Set zsGetReverseWithScores(String key, long start, long end) { |
| | | try { |
| | | return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通过索引区间返回有序集合成指定区间内的成员对象,其中有序集成员按分数值递减(从大到小)顺序排列 |
| | | * |
| | | * @param key 键 |
| | | * @param start 起始位置 0 |
| | | * @param end 末尾位置 -1 |
| | | * @return 0 -1 返回按分数递增的顺序集合,返回成员对象 |
| | | */ |
| | | public Set zsGetReverseWithScores(String key, long start, long end,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 原子加 |
| | | * @param key 键 |
| | | * @param num 数量 |
| | | */ |
| | | public Long increment(String key,long num) { |
| | | try { |
| | | return redisTemplate.opsForValue().increment(key, num); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 原子加 |
| | | * @param key 键 |
| | | * @param num 数量 |
| | | * @param db 数据库 |
| | | */ |
| | | public Long increment(String key,long num,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForValue().increment(key, num); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 原子减 |
| | | * @param key 键 |
| | | * @param num 数量 |
| | | */ |
| | | public Long decrement(String key,long num) { |
| | | try { |
| | | return redisTemplate.opsForValue().decrement(key, num); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 原子减 |
| | | * @param key 键 |
| | | * @param num 数量 |
| | | * @param db 数据库 |
| | | */ |
| | | public Long decrement(String key,long num,int db) { |
| | | try { |
| | | RedisTemplate redisTemplate = redisManager.getRedisTemplate(db); |
| | | return redisTemplate.opsForValue().decrement(key, num); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取红锁 |
| | | * @param key 锁key |
| | | * @param db 数据库编号 |
| | | */ |
| | | public RLock getRLock(String key,int db) { |
| | | RLock lock = null; |
| | | try { |
| | | RedissonClient redissonClient = RedisManager.redissonTemplateMap.get(db+""); |
| | | lock = redissonClient.getLock(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return lock; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.redisson.entity; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * redisconfig 配置实体类 |
| | | * |
| | | * @author CJH |
| | | * @date 2022-06-27 |
| | | */ |
| | | @Data |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class RedissondbConfigEntity implements Serializable { |
| | | /**地址*/ |
| | | private String host; |
| | | /**端口*/ |
| | | private String port; |
| | | /**密码*/ |
| | | private String password; |
| | | /**所有的db序号*/ |
| | | private List<Integer> databases = new ArrayList<>(); |
| | | } |
| | | |
New file |
| | |
| | | package com.hx.redisson.manager; |
| | | |
| | | import org.redisson.api.RedissonClient; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | /** |
| | | * redis管理 |
| | | * |
| | | * @author CJH |
| | | * @date 2022-06-27 |
| | | */ |
| | | public class RedisManager { |
| | | |
| | | private Map<String, RedisTemplate> redisTemplateMap = new ConcurrentHashMap<>(); |
| | | |
| | | public static Map<String, RedissonClient> redissonTemplateMap = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * 构造方法初始化 redisTemplateMap 的数据 |
| | | * |
| | | * @param redisTemplateMap |
| | | */ |
| | | public RedisManager(Map<String, RedisTemplate> redisTemplateMap) { |
| | | this.redisTemplateMap = redisTemplateMap; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据数据库序号,返回对应的RedisTemplate |
| | | * |
| | | * @param dbIndex 序号 |
| | | * @return {@link RedisTemplate} |
| | | */ |
| | | public RedisTemplate getRedisTemplate(Integer dbIndex) { |
| | | RedisTemplate redisTemplate = redisTemplateMap.get("redisTemplate" + dbIndex); |
| | | if (redisTemplate == null) { |
| | | throw new RuntimeException("Map不存在该redisTemplate"); |
| | | } |
| | | return redisTemplate; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.redisson.register; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonAutoDetect; |
| | | import com.fasterxml.jackson.annotation.PropertyAccessor; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; |
| | | import com.hx.redisson.entity.RedissondbConfigEntity; |
| | | import com.hx.redisson.manager.RedisManager; |
| | | import org.apache.commons.collections.CollectionUtils; |
| | | import org.redisson.Redisson; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.redisson.client.codec.StringCodec; |
| | | import org.redisson.config.Config; |
| | | import org.redisson.config.SingleServerConfig; |
| | | import org.redisson.spring.data.connection.RedissonConnectionFactory; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.config.AutowireCapableBeanFactory; |
| | | import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
| | | import org.springframework.beans.factory.support.GenericBeanDefinition; |
| | | import org.springframework.boot.context.properties.bind.Binder; |
| | | import org.springframework.context.EnvironmentAware; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; |
| | | import org.springframework.core.env.Environment; |
| | | import org.springframework.core.type.AnnotationMetadata; |
| | | import org.springframework.data.redis.connection.RedisConnectionFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; |
| | | import org.springframework.data.redis.serializer.RedisSerializer; |
| | | import org.springframework.data.redis.serializer.StringRedisSerializer; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <h1>redistemplate初始化</h1> |
| | | * <p> |
| | | * 作用: |
| | | * <p> |
| | | * 读取系统配置,系统启动时,读取redis 的配置,初始化所有的redistemplate |
| | | * 并动态注册为bean |
| | | * |
| | | * @author gengzi |
| | | * @date 2021年1月5日22:16:29 |
| | | */ |
| | | @Configuration |
| | | public class RedisRegister implements EnvironmentAware, ImportBeanDefinitionRegistrar { |
| | | |
| | | private Logger logger = LoggerFactory.getLogger(RedisRegister.class); |
| | | |
| | | /**用于获取环境配置*/ |
| | | private Environment environment; |
| | | /**用于绑定对象*/ |
| | | private Binder binder; |
| | | |
| | | /** |
| | | * 设置环境 |
| | | * |
| | | * @param environment |
| | | */ |
| | | @Override |
| | | public void setEnvironment(Environment environment) { |
| | | this.environment = environment; |
| | | this.binder = Binder.get(environment); |
| | | } |
| | | |
| | | /** |
| | | * 注册bean |
| | | * |
| | | * @param importingClassMetadata |
| | | * @param registry |
| | | */ |
| | | @Override |
| | | public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { |
| | | logger.info("《《《动态注册bean开始》》》"); |
| | | RedissondbConfigEntity redissondb; |
| | | try { |
| | | redissondb = binder.bind("redissondb", RedissondbConfigEntity.class).get(); |
| | | } catch (Exception e) { |
| | | logger.error("读取redissondb环境配置失败", e); |
| | | return; |
| | | } |
| | | List<Integer> databases = redissondb.getDatabases(); |
| | | if (CollectionUtils.isNotEmpty(databases)) { |
| | | databases.forEach(db -> { |
| | | // 单机模式,集群只能使用db0 |
| | | Config config = new Config(); |
| | | config.setCodec(StringCodec.INSTANCE); |
| | | SingleServerConfig singleConfig = config.useSingleServer(); |
| | | singleConfig.setAddress("redis://"+redissondb.getHost()+":"+redissondb.getPort()); |
| | | singleConfig.setPassword(redissondb.getPassword()); |
| | | singleConfig.setDatabase(db); |
| | | |
| | | System.out.println("getHost:"+singleConfig.getAddress()); |
| | | System.out.println("getHost:"+singleConfig.getPassword()); |
| | | RedissonClient redissonClient = Redisson.create(config); |
| | | |
| | | // 构造RedissonConnectionFactory |
| | | RedissonConnectionFactory redisConnectionFactory = new RedissonConnectionFactory(redissonClient); |
| | | // bean定义 |
| | | GenericBeanDefinition redisTemplate = new GenericBeanDefinition(); |
| | | // 设置bean 的类型 |
| | | redisTemplate.setBeanClass(RedisTemplate.class); |
| | | // 设置自动注入的形式,根据名称 |
| | | redisTemplate.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME); |
| | | // redisTemplate 的属性配置 |
| | | redisTemplate(redisTemplate, redisConnectionFactory); |
| | | // 注册Bean |
| | | registry.registerBeanDefinition("redisTemplate" + db, redisTemplate); |
| | | |
| | | RedisManager.redissonTemplateMap.put(db+"",redissonClient); |
| | | }); |
| | | } |
| | | logger.info("《《《动态注册bean结束》》》"); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * redisTemplate 的属性配置 |
| | | * |
| | | * @param redisTemplate 泛型bean |
| | | * @param redisConnectionFactory 连接工厂 |
| | | * @return |
| | | */ |
| | | public GenericBeanDefinition redisTemplate(GenericBeanDefinition redisTemplate, RedisConnectionFactory redisConnectionFactory) { |
| | | RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer(); |
| | | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); |
| | | // 解决查询缓存转换异常的问题 |
| | | ObjectMapper om = new ObjectMapper(); |
| | | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); |
| | | om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, |
| | | ObjectMapper.DefaultTyping.NON_FINAL); |
| | | jackson2JsonRedisSerializer.setObjectMapper(om); |
| | | // key采用String的序列化方式,value采用json序列化方式 |
| | | // 通过方法设置属性值 |
| | | redisTemplate.getPropertyValues().add("connectionFactory", redisConnectionFactory); |
| | | redisTemplate.getPropertyValues().add("keySerializer", stringRedisSerializer); |
| | | redisTemplate.getPropertyValues().add("hashKeySerializer", stringRedisSerializer); |
| | | redisTemplate.getPropertyValues().add("valueSerializer", jackson2JsonRedisSerializer); |
| | | redisTemplate.getPropertyValues().add("hashValueSerializer", jackson2JsonRedisSerializer); |
| | | |
| | | return redisTemplate; |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | # Compiled class file |
| | | *.class |
| | | |
| | | # Log file |
| | | *.log |
| | | |
| | | # BlueJ files |
| | | *.ctxt |
| | | |
| | | # Mobile Tools for Java (J2ME) |
| | | .mtj.tmp/ |
| | | |
| | | # Package Files # |
| | | *.jar |
| | | *.war |
| | | *.nar |
| | | *.ear |
| | | *.zip |
| | | *.tar.gz |
| | | *.rar |
| | | *.iml |
| | | |
| | | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
| | | hs_err_pid* |
| | | /target/ |
| | | /.idea |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <groupId>com.hx.gitee</groupId> |
| | | <artifactId>hx-auto</artifactId> |
| | | <version>stander</version> |
| | | |
| | | <properties> |
| | | <!--模板--> |
| | | <freemarker.version>2.3.28</freemarker.version> |
| | | <!--mybatis自动生成--> |
| | | <mybatis.actable>1.1.1.RELEASE</mybatis.actable> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | |
| | | <dependency> |
| | | <groupId>org.freemarker</groupId> |
| | | <artifactId>freemarker</artifactId> |
| | | <version>${freemarker.version}</version> |
| | | </dependency> |
| | | <!-- 数据库自动生成表 --> |
| | | <dependency> |
| | | <groupId>com.gitee.sunchenbin.mybatis.actable</groupId> |
| | | <artifactId>mybatis-enhance-actable</artifactId> |
| | | <version>${mybatis.actable}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-context</artifactId> |
| | | <version>5.2.5.RELEASE</version> |
| | | <scope>compile</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.slf4j</groupId> |
| | | <artifactId>slf4j-api</artifactId> |
| | | <version>1.7.30</version> |
| | | <scope>compile</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-beans</artifactId> |
| | | <version>5.2.5.RELEASE</version> |
| | | <scope>compile</scope> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | |
| | | <build> |
| | | <resources> |
| | | <resource> |
| | | <directory>src/main/java</directory> |
| | | <includes> |
| | | <include>**/*.properties</include> |
| | | <include>**/*.xml</include> |
| | | <include>**/*.tld</include> |
| | | <include>**/*.tpl</include> |
| | | </includes> |
| | | <filtering>false</filtering> |
| | | </resource> |
| | | <resource> |
| | | <directory>src/main/resources</directory> |
| | | <includes> |
| | | <include>**/*.properties</include> |
| | | <include>**/*.xml</include> |
| | | <include>**/*.tld</include> |
| | | <include>**/*.tpl</include> |
| | | </includes> |
| | | </resource> |
| | | <resource> |
| | | <directory>${runtime.env}</directory> |
| | | </resource> |
| | | </resources> |
| | | <plugins> |
| | | <plugin> |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-compiler-plugin</artifactId> |
| | | <configuration> |
| | | <source>6</source> |
| | | <target>6</target> |
| | | </configuration> |
| | | </plugin> |
| | | </plugins> |
| | | </build> |
| | | |
| | | </project> |
New file |
| | |
| | | package com.hx.auto; |
| | | |
| | | import com.hx.auto.common.UrlData; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 自动生成工具 |
| | | * 2019-08-29 |
| | | * @author cjh |
| | | * |
| | | */ |
| | | public class AutoDomeUtil { |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | System.out.println("开始"); |
| | | UrlData urlData = new UrlData(); |
| | | urlData.setTotalUrl("com.hx"); |
| | | urlData.actionUrlData("hx-web.src.main.java","com.hx.controller.admin"); |
| | | urlData.daoUrlData("hx-web.src.main.java","com.hx.dao.mapper"); |
| | | urlData.serviceUrlData("hx-web.src.main.java","com.hx.service"); |
| | | urlData.serviceImplUrlData("hx-web.src.main.java","com.hx.service.impl"); |
| | | urlData.mapperUrlData("hx-web.src.main.java", "com.hx.dao.mapperXml"); |
| | | |
| | | /* |
| | | //dao |
| | | GeneratorUtil.generatorDao(SysAdmin.class,urlData); |
| | | //mapper |
| | | GeneratorUtil.generatorMapper(SysAdmin.class, urlData); |
| | | //action |
| | | GeneratorUtil.generatorAction(SysAdmin.class,urlData); |
| | | // 生成service |
| | | GeneratorUtil.generatorService(SysAdmin.class,urlData); |
| | | |
| | | //通过实体类的包获取所有的表,直接全部生成 |
| | | //GeneratorUtil.generatorTableByPackUrl("com.hx.model", urlData); |
| | | */ |
| | | //generatorTableByPackUrl(packPath, urlData); |
| | | |
| | | /*Class cl = TestM2.class; |
| | | Field[] fields = cl.getDeclaredFields(); |
| | | for(Field field:fields) { |
| | | System.out.println("field.getName():"+field.getName()); |
| | | System.out.println("field.getType():"+field.getType()); |
| | | System.out.println("field.getGenericType():"+field.getGenericType()); |
| | | System.out.println("field.getModifiers():"+field.getModifiers()); |
| | | }*/ |
| | | |
| | | //StringBuffer stringBuffer = SimpleToolUtil.getFileContent("com/cjh/auto/file/test.txt"); |
| | | //System.out.println("stringBuffer:"+stringBuffer); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.auto; |
| | | |
| | | import java.io.BufferedWriter; |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.OutputStreamWriter; |
| | | import java.io.Writer; |
| | | import java.util.HashMap; |
| | | |
| | | import com.hx.auto.common.UrlData; |
| | | import com.hx.auto.util.CommonTool; |
| | | import freemarker.template.Configuration; |
| | | import freemarker.template.DefaultObjectWrapper; |
| | | import freemarker.template.Template; |
| | | |
| | | /** |
| | | * 自动生成action |
| | | * |
| | | * @author chenjiahe 2019年09月08日16:57:47 |
| | | * |
| | | */ |
| | | public class GeneratorActionUtil { |
| | | |
| | | private static String templateDir = "/ftl";//获取模板路径 |
| | | private static String templateName = "Action.tpl";//action模板名称 |
| | | |
| | | /**生成action |
| | | * @param cl 实体类 |
| | | * @param urlData 生成配置信息 |
| | | * @param sqlParam 是否生成动态sql的文件(sqlSentence.java),已经生成就不用生成 |
| | | * @throws Exception |
| | | */ |
| | | public static void generatorAction(Class<?> cl, UrlData urlData, boolean sqlParam) throws Exception { |
| | | try { |
| | | |
| | | // 反射start |
| | | // 类名 |
| | | String entityName = cl.getSimpleName(); |
| | | // 类名首字母小写 |
| | | String initial = entityName.substring(0, 1).toLowerCase(); |
| | | String entityNameSmall = initial + entityName.substring(1, entityName.length()); |
| | | |
| | | //判断是否存在 |
| | | //生成文件路径 |
| | | String targetFile = urlData.getActionUrl()[1].replace(".", "/")+"/"; |
| | | //生成文件名称 |
| | | targetFile += entityName + "Controller.java"; |
| | | targetFile = "./"+urlData.getActionUrl()[0].replace(".", "/")+"/"+targetFile; |
| | | File file = new File(targetFile); |
| | | if(file.exists()){ |
| | | //存在就结束 |
| | | return; |
| | | } |
| | | |
| | | //获取实体类包名 |
| | | String[] strs = cl.getName().split("\\."); |
| | | String packageName = ""; |
| | | //去掉类名 |
| | | for(int i=0;i<strs.length-1;i++) { |
| | | packageName += "."+strs[i]; |
| | | } |
| | | packageName = packageName.replaceFirst(".", ""); |
| | | |
| | | //获取模板 |
| | | Configuration configuration = new Configuration(Configuration.getVersion()); |
| | | configuration.setClassForTemplateLoading(GeneratorActionUtil.class, templateDir); |
| | | //configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "填你的resource下的路径,比如/ftl")); |
| | | Template template = configuration.getTemplate(templateName); |
| | | |
| | | // 创建数据模型 |
| | | HashMap<String, Object> root = new HashMap<String, Object>(); |
| | | |
| | | //action包名 |
| | | if(!CommonTool.checkNotNull(urlData.getActionUrl())) { |
| | | System.err.println("没有生成action路径"); |
| | | return; |
| | | } |
| | | root.put("packageName",urlData.getActionUrl()[1]); |
| | | //实体类的类名 |
| | | root.put("entityName", entityName); |
| | | //实体类的类名(首字母小写) |
| | | root.put("entityNameSmall", entityNameSmall); |
| | | |
| | | if(!CommonTool.checkNotNull(urlData.getTotalUrl())) { |
| | | System.err.println("没有设置总包路径"); |
| | | return; |
| | | } |
| | | //dao的包名 |
| | | if(!CommonTool.checkNotNull(urlData.getDaoUrl())) { |
| | | System.err.println("没有dao路径"); |
| | | return; |
| | | } |
| | | root.put("TotalPackageName",urlData.getTotalUrl()); |
| | | root.put("DAOPackageName",urlData.getDaoUrl()[1]); |
| | | //实体类的包名 |
| | | root.put("entityPackageName",packageName); |
| | | //service的包名 |
| | | if(!CommonTool.checkNotNull(urlData.getServiceUrl())) { |
| | | System.err.println("没有service路径"); |
| | | return; |
| | | } |
| | | root.put("servicePackageName",urlData.getServiceUrl()[1]); |
| | | |
| | | // 将模板和数据模型合并 输出到Console |
| | | Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8")); |
| | | template.process(root, out); |
| | | out.flush(); |
| | | out.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto; |
| | | |
| | | import java.io.BufferedWriter; |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.OutputStreamWriter; |
| | | import java.io.Writer; |
| | | import java.util.HashMap; |
| | | |
| | | import com.hx.auto.common.UrlData; |
| | | import com.hx.auto.util.CommonTool; |
| | | |
| | | import freemarker.template.Configuration; |
| | | import freemarker.template.DefaultObjectWrapper; |
| | | import freemarker.template.Template; |
| | | |
| | | /** |
| | | * 自动生成DAO |
| | | * @author chenjiahe 2019年09月08日16:57:47 |
| | | * |
| | | */ |
| | | public class GeneratorDaoUtil { |
| | | |
| | | private static String templateDir = "/ftl";//获取模板路径 |
| | | private static String templateName = "Dao.tpl";//action模板名称 |
| | | |
| | | /**生成Dao |
| | | * @param cl 实体类 |
| | | * @param urlData 生成配置信息 |
| | | * @throws Exception |
| | | */ |
| | | public static void generatorDao(Class<?> cl,UrlData urlData) throws Exception { |
| | | try { |
| | | // 反射start |
| | | // 类名 |
| | | String entityName = cl.getSimpleName(); |
| | | // 类名首字母小写 |
| | | String initial = entityName.substring(0, 1).toLowerCase(); |
| | | String entityNameSmall = initial + entityName.substring(1, entityName.length()); |
| | | |
| | | //生成文件路径 |
| | | String targetFile = urlData.getDaoUrl()[1].replace(".", "/")+"/"; |
| | | //生成文件名称 |
| | | targetFile += entityName + "Mapper.java"; |
| | | //映射文件的文件夹 |
| | | //补全路径 |
| | | targetFile = "./"+urlData.getDaoUrl()[0].replace(".", "/")+"/"+targetFile; |
| | | File file = new File(targetFile); |
| | | if(file.exists()){ |
| | | //System.out.println("存在333...:"); |
| | | //存在就结束 |
| | | return; |
| | | } |
| | | |
| | | //获取实体类包名 |
| | | String[] strs = cl.getName().split("\\."); |
| | | String packageName = ""; |
| | | //去掉类名 |
| | | for(int i=0;i<strs.length-1;i++) { |
| | | packageName += "."+strs[i]; |
| | | } |
| | | packageName = packageName.replaceFirst(".", ""); |
| | | |
| | | //获取模板 |
| | | Configuration configuration = new Configuration(Configuration.getVersion()); |
| | | configuration.setClassForTemplateLoading(GeneratorDaoUtil.class, templateDir); |
| | | //configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "填你的resource下的路径,比如/ftl")); |
| | | Template template = configuration.getTemplate(templateName); |
| | | |
| | | // 创建数据模型 |
| | | HashMap<String, Object> root = new HashMap<String, Object>(); |
| | | |
| | | //action包名 |
| | | if(!CommonTool.checkNotNull(urlData.getActionUrl())) { |
| | | System.err.println("没有生成action路径"); |
| | | return; |
| | | } |
| | | root.put("packageName",urlData.getActionUrl()[1]); |
| | | //实体类的类名 |
| | | root.put("entityName", entityName); |
| | | //实体类的类名(首字母小写) |
| | | root.put("entityNameSmall", entityNameSmall); |
| | | |
| | | //dao的包名 |
| | | if(!CommonTool.checkNotNull(urlData.getDaoUrl())) { |
| | | System.err.println("没有dao路径"); |
| | | return; |
| | | } |
| | | |
| | | if(!CommonTool.checkNotNull(urlData.getTotalUrl())) { |
| | | System.err.println("没有设置总包路径"); |
| | | return; |
| | | } |
| | | root.put("TotalPackageName",urlData.getTotalUrl()); |
| | | root.put("DAOPackageName",urlData.getDaoUrl()[1]); |
| | | //实体类的包名 |
| | | root.put("entityPackageName",packageName); |
| | | |
| | | System.out.println("actionUrl:"+targetFile); |
| | | // 将模板和数据模型合并 输出到Console |
| | | Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8")); |
| | | template.process(root, out); |
| | | out.flush(); |
| | | out.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto; |
| | | |
| | | import java.io.BufferedWriter; |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.OutputStreamWriter; |
| | | import java.io.Writer; |
| | | import java.lang.reflect.Field; |
| | | import java.util.HashMap; |
| | | import java.util.zip.ZipOutputStream; |
| | | |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Column; |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Table; |
| | | import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant; |
| | | import com.hx.auto.common.JdbcType; |
| | | import com.hx.auto.common.ReadEntityData; |
| | | import com.hx.auto.common.UrlData; |
| | | import com.hx.auto.util.CommonTool; |
| | | |
| | | import com.hx.auto.util.GeneratorClassParentUtil; |
| | | import freemarker.template.Configuration; |
| | | import freemarker.template.DefaultObjectWrapper; |
| | | import freemarker.template.Template; |
| | | |
| | | /** |
| | | * 自动生成mapper.xml |
| | | * |
| | | * @author chenjiahe 2019年09月08日23:57:47 |
| | | * |
| | | */ |
| | | public class GeneratorMapperUtil { |
| | | |
| | | private static String templateDir = "/ftl";//获取模板路径 |
| | | private static String templateName = "Mapper.tpl";//action模板名称 |
| | | |
| | | /**生成mapper.xml |
| | | * @param cl 实体类 |
| | | * @param urlData 生成配置信息 |
| | | * @throws Exception |
| | | */ |
| | | public static void generatorMapper(Class<?> cl,UrlData urlData) throws Exception { |
| | | try { |
| | | // 反射start |
| | | // 类名 |
| | | String entityName = cl.getSimpleName(); |
| | | // 类名首字母小写 |
| | | String initial = entityName.substring(0, 1).toLowerCase(); |
| | | String entityNameSmall = initial + entityName.substring(1, entityName.length()); |
| | | |
| | | //获取实体类包名 |
| | | String[] strs = cl.getName().split("\\."); |
| | | String packageName = ""; |
| | | //去掉类名 |
| | | for(int i=0;i<strs.length-1;i++) { |
| | | packageName += "."+strs[i]; |
| | | } |
| | | packageName = packageName.replaceFirst(".", ""); |
| | | |
| | | //获取模板 |
| | | Configuration configuration = new Configuration(Configuration.getVersion()); |
| | | configuration.setClassForTemplateLoading(GeneratorMapperUtil.class, templateDir); |
| | | //configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "填你的resource下的路径,比如/ftl")); |
| | | Template template = configuration.getTemplate(templateName); |
| | | |
| | | //实体类所有的字段 |
| | | //用来存储数据 |
| | | ReadEntityData readEntityData = new ReadEntityData(); |
| | | //表名称 |
| | | Table table = cl.getAnnotation(Table.class); |
| | | readEntityData.setTableName(table.name()); |
| | | // 取得本类的全部属性 |
| | | Field[] fields = cl.getDeclaredFields(); |
| | | fields = GeneratorClassParentUtil.getPatentFields(fields,cl); |
| | | for (Field field:fields) { |
| | | // 判断方法中是否有指定注解类型的注解 |
| | | boolean hasAnnotation = field.isAnnotationPresent(Column.class); |
| | | if (hasAnnotation) { |
| | | // 根据注解类型返回方法的指定类型注解 |
| | | Column column = field.getAnnotation(Column.class); |
| | | |
| | | //判断是不是 |
| | | boolean isBol = false; |
| | | Integer isBlob = 0; |
| | | if(column.type().equals(MySqlTypeConstant.TEXT)||column.type().equals(MySqlTypeConstant.LONGTEXT) |
| | | ||column.type().equals(MySqlTypeConstant.LONGBLOB)){ |
| | | isBol = true; |
| | | isBlob = 1; |
| | | } |
| | | |
| | | //类型 |
| | | //String type = column.type().toUpperCase(); |
| | | String type = JdbcType.jdbcTypeData(field.getType().getTypeName().toUpperCase(),isBol); |
| | | //主键 |
| | | if (column.isKey()) { |
| | | readEntityData.setEntityIdName(field.getName()); |
| | | readEntityData.setEntityIdData("#{"+field.getName()+"}"); |
| | | if(!CommonTool.checkNotNull(column.name())) { |
| | | readEntityData.setTableIdName(field.getName()); |
| | | }else { |
| | | readEntityData.setTableIdName(column.name()); |
| | | } |
| | | readEntityData.setKeyType(type); |
| | | continue; |
| | | } |
| | | //存储数据 |
| | | if(!CommonTool.checkNotNull(column.name())) { |
| | | readEntityData.fielData(field.getName(),field.getName(),type,isBlob,"#{"+field.getName()+"}"); |
| | | }else { |
| | | readEntityData.fielData(field.getName(),column.name(),type,isBlob,"#{"+field.getName()+"}"); |
| | | } |
| | | } |
| | | } |
| | | // 创建数据模型 |
| | | HashMap<String, Object> root = new HashMap<String, Object>(); |
| | | |
| | | //action包名 |
| | | if(!CommonTool.checkNotNull(urlData.getActionUrl())) { |
| | | System.err.println("没有生成action路径"); |
| | | return; |
| | | } |
| | | if(!CommonTool.checkNotNull(urlData.getTotalUrl())) { |
| | | System.err.println("没有设置总包路径"); |
| | | return; |
| | | } |
| | | root.put("TotalPackageName",urlData.getTotalUrl()); |
| | | root.put("packageActionName",urlData.getActionUrl()[1]); |
| | | root.put("packageEntityName",packageName); |
| | | //实体类的类名 |
| | | root.put("entityName", entityName); |
| | | //实体类的类名(首字母小写) |
| | | root.put("entityNameSmall", entityNameSmall); |
| | | //表字段 数据 |
| | | root.put("fieldData",readEntityData); |
| | | |
| | | root.put("sqlSentence","${sqlSentence}"); |
| | | //root.put("sqlSentence","${sqlSentence}"); |
| | | //root.put("sqlSentence","${sqlSentence}"); |
| | | |
| | | //dao的包名 |
| | | if(!CommonTool.checkNotNull(urlData.getDaoUrl())) { |
| | | System.err.println("没有dao路径"); |
| | | return; |
| | | } |
| | | root.put("DAOPackageName",urlData.getDaoUrl()[1]); |
| | | //实体类的包名 |
| | | root.put("entityPackageName",packageName); |
| | | |
| | | //生成文件路径 |
| | | String targetFile = urlData.getMapperUrl()[1].replace(".", "/")+"/"; |
| | | //生成文件名称 |
| | | targetFile += entityName + "Mapper.xml"; |
| | | //补全路径 |
| | | targetFile = "./"+urlData.getMapperUrl()[0].replace(".", "/")+"/"+targetFile; |
| | | //获取是否已经生成过文件,拿取自定义的内容 |
| | | String xmlStr = GeneratorReadXmlUtil.readMapperXml(targetFile); |
| | | if(!"false".equals(xmlStr)){ |
| | | root.put("customData",GeneratorReadXmlUtil.readMapperXml(targetFile)); |
| | | }else{ |
| | | root.put("customData",""); |
| | | } |
| | | |
| | | System.out.println("mapperUrl:"+targetFile); |
| | | // 将模板和数据模型合并 输出到Console |
| | | Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8")); |
| | | template.process(root, out); |
| | | |
| | | |
| | | |
| | | out.flush(); |
| | | out.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto; |
| | | |
| | | import java.io.BufferedWriter; |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.OutputStreamWriter; |
| | | import java.io.Writer; |
| | | import java.util.HashMap; |
| | | |
| | | import com.hx.auto.common.UrlData; |
| | | import com.hx.auto.util.CommonTool; |
| | | import freemarker.template.Configuration; |
| | | import freemarker.template.DefaultObjectWrapper; |
| | | import freemarker.template.Template; |
| | | import freemarker.template.TemplateException; |
| | | |
| | | /** |
| | | * 自动生成Service and ServiceImpl |
| | | * |
| | | * @author chenjiahe 2019年09月08日16:57:47 |
| | | * |
| | | */ |
| | | public class GeneratorServiceUtil { |
| | | |
| | | private static String templateDir = "/ftl";//获取模板路径 |
| | | |
| | | private static String templateServiceName = "Service.tpl";//service名称 |
| | | private static String templateServiceImplName = "ServiceImpl.tpl";//serviceImpl名称 |
| | | /** |
| | | * @param cl 实体类 |
| | | * @param urlData 配置信息 |
| | | * @throws Exception |
| | | */ |
| | | @SuppressWarnings("deprecation") |
| | | public static void generatorService(Class<?> cl, UrlData urlData) throws Exception { |
| | | try { |
| | | //获取类的包名 |
| | | String className = cl.getSimpleName(); |
| | | String[] strs = cl.getName().split("\\."); |
| | | String packageName = ""; |
| | | for(int i=0;i<strs.length-1;i++) { |
| | | packageName += "."+strs[i]; |
| | | } |
| | | packageName = packageName.replaceFirst(".",""); |
| | | |
| | | // 类名首字母小写 |
| | | String initial = className.substring(0, 1).toLowerCase(); |
| | | String classNamex = initial + className.substring(1, className.length()); |
| | | // 取得本类的全部属性 |
| | | |
| | | String targetFile = urlData.getServiceUrl()[1].replace(".", "/")+"/"; |
| | | targetFile += className + "Service.java"; |
| | | //补全路径 |
| | | targetFile = "./"+urlData.getServiceUrl()[0].replace(".", "/")+"/"+targetFile; |
| | | File fileService = new File(targetFile); |
| | | if(fileService.exists()){ |
| | | //存在就结束 |
| | | return; |
| | | } |
| | | |
| | | |
| | | String targetFile2 = urlData.getServiceImplUrl()[1].replace(".", "/")+"/"; |
| | | targetFile2 += className + "ServiceImpl.java"; |
| | | //补全路径 |
| | | targetFile2 = "./"+urlData.getServiceImplUrl()[0].replace(".", "/")+"/"+targetFile2; |
| | | File fileServiceImple = new File(targetFile2); |
| | | if(fileServiceImple.exists()){ |
| | | System.out.println("fileServiceImple:"+targetFile2); |
| | | //存在就结束 |
| | | return; |
| | | } |
| | | |
| | | //获取模板 |
| | | Configuration configuration = new Configuration(Configuration.getVersion()); |
| | | configuration.setClassForTemplateLoading(GeneratorServiceUtil.class, templateDir); |
| | | //configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "填你的resource下的路径,比如/ftl")); |
| | | |
| | | // 获取或创建模板 |
| | | Template template = configuration.getTemplate(templateServiceName); |
| | | |
| | | // 创建数据模型 |
| | | HashMap<String, Object> root = new HashMap<String, Object>(); |
| | | root.put("className", classNamex); |
| | | root.put("classNameUP", className); |
| | | root.put("packageName", packageName); |
| | | root.put("servicePack", urlData.getServiceUrl()[1]); |
| | | root.put("actionPack", urlData.getActionUrl()[1]); |
| | | |
| | | |
| | | System.out.println("serviceUrl:"+targetFile); |
| | | // 将模板和数据模型合并 输出到Console |
| | | Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8")); |
| | | template.process(root, out); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | if(!CommonTool.checkNotNull(urlData.getTotalUrl())) { |
| | | System.err.println("没有设置总包路径"); |
| | | return; |
| | | } |
| | | root.put("TotalPackageName",urlData.getTotalUrl()); |
| | | root.put("serviceImpPack", urlData.getServiceImplUrl()[1]); |
| | | root.put("daoPack", urlData.getDaoUrl()[1]); |
| | | //serviceImp文件 |
| | | // 获取或创建模板 |
| | | Template template2 = configuration.getTemplate(templateServiceImplName); |
| | | |
| | | System.out.println("serviceImpUrl:"+targetFile2); |
| | | // 将模板和数据模型合并 输出到Console |
| | | Writer out2 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile2), "UTF-8")); |
| | | template2.process(root, out2); |
| | | out2.flush(); |
| | | out2.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } catch (TemplateException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileFilter; |
| | | import java.io.IOException; |
| | | import java.net.URL; |
| | | import java.net.URLDecoder; |
| | | import java.util.Enumeration; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.Set; |
| | | |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Table; |
| | | import com.hx.auto.common.UrlData; |
| | | |
| | | /** |
| | | * 自动生成工具 |
| | | * 2019-08-29 |
| | | * @author hx |
| | | * |
| | | */ |
| | | public class GeneratorUtil { |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | System.out.println("开始"); |
| | | UrlData urlData = new UrlData(); |
| | | urlData.setTotalUrl("com.hx"); |
| | | urlData.actionUrlData("src.main.java","com.hx.controller.admin"); |
| | | urlData.daoUrlData("src.main.java","com.hx.dao.mapper"); |
| | | urlData.serviceUrlData("src.main.java","com.hx.service"); |
| | | urlData.serviceImplUrlData("src.main.java","com.hx.service.impl"); |
| | | urlData.mapperUrlData("src.main.java", "com.hx.dao.mapperXml"); |
| | | |
| | | /*//dao |
| | | generatorDao(SysAdmin.class,urlData); |
| | | //mapper |
| | | generatorMapper(SysAdmin.class, urlData); |
| | | //action |
| | | generatorAction(SysAdmin.class,urlData); |
| | | // 生成service |
| | | generatorService(SysAdmin.class,urlData);*/ |
| | | |
| | | //generatorTableByPackUrl(packPath, urlData); |
| | | |
| | | /*Class cl = TestM2.class; |
| | | Field[] fields = cl.getDeclaredFields(); |
| | | for(Field field:fields) { |
| | | System.out.println("field.getName():"+field.getName()); |
| | | System.out.println("field.getType():"+field.getType()); |
| | | System.out.println("field.getGenericType():"+field.getGenericType()); |
| | | System.out.println("field.getModifiers():"+field.getModifiers()); |
| | | }*/ |
| | | |
| | | //StringBuffer stringBuffer = SimpleToolUtil.getFileContent("com/hx/auto/file/test.txt"); |
| | | //System.out.println("stringBuffer:"+stringBuffer); |
| | | } |
| | | |
| | | /**通过包路径获取xml和mapper |
| | | * |
| | | * @param packPath 包路径 |
| | | * @param urlData 生成文件的配置 |
| | | */ |
| | | public static <T> void generatorXmlAndMapper(String packPath,UrlData urlData) { |
| | | try { |
| | | Set<Class<?>> classes = classData(packPath); |
| | | for(Class<?> cl:classes) { |
| | | //action |
| | | //generatorAction(cl,urlData); |
| | | //dao |
| | | generatorDao(cl,urlData); |
| | | //mapper.xml |
| | | generatorMapper(cl, urlData); |
| | | // 生成service |
| | | //generatorService(cl,urlData); |
| | | } |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /**通过包路径获取所有文件 |
| | | * |
| | | * @param packPath 包路径 |
| | | * @param urlData 生成文件的配置 |
| | | */ |
| | | public static <T> void generatorTableByPackUrl(String packPath,UrlData urlData) { |
| | | try { |
| | | Set<Class<?>> classes = classData(packPath); |
| | | for(Class<?> cl:classes) { |
| | | //action |
| | | generatorAction(cl,urlData); |
| | | //dao |
| | | generatorDao(cl,urlData); |
| | | //mapper.xml |
| | | generatorMapper(cl, urlData); |
| | | // 生成service |
| | | generatorService(cl,urlData); |
| | | } |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /**自动生成dao文件 |
| | | * |
| | | * @param cl 指定生成类 |
| | | * @param urlData 生成文件的配置文件 |
| | | */ |
| | | public static <T> void generatorDao(Class<?> cl,UrlData urlData) { |
| | | try { |
| | | //判断是否有标志,没有标志就跳过 |
| | | if (null != cl.getAnnotation(Table.class)) { |
| | | // 生成action |
| | | GeneratorDaoUtil.generatorDao(cl,urlData); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /**自动生成mapper.xml文件 |
| | | * |
| | | * @param cl 指定生成类 |
| | | * @param urlData 生成文件的配置文件 |
| | | */ |
| | | public static <T> void generatorMapper(Class<?> cl,UrlData urlData) { |
| | | try { |
| | | //判断是否有标志,没有标志就跳过 |
| | | if (null != cl.getAnnotation(Table.class)) { |
| | | // 生成action |
| | | GeneratorMapperUtil.generatorMapper(cl, urlData); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /**自动生成action文件 |
| | | * |
| | | * @param cl 指定生成类 |
| | | * @param urlData 生成文件的配置文件 |
| | | */ |
| | | public static <T> void generatorAction(Class<?> cl,UrlData urlData) { |
| | | try { |
| | | //生成动态sql的文件(sqlSentence.java),已经生成就不用生成,否则会覆盖 |
| | | /*if(sqlParam) { |
| | | GeneratorsqlSentenceUtil.GeneratorsqlSentence(urlData); |
| | | }*/ |
| | | //判断是否有标志,没有标志就跳过 |
| | | if (null != cl.getAnnotation(Table.class)) { |
| | | // 生成action |
| | | GeneratorActionUtil.generatorAction(cl, urlData, false); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | /**自动生成Service and ServiceImpl文件 |
| | | * |
| | | * @param cl 指定生成类 |
| | | * @param urlData 生成文件的配置文件 |
| | | */ |
| | | public static <T> void generatorService(Class<?> cl,UrlData urlData) { |
| | | try { |
| | | //判断是否有标志,没有标志就跳过 |
| | | if (null != cl.getAnnotation(Table.class)) { |
| | | // 生成action |
| | | GeneratorServiceUtil.generatorService(cl,urlData); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /**获取包下面的所有文件*/ |
| | | public static Set<Class<?>> classData(String packPath){ |
| | | Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); |
| | | // 是否循环迭代 |
| | | boolean recursive = true; |
| | | // 获取包的名字 并进行替换 |
| | | String packageName = packPath; |
| | | String packageDirName = packageName.replace('.', '/'); |
| | | // 定义一个枚举的集合 并进行循环来处理这个目录下的things |
| | | Enumeration<URL> dirs; |
| | | try{ |
| | | dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName); |
| | | // 循环迭代下去 |
| | | while (dirs.hasMoreElements()){ |
| | | // 获取下一个元素 |
| | | URL url = dirs.nextElement(); |
| | | // 得到协议的名称 |
| | | String protocol = url.getProtocol(); |
| | | // 如果是以文件的形式保存在服务器上 |
| | | if ("file".equals(protocol)) { |
| | | System.err.println("file类型的扫描:" + packPath); |
| | | // 获取包的物理路径 |
| | | String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); |
| | | // 以文件的方式扫描整个包下的文件 并添加到集合中 |
| | | findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes); |
| | | } |
| | | } |
| | | }catch (IOException e){ |
| | | e.printStackTrace(); |
| | | } |
| | | return classes; |
| | | } |
| | | |
| | | /** |
| | | * 以文件的形式来获取包下的所有Class |
| | | * |
| | | * @param packageName |
| | | * @param packagePath |
| | | * @param recursive |
| | | * @param classes |
| | | */ |
| | | public static void findAndAddClassesInPackageByFile( |
| | | String packageName, |
| | | String packagePath, |
| | | final boolean recursive, |
| | | Set<Class<?>> classes){ |
| | | // 获取此包的目录 建立一个File |
| | | File dir = new File(packagePath); |
| | | // 如果不存在或者 也不是目录就直接返回 |
| | | if (!dir.exists() || !dir.isDirectory()) { |
| | | // log.warn("用户定义包名 " + packageName + " 下没有任何文件"); |
| | | return; |
| | | } |
| | | // 如果存在 就获取包下的所有文件 包括目录 |
| | | File[] dirfiles = dir.listFiles(new FileFilter(){ |
| | | // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件) |
| | | public boolean accept(File file){ |
| | | return (recursive && file.isDirectory()) || (file.getName().endsWith(".class")); |
| | | } |
| | | }); |
| | | // 循环所有文件 |
| | | for (File file : dirfiles){ |
| | | // 如果是目录 则继续扫描 |
| | | if (file.isDirectory()) { |
| | | findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes); |
| | | }else{ |
| | | // 如果是java类文件 去掉后面的.class 只留下类名 |
| | | String className = file.getName().substring(0, file.getName().length() - 6); |
| | | try{ |
| | | // 添加到集合中去 |
| | | // classes.add(Class.forName(packageName + '.' + |
| | | // className)); |
| | | // 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净 |
| | | classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className)); |
| | | }catch (ClassNotFoundException e){ |
| | | // log.error("添加用户自定义视图类错误 找不到此类的.class文件"); |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto.common; |
| | | |
| | | /**javaType和jdbcType对比 |
| | | * |
| | | * @author chenjiahe |
| | | * |
| | | */ |
| | | public class JdbcType { |
| | | |
| | | /** |
| | | * @param type 字段类型 |
| | | * @param isBol 是否长字符串 |
| | | * @return |
| | | */ |
| | | public static String jdbcTypeData(String type,boolean isBol) { |
| | | //字母转化为小字母 |
| | | type = type.toLowerCase(); |
| | | if(type.equals("java.lang.string")) { |
| | | if(!isBol) { |
| | | type = "VARCHAR"; |
| | | }else { |
| | | type = "LONGVARCHAR"; |
| | | } |
| | | }else if(type.equals("int")) { |
| | | type = "INTEGER"; |
| | | }else if(type.equals("java.lang.integer")) { |
| | | type = "INTEGER"; |
| | | }else if(type.equals("boolean")) { |
| | | type = "BOOLEAN"; |
| | | }else if(type.equals("byte")) { |
| | | type = "TINYINT"; |
| | | }else if(type.equals("short")) { |
| | | type = "SMALLINT"; |
| | | }else if(type.equals("long")) { |
| | | type = "BIGINT"; |
| | | }else if(type.equals("float")) { |
| | | type = "REAL"; |
| | | }else if(type.equals("double")) { |
| | | type = "DOUBLE"; |
| | | }else if(type.equals("java.lang.double")) { |
| | | type = "DOUBLE"; |
| | | }else if(type.equals("java.util.date")) { |
| | | type = "TIMESTAMP"; |
| | | }else if(type.equals("java.sql.date")) { |
| | | type = "TIMESTAMP"; |
| | | }else if(type.equals("blob")) { |
| | | type = "BLOB"; |
| | | } |
| | | return type; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto.common; |
| | | |
| | | import java.lang.annotation.Documented; |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Inherited; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | |
| | | |
| | | /**长字符串 |
| | | * @author chenjiahe |
| | | * @version 2019年09月14日 下午6:13:37 |
| | | */ |
| | | //表示注解加在接口、类、枚举等 |
| | | @Target(ElementType.TYPE) |
| | | //VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息 |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | //将此注解包含在javadoc中 |
| | | @Documented |
| | | //允许子类继承父类中的注解 |
| | | @Inherited |
| | | public @interface Lob { |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.auto.common; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /**实体类对应生成mapper.xml的数据*/ |
| | | public class ReadEntityData { |
| | | //实体类的主键id名称 |
| | | private String entityIdName; |
| | | //表的主键id名称 |
| | | private String tableIdName; |
| | | //主键类型 |
| | | private String keyType; |
| | | //表的名称 |
| | | private String tableName; |
| | | //实体类和表的所有字段名称(除了主键) |
| | | private List<FieldAttribute> fields = new ArrayList<FieldAttribute>(); |
| | | //特殊字段,主键id,如:#{id} |
| | | private String entityIdData; |
| | | //特殊字段,mybatis的排序 |
| | | private String orderBy = "${orderBy}"; |
| | | //特殊字段,mybatis的实体类匹配表字段 |
| | | private String createData = "#{createData.obj}"; |
| | | //特殊字段,mybatis的传的值 |
| | | private String valueData = "#{value}"; |
| | | |
| | | /********************************************************************/ |
| | | /** 存储实体类的表字段 |
| | | * @param entityName 实体类字段名称 |
| | | * @param tableName1 表名称 |
| | | * @param dataType 类型 |
| | | */ |
| | | public void fielData(String entityName,String tableName1,String dataType,Integer isBlob,String mybatisName) { |
| | | fields.add(new FieldAttribute(entityName,tableName1, dataType,isBlob,mybatisName)); |
| | | } |
| | | |
| | | /******************************************************************/ |
| | | public String getEntityIdName() { |
| | | return entityIdName; |
| | | } |
| | | public void setEntityIdName(String entityIdName) { |
| | | this.entityIdName = entityIdName; |
| | | } |
| | | public String getTableIdName() { |
| | | return tableIdName; |
| | | } |
| | | public void setTableIdName(String tableIdName) { |
| | | this.tableIdName = tableIdName; |
| | | } |
| | | public String getTableName() { |
| | | return tableName; |
| | | } |
| | | public void setTableName(String tableName) { |
| | | this.tableName = tableName; |
| | | } |
| | | public List<FieldAttribute> getFields() { |
| | | return fields; |
| | | } |
| | | public void setFields(List<FieldAttribute> fields) { |
| | | this.fields = fields; |
| | | } |
| | | public String getOrderBy() { |
| | | return orderBy; |
| | | } |
| | | public void setOrderBy(String orderBy) { |
| | | this.orderBy = orderBy; |
| | | } |
| | | public String getKeyType() { |
| | | return keyType; |
| | | } |
| | | public void setKeyType(String keyType) { |
| | | this.keyType = keyType; |
| | | } |
| | | |
| | | public String getCreateData() { |
| | | return createData; |
| | | } |
| | | public void setCreateData(String createData) { |
| | | this.createData = createData; |
| | | } |
| | | public String getValueData() { |
| | | return valueData; |
| | | } |
| | | |
| | | public void setValueData(String valueData) { |
| | | this.valueData = valueData; |
| | | } |
| | | |
| | | public String getEntityIdData() { |
| | | return entityIdData; |
| | | } |
| | | |
| | | public void setEntityIdData(String entityIdData) { |
| | | this.entityIdData = entityIdData; |
| | | } |
| | | |
| | | /*****************************************************************/ |
| | | public static class FieldAttribute { |
| | | //实体类字段名称 |
| | | private String entityName; |
| | | //表字段名称 |
| | | private String tableName; |
| | | //数据库类型 |
| | | private String dataType; |
| | | //是否大数据 |
| | | private Integer isBlob = 0; |
| | | //特殊字段,如在mybati中 #{id}的表示 |
| | | private String mybatisName; |
| | | |
| | | /**********************************/ |
| | | public FieldAttribute(String entityName,String tableName,String dataType,Integer isBlob |
| | | ,String mybatisName) { |
| | | this.entityName = entityName; |
| | | this.tableName = tableName; |
| | | this.dataType = dataType; |
| | | this.isBlob = isBlob; |
| | | this.mybatisName = mybatisName; |
| | | } |
| | | |
| | | /*********************************/ |
| | | public String getDataType() { |
| | | return dataType; |
| | | } |
| | | public void setDataType(String dataType) { |
| | | this.dataType = dataType; |
| | | } |
| | | public String getEntityName() { |
| | | return entityName; |
| | | } |
| | | public void setEntityName(String entityName) { |
| | | this.entityName = entityName; |
| | | } |
| | | public String getTableName() { |
| | | return tableName; |
| | | } |
| | | public void setTableName(String tableName) { |
| | | this.tableName = tableName; |
| | | } |
| | | public Integer getIsBlob() { |
| | | return isBlob; |
| | | } |
| | | public void setIsBlob(Integer isBlob) { |
| | | this.isBlob = isBlob; |
| | | } |
| | | |
| | | public String getMybatisName() { |
| | | return mybatisName; |
| | | } |
| | | public void setMybatisName(String mybatisName) { |
| | | this.mybatisName = mybatisName; |
| | | } |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.hx.auto.common; |
| | | |
| | | /**属性保存*/ |
| | | public class UrlData { |
| | | |
| | | /**总包*/ |
| | | private String totalUrl; |
| | | /**生成action的包路径*/ |
| | | private String[] actionUrl; |
| | | /**生成mapper.xml路径*/ |
| | | private String[] mapperUrl; |
| | | /**生成DAO的包路径*/ |
| | | private String[] daoUrl; |
| | | /**生成service接口的包路径*/ |
| | | private String[] serviceUrl; |
| | | /**生成serviceImpl接口的包路径*/ |
| | | private String[] serviceImplUrl; |
| | | /**********************************/ |
| | | /** |
| | | * 一下类引入的路径需要 |
| | | * @param totalUrl 总包,如:com.songSir |
| | | */ |
| | | public void totalUrlData(String totalUrl){ |
| | | this.totalUrl = totalUrl; |
| | | } |
| | | |
| | | /**生成action的包路径 |
| | | * @param packRoot 根目录,如:src.main.java |
| | | * @param actionPack 包目录,如:com.songSir.model |
| | | */ |
| | | public void actionUrlData(String packRoot,String actionPack) { |
| | | actionUrl = new String[] {packRoot,actionPack}; |
| | | } |
| | | /**生成mapper.xml路径 |
| | | * |
| | | * @param packRoot 根目录,如:src.main.java |
| | | * @param mapperPack 包目录/文件目录,如:com.songSir.mapper 或者 com/songSir/mapper |
| | | */ |
| | | public void mapperUrlData(String packRoot,String mapperPack) { |
| | | mapperUrl = new String[] {packRoot,mapperPack}; |
| | | } |
| | | /**生成DAO的包路径 |
| | | * |
| | | * @param packRoot 根目录,如:src.main.java |
| | | * @param daoPack 包目录,如:com.songSir.dao |
| | | */ |
| | | public void daoUrlData(String packRoot,String daoPack) { |
| | | daoUrl = new String[] {packRoot,daoPack}; |
| | | } |
| | | /**生成service接口的包路径 |
| | | * |
| | | * @param packRoot 根目录,如:src.main.java |
| | | * @param servicePack 包目录,如:com.songSir.service |
| | | */ |
| | | public void serviceUrlData(String packRoot,String servicePack) { |
| | | serviceUrl = new String[] {packRoot,servicePack}; |
| | | } |
| | | /**生成service接口的包路径 |
| | | * |
| | | * @param packRoot 根目录,如:src.main.java |
| | | * @param serviceImpUrlPack 包目录,如:com.songSir.serviceImp |
| | | */ |
| | | public void serviceImplUrlData(String packRoot,String serviceImpUrlPack) { |
| | | serviceImplUrl = new String[] {packRoot,serviceImpUrlPack}; |
| | | } |
| | | /*********************************/ |
| | | public String[] getActionUrl() { |
| | | return actionUrl; |
| | | } |
| | | public void setActionUrl(String[] actionUrl) { |
| | | this.actionUrl = actionUrl; |
| | | } |
| | | public String[] getMapperUrl() { |
| | | return mapperUrl; |
| | | } |
| | | public void setMapperUrl(String[] mapperUrl) { |
| | | this.mapperUrl = mapperUrl; |
| | | } |
| | | public String[] getDaoUrl() { |
| | | return daoUrl; |
| | | } |
| | | public void setDaoUrl(String[] daoUrl) { |
| | | this.daoUrl = daoUrl; |
| | | } |
| | | public String[] getServiceUrl() { |
| | | return serviceUrl; |
| | | } |
| | | public void setServiceUrl(String[] serviceUrl) { |
| | | this.serviceUrl = serviceUrl; |
| | | } |
| | | public String[] getServiceImplUrl() { |
| | | return serviceImplUrl; |
| | | } |
| | | public void setServiceImplUrl(String[] serviceImplUrl) { |
| | | this.serviceImplUrl = serviceImplUrl; |
| | | } |
| | | |
| | | public String getTotalUrl() { |
| | | return totalUrl; |
| | | } |
| | | |
| | | public void setTotalUrl(String totalUrl) { |
| | | this.totalUrl = totalUrl; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto; |
| | | |
| | | import org.w3c.dom.Document; |
| | | import org.w3c.dom.NamedNodeMap; |
| | | import org.w3c.dom.Node; |
| | | import org.w3c.dom.NodeList; |
| | | import org.xml.sax.SAXException; |
| | | |
| | | import javax.xml.parsers.DocumentBuilder; |
| | | import javax.xml.parsers.DocumentBuilderFactory; |
| | | import javax.xml.parsers.ParserConfigurationException; |
| | | import javax.xml.transform.OutputKeys; |
| | | import javax.xml.transform.Transformer; |
| | | import javax.xml.transform.TransformerException; |
| | | import javax.xml.transform.TransformerFactory; |
| | | import javax.xml.transform.dom.DOMSource; |
| | | import javax.xml.transform.stream.StreamResult; |
| | | import java.io.*; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 自动生成Service and ServiceImpl |
| | | * |
| | | * @author chenjiahe 2020-06-28 |
| | | * |
| | | */ |
| | | public class GeneratorReadXmlUtil { |
| | | |
| | | /** |
| | | * |
| | | * @param targetFile 文件路径 |
| | | * @return 返回自定义的sql |
| | | */ |
| | | public static String readMapperXml(String targetFile) throws ParserConfigurationException, IOException, SAXException { |
| | | String temp = ""; |
| | | |
| | | //映射文件的文件夹 |
| | | File file = new File(targetFile); |
| | | if(!file.exists()){ |
| | | return "false"; |
| | | } |
| | | |
| | | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| | | DocumentBuilder builder = factory.newDocumentBuilder(); |
| | | Document doc = builder.parse(file); |
| | | Node Node= doc.getLastChild(); |
| | | NodeList nodeList = Node.getChildNodes(); |
| | | |
| | | String comment = ""; |
| | | for(int i=0;i<nodeList.getLength();i++) { |
| | | //从节点集中获取i个book节点 |
| | | Node childNode = nodeList.item(i); |
| | | //获取子节点内的文本内容 |
| | | String content = childNode.getTextContent(); |
| | | //获取节点名 |
| | | String name = childNode.getNodeName(); |
| | | //System.out.println("content:"+content+";name:"+name); |
| | | //System.out.println("name....:"+name); |
| | | if(!"#text".equals(name)&&!"#comment".equals(name)){ |
| | | //获取第一个节点内的所有属性 |
| | | NamedNodeMap nameNodeMap = childNode.getAttributes(); |
| | | //获取节点内名为id的属性的值 |
| | | String id = nameNodeMap.getNamedItem("id").getTextContent(); |
| | | if(isCustom(nameNodeMap.getNamedItem("id").getTextContent())){ |
| | | String con = NodetoString(childNode); |
| | | //去掉附带的内容 |
| | | con = con.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>",""); |
| | | String con2 = con; |
| | | con = con.replaceAll("\t","").replaceAll("\n",""); |
| | | if(con.length()>3){ |
| | | con= con2; |
| | | } |
| | | temp+=comment+"\n\t"+con; |
| | | } |
| | | comment = ""; |
| | | }else{ |
| | | String con = NodetoString(childNode); |
| | | //去掉附带的内容 |
| | | con = con.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>",""); |
| | | String con2 = con; |
| | | //去掉多余的 |
| | | con = con.replaceAll("\t","").replaceAll("\n",""); |
| | | if(con.length()>5){ |
| | | comment+= con2; |
| | | } |
| | | } |
| | | } |
| | | System.out.println("temp:...:"+temp); |
| | | return temp; |
| | | } |
| | | |
| | | public static boolean isCustom(String id){ |
| | | boolean custom = true; |
| | | Set<String> noCustomIds = new HashSet<String>(); |
| | | noCustomIds.add("BaseResultMap"); |
| | | noCustomIds.add("Entity_Id"); |
| | | noCustomIds.add("Table_Id"); |
| | | noCustomIds.add("Table_Name"); |
| | | noCustomIds.add("Base_Column_List"); |
| | | noCustomIds.add("Blob_Column_List"); |
| | | noCustomIds.add("Insert_Column_All"); |
| | | noCustomIds.add("Update_Column_All"); |
| | | noCustomIds.add("Update_Column_NoNull"); |
| | | noCustomIds.add("keyFind"); |
| | | noCustomIds.add("insert"); |
| | | noCustomIds.add("insertById"); |
| | | noCustomIds.add("selectList"); |
| | | noCustomIds.add("selectListBlob"); |
| | | noCustomIds.add("selectOne"); |
| | | noCustomIds.add("selectOneBlob"); |
| | | noCustomIds.add("selectOneByKey"); |
| | | noCustomIds.add("selectOneByKeyBlob"); |
| | | noCustomIds.add("updateWhere"); |
| | | noCustomIds.add("updateAll"); |
| | | noCustomIds.add("updateByNoNull"); |
| | | noCustomIds.add("deleteWhere"); |
| | | noCustomIds.add("deleteById"); |
| | | noCustomIds.add("selectCount"); |
| | | noCustomIds.add("Insert_Values_All"); |
| | | noCustomIds.add("selectListMap"); |
| | | noCustomIds.add("selectOneMap"); |
| | | noCustomIds.add("selectCountSql"); |
| | | if (noCustomIds.contains(id)){ |
| | | custom = false; |
| | | } |
| | | return custom; |
| | | } |
| | | |
| | | |
| | | |
| | | /* |
| | | * 把dom文件转换为xml字符串 |
| | | */ |
| | | public static String toStringFromDoc(Document document) throws IOException { |
| | | String result = null; |
| | | |
| | | if (document != null) { |
| | | StringWriter strWtr = new StringWriter(); |
| | | StreamResult strResult = new StreamResult(strWtr); |
| | | TransformerFactory tfac = TransformerFactory.newInstance(); |
| | | try { |
| | | javax.xml.transform.Transformer t = tfac.newTransformer(); |
| | | t.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); |
| | | t.setOutputProperty(OutputKeys.INDENT, "yes"); |
| | | t.setOutputProperty(OutputKeys.METHOD, "xml"); // xml, html, |
| | | // text |
| | | t.setOutputProperty( |
| | | "{http://xml.apache.org/xslt}indent-amount", "4"); |
| | | t.transform(new DOMSource(document.getDocumentElement()), |
| | | strResult); |
| | | } catch (Exception e) { |
| | | System.err.println("XML.toString(Document): " + e); |
| | | } |
| | | result = strResult.getWriter().toString(); |
| | | strWtr.close(); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 将传入的一个DOM Node对象输出成字符串。如果失败则返回一个空字符串""。 |
| | | * |
| | | * @param node |
| | | * DOM Node 对象。 |
| | | * @return a XML String from node |
| | | */ |
| | | public static String NodetoString(Node node) { |
| | | Transformer transformer = null; |
| | | String result = null; |
| | | if (node == null) { |
| | | throw new IllegalArgumentException(); |
| | | } |
| | | try { |
| | | transformer = TransformerFactory.newInstance().newTransformer(); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e.getMessage()); |
| | | } |
| | | if (transformer != null) { |
| | | try { |
| | | StringWriter sw = new StringWriter(); |
| | | transformer.transform(new DOMSource(node), new StreamResult(sw)); |
| | | return sw.toString(); |
| | | } catch (TransformerException te) { |
| | | throw new RuntimeException(te.getMessage()); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package ${packageName}; |
| | | |
| | | import java.util.List; |
| | | import javax.annotation.Resource; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import com.github.pagehelper.PageHelper; |
| | | import com.github.pagehelper.PageInfo; |
| | | |
| | | import com.hx.common.BaseController; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import ${DAOPackageName}.${entityName}Mapper; |
| | | import ${entityPackageName}.${entityName}; |
| | | import ${servicePackageName}.${entityName}Service; |
| | | import com.hx.resultTool.Result; |
| | | import com.hx.util.SimpleTool; |
| | | import net.sf.json.JSONObject; |
| | | import com.hx.phitab.common.AuthConstants; |
| | | |
| | | @RestController |
| | | @RequestMapping("${entityNameSmall}") |
| | | public class ${entityName}Controller extends BaseController { |
| | | |
| | | @Resource |
| | | private ${entityName}Service service; |
| | | |
| | | /**列表*/ |
| | | @Authority(tag = AuthConstants.${entityName}.SEE) |
| | | @RequestMapping("/list") |
| | | public Result listData(Integer pageNum,Integer pageSize) { |
| | | //pageNum当前第几页 |
| | | //rowCount 拿几条 |
| | | |
| | | //分页插件 |
| | | PageHelper.startPage(pageNum==null?1:pageNum,pageSize==null?20:pageSize); |
| | | SqlSentence sqlSentence = new SqlSentence(); |
| | | List<${entityName}> ${entityNameSmall}s = service.selectList(sqlSentence); |
| | | PageInfo pageInfo = new PageInfo<${entityName}>(${entityNameSmall}s); |
| | | Map<String,Object> data = new HashMap<>(); |
| | | data.put("pageNum",pageInfo.getPageNum()); |
| | | data.put("pageSize",pageInfo.getPageSize()); |
| | | data.put("total",pageInfo.getTotal()); |
| | | data.put("isLastPage",pageInfo.isIsLastPage()); |
| | | data.put("list",pageInfo.getList()); |
| | | return Result.success(data); |
| | | } |
| | | |
| | | /**新增*/ |
| | | @Authority(tag = AuthConstants.${entityName}.ADD) |
| | | @RequestMapping("/add") |
| | | public Result addData(${entityName} ${entityNameSmall}) { |
| | | service.insert(${entityNameSmall}); |
| | | return Result.success(); |
| | | } |
| | | |
| | | /**获取数据*/ |
| | | @Authority(tag = AuthConstants.${entityName}.SEE) |
| | | @RequestMapping("/see") |
| | | public Result editeData(String id) { |
| | | ${entityName} ${entityNameSmall} = service.selectOneByKeyBlob(id); |
| | | return Result.success(${entityNameSmall}); |
| | | } |
| | | |
| | | /**修改数据*/ |
| | | @Authority(tag = AuthConstants.${entityName}.EDIT) |
| | | @RequestMapping("/update") |
| | | public Result updateData(${entityName} ${entityNameSmall}) { |
| | | service.updateAll(${entityNameSmall}); |
| | | return Result.success(); |
| | | } |
| | | |
| | | /**删除数据(单个)*/ |
| | | @Authority(tag = AuthConstants.${entityName}.DELETE) |
| | | @RequestMapping("/delete/one") |
| | | public Result deleteData(String id) { |
| | | service.deleteOne(id); |
| | | return Result.success(); |
| | | } |
| | | } |
New file |
| | |
| | | package ${DAOPackageName}; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import ${entityPackageName}.${entityName}; |
| | | |
| | | public interface ${entityName}Mapper { |
| | | /**新增,返回主键*/ |
| | | int insert(${entityName} ${entityNameSmall}); |
| | | /**新增,返回主键*/ |
| | | int insertById(${entityName} ${entityNameSmall}); |
| | | /**查询条数*/ |
| | | int selectCount(SqlSentence sqlSentence); |
| | | /**查询列表,返回实体类的List*/ |
| | | List<${entityName}> selectList(SqlSentence sqlSentence); |
| | | /**查询列表,返回Map的List*/ |
| | | List<Map<String,Object>> selectListMap(SqlSentence sqlSentence); |
| | | /**查询,返回单个实体*/ |
| | | ${entityName} selectOne(SqlSentence sqlSentence); |
| | | /**查询,返回单个map*/ |
| | | Map<String,Object> selectOneMap(SqlSentence sqlSentence); |
| | | /**查询,返回实体类没有大数据的*/ |
| | | ${entityName} selectOneByKey(Object object); |
| | | /**查询,返回实体类有大数据的*/ |
| | | ${entityName} selectOneByKeyBlob(Object object); |
| | | /**更新,返回更新数量*/ |
| | | int updateWhere(SqlSentence sqlSentence); |
| | | /**更新,返回更新数量*/ |
| | | int updateAll(${entityName} ${entityNameSmall}); |
| | | /**删除,返回删除数量*/ |
| | | int deleteWhere(SqlSentence sqlSentence); |
| | | /**删除,返回删除数量*/ |
| | | int deleteById(Object object); |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <!-- namespace:该mapper.xml映射文件的 唯一标识 --> |
| | | <mapper namespace="${DAOPackageName}.${entityName}Mapper"> |
| | | |
| | | <!-- 整个实体类修改,表字段=实体类字段--> |
| | | <sql id="Update_Column_All"> |
| | | <trim prefixOverrides=","> |
| | | <#list fieldData.fields as item>,${item.tableName} = ${item.mybatisName}</#list> |
| | | </trim> |
| | | </sql> |
| | | |
| | | <!-- 后续通过 namespace.id--> |
| | | <!--parameterType:输入参数的类型 |
| | | resultType:查询返回结果值的类型 ,返回类型 --> |
| | | <insert id="insert" parameterType="${packageEntityName}.${entityName}"> |
| | | <selectKey keyProperty="id" resultType="String" order="BEFORE"> |
| | | select replace(uuid(),'-','') from dual |
| | | </selectKey> |
| | | insert into ${fieldData.tableName} (${fieldData.tableIdName}<#list fieldData.fields as item>,${item.tableName}</#list>) |
| | | values (${fieldData.entityIdData}<#list fieldData.fields as item>,${item.mybatisName}</#list>) |
| | | </insert> |
| | | |
| | | <select id="selectList" resultType="${packageEntityName}.${entityName}" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectListMap" resultType="java.util.Map" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectOne" resultType="${packageEntityName}.${entityName}" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectOneMap" resultType="java.util.Map" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectCount" resultType="int" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | select |
| | | COUNT(*) |
| | | from ${fieldData.tableName} |
| | | WHERE ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectOneByKey" resultType="${packageEntityName}.${entityName}" parameterType="java.lang.Object" > |
| | | select |
| | | ${fieldData.tableIdName}<#list fieldData.fields as item>,${item.tableName}</#list> |
| | | from ${fieldData.tableName} |
| | | WHERE ${fieldData.tableIdName} = ${fieldData.valueData} |
| | | </select> |
| | | |
| | | <select id="selectOneByKeyBlob" resultType="${packageEntityName}.${entityName}" parameterType="java.lang.Object" > |
| | | select |
| | | ${fieldData.tableIdName}<#list fieldData.fields as item>,${item.tableName}</#list> |
| | | from ${fieldData.tableName} |
| | | WHERE ${fieldData.tableIdName} = ${fieldData.valueData} |
| | | </select> |
| | | |
| | | <update id="updateWhere" parameterType="com.hx.mybatisTool.SqlSentence"> |
| | | update |
| | | ${fieldData.tableName} |
| | | SET ${sqlSentence} |
| | | </update> |
| | | |
| | | <update id="updateAll" parameterType="${packageEntityName}.${entityName}"> |
| | | update ${fieldData.tableName} |
| | | SET <include refid="Update_Column_All"/> |
| | | WHERE ${fieldData.tableIdName} = ${fieldData.entityIdData} |
| | | </update> |
| | | |
| | | <delete id="deleteWhere" parameterType="com.hx.mybatisTool.SqlSentence"> |
| | | delete from ${fieldData.tableName} WHERE ${sqlSentence} |
| | | </delete> |
| | | |
| | | <delete id="deleteById" parameterType="java.lang.Object"> |
| | | delete from ${fieldData.tableName} WHERE ${fieldData.tableIdName} = ${fieldData.valueData} |
| | | </delete> |
| | | ${customData} |
| | | </mapper> |
New file |
| | |
| | | package ${servicePack}; |
| | | |
| | | import ${packageName}.${classNameUP}; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface ${classNameUP}Service { |
| | | |
| | | int selectCount(SqlSentence sqlSentence); |
| | | |
| | | void insert(${classNameUP} ${className}); |
| | | |
| | | List<${classNameUP}> selectList(SqlSentence sqlSentence); |
| | | |
| | | List<Map<String,Object>> selectListMap(SqlSentence sqlSentence); |
| | | |
| | | ${classNameUP} selectOne(SqlSentence sqlSentence); |
| | | |
| | | Map<String,Object> selectOneMap(SqlSentence sqlSentence); |
| | | |
| | | ${classNameUP} selectOneByKey(Object object); |
| | | |
| | | ${classNameUP} selectOneByKeyBlob(Object object); |
| | | |
| | | void updateAll(${classNameUP} ${className}); |
| | | |
| | | void updateWhere(SqlSentence sqlSentence); |
| | | |
| | | void deleteOne(String delId); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package ${serviceImpPack}; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import ${daoPack}.${classNameUP}Mapper; |
| | | import ${packageName}.${classNameUP}; |
| | | import ${servicePack}.${classNameUP}Service; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Transactional |
| | | @Service |
| | | public class ${classNameUP}ServiceImpl implements ${classNameUP}Service { |
| | | |
| | | @Resource |
| | | private ${classNameUP}Mapper ${className}Mapper; |
| | | |
| | | /**查询列表*/ |
| | | @Override |
| | | public List<${classNameUP}> selectList(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectList(sqlSentence); |
| | | } |
| | | |
| | | /**查询列表*/ |
| | | @Override |
| | | public List<Map<String,Object>> selectListMap(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectListMap(sqlSentence); |
| | | } |
| | | |
| | | /**查询单个*/ |
| | | @Override |
| | | public ${classNameUP} selectOne(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectOne(sqlSentence); |
| | | } |
| | | |
| | | /**查询单个*/ |
| | | @Override |
| | | public Map<String,Object> selectOneMap(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectOneMap(sqlSentence); |
| | | } |
| | | |
| | | /**查询单个,大数据不拿取*/ |
| | | @Override |
| | | public ${classNameUP} selectOneByKey(Object object) { |
| | | return ${className}Mapper.selectOneByKey(object); |
| | | } |
| | | |
| | | /**查询单个,大数据拿取*/ |
| | | @Override |
| | | public ${classNameUP} selectOneByKeyBlob(Object object) { |
| | | return ${className}Mapper.selectOneByKeyBlob(object); |
| | | } |
| | | |
| | | /**新增*/ |
| | | @Override |
| | | public void insert(${classNameUP} ${className}) { |
| | | int count = ${className}Mapper.insert(${className}); |
| | | if(count != 1) { |
| | | throw new TipsException("新增失败!"); |
| | | } |
| | | } |
| | | |
| | | /**修改*/ |
| | | @Override |
| | | public void updateAll(${classNameUP} ${className}) { |
| | | int count = ${className}Mapper.updateAll(${className}); |
| | | if(count!=1) { |
| | | throw new TipsException("保存失败!"); |
| | | } |
| | | } |
| | | |
| | | /**修改*/ |
| | | @Override |
| | | public void updateWhere(SqlSentence sqlSentence) { |
| | | int count = ${className}Mapper.updateWhere(sqlSentence); |
| | | if(count!=1) { |
| | | throw new TipsException("保存失败!"); |
| | | } |
| | | } |
| | | |
| | | /**删除一个*/ |
| | | @Override |
| | | public void deleteOne(String delId) { |
| | | int count = ${className}Mapper.deleteById(delId); |
| | | if(count!=1) { |
| | | throw new TipsException("删除失败!"); |
| | | } |
| | | } |
| | | |
| | | /**查询条数*/ |
| | | @Override |
| | | public int selectCount(SqlSentence sqlSentence) { |
| | | int count = ${className}Mapper.selectCount(sqlSentence); |
| | | return count; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto.manage.xml.scan; |
| | | |
| | | |
| | | /** |
| | | * 启动时执行处理的接口 |
| | | * @author chenbin.sun |
| | | * |
| | | */ |
| | | public interface StartScanXmlHandler { |
| | | |
| | | /** |
| | | * 建表开始 |
| | | */ |
| | | void startHandler() throws Exception; |
| | | } |
New file |
| | |
| | | package com.hx.auto.manage.xml.scan; |
| | | |
| | | import com.hx.auto.GeneratorUtil; |
| | | import com.hx.auto.manage.xml.scan.util.ConfigUtil; |
| | | import com.hx.auto.manage.xml.scan.util.CreateMapperUtil; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.PostConstruct; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * 启动时进行处理的实现类 |
| | | * @author chenbin.sun |
| | | * |
| | | */ |
| | | @SuppressWarnings("restriction") |
| | | @Service |
| | | public class StartScanXmlHandlerImpl implements StartScanXmlHandler { |
| | | |
| | | @Autowired |
| | | private ConfigUtil configUtil; |
| | | |
| | | @PostConstruct |
| | | public void startHandler() throws Exception { |
| | | if(configUtil.getIsScan()){ |
| | | System.out.println("开始扫描更新xml文件"); |
| | | Set<Class<?>> classes = GeneratorUtil.classData(configUtil.getModelPack()); |
| | | for(Class<?> cl:classes) { |
| | | CreateMapperUtil.generatorMapper(cl,configUtil); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto.manage.xml.scan.util; |
| | | |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.beans.factory.config.BeanFactoryPostProcessor; |
| | | import org.springframework.beans.factory.config.PropertyResourceConfigurer; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.core.io.support.PropertiesLoaderSupport; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.Properties; |
| | | |
| | | @Component |
| | | public class ConfigUtil implements ApplicationContextAware { |
| | | |
| | | private static ApplicationContext applicationContext; |
| | | |
| | | private static Properties properties = null; |
| | | |
| | | @Value(Constants.CJH_SCAN_XML_SUPPLY) |
| | | private String isScan; |
| | | |
| | | @Value(Constants.CJH_PACKAGE_FILE_NAME_URL) |
| | | private String packFileName; |
| | | |
| | | @Value(Constants.CJH_PACKAGE_MODEL_URL) |
| | | private String modelPack; |
| | | |
| | | @Value(Constants.CJH_CREATE_XML_URL) |
| | | private String xmlUrl; |
| | | |
| | | @Value(Constants.CJH_CREATE_DAO_URL) |
| | | private String daoUrl; |
| | | |
| | | /** |
| | | * 实现ApplicationContextAware接口的回调方法,设置上下文环境 |
| | | */ |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContext) { |
| | | ConfigUtil.applicationContext = applicationContext; |
| | | } |
| | | |
| | | /** |
| | | * 获得spring上下文 |
| | | * |
| | | * @return ApplicationContext spring上下文 |
| | | */ |
| | | public ApplicationContext getApplicationContext() { |
| | | return applicationContext; |
| | | } |
| | | |
| | | /** |
| | | * 获取bean |
| | | * |
| | | * @param name |
| | | * service注解方式name为小驼峰格式 |
| | | * @return Object bean的实例对象 |
| | | */ |
| | | public Object getBean(String name) throws BeansException { |
| | | return applicationContext.getBean(name); |
| | | } |
| | | |
| | | private void initProperties() { |
| | | |
| | | properties = new Properties(); |
| | | try { |
| | | String[] postProcessorNames = applicationContext.getBeanNamesForType(BeanFactoryPostProcessor.class, true, |
| | | true); |
| | | for (String ppName : postProcessorNames) { |
| | | BeanFactoryPostProcessor beanProcessor = applicationContext.getBean(ppName, |
| | | BeanFactoryPostProcessor.class); |
| | | if (beanProcessor instanceof PropertyResourceConfigurer) { |
| | | PropertyResourceConfigurer propertyResourceConfigurer = (PropertyResourceConfigurer) beanProcessor; |
| | | Method mergeProperties = PropertiesLoaderSupport.class.getDeclaredMethod("mergeProperties"); |
| | | mergeProperties.setAccessible(true); |
| | | Properties props = (Properties) mergeProperties.invoke(propertyResourceConfigurer); |
| | | |
| | | // get the method convertProperties |
| | | // in class PropertyResourceConfigurer |
| | | Method convertProperties = PropertyResourceConfigurer.class.getDeclaredMethod("convertProperties", |
| | | Properties.class); |
| | | // convert properties |
| | | convertProperties.setAccessible(true); |
| | | convertProperties.invoke(propertyResourceConfigurer, props); |
| | | |
| | | properties.putAll(props); |
| | | } |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | |
| | | public static Properties getProperties() { |
| | | return properties; |
| | | } |
| | | |
| | | public static void setProperties(Properties properties) { |
| | | ConfigUtil.properties = properties; |
| | | } |
| | | |
| | | public String getModelPack() { |
| | | return modelPack; |
| | | } |
| | | |
| | | public void setModelPack(String modelPack) { |
| | | this.modelPack = modelPack; |
| | | } |
| | | |
| | | public Boolean getIsScan() { |
| | | return "true".equals(isScan); |
| | | } |
| | | |
| | | public void setIsScan(String isScan) { |
| | | this.isScan = isScan; |
| | | } |
| | | |
| | | public String getPackFileName() { |
| | | return packFileName; |
| | | } |
| | | |
| | | public void setPackFileName(String packFileName) { |
| | | this.packFileName = packFileName; |
| | | } |
| | | |
| | | public String getXmlUrl() { |
| | | return xmlUrl; |
| | | } |
| | | |
| | | public void setXmlUrl(String xmlUrl) { |
| | | this.xmlUrl = xmlUrl; |
| | | } |
| | | |
| | | public String getDaoUrl() { |
| | | return daoUrl; |
| | | } |
| | | |
| | | public void setDaoUrl(String daoUrl) { |
| | | this.daoUrl = daoUrl; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto.manage.xml.scan.util; |
| | | |
| | | public class Constants { |
| | | |
| | | /**是否扫描补充xml文件*/ |
| | | public static final String CJH_SCAN_XML_SUPPLY = "${xml.scan.xml.supply}"; |
| | | /**项目名称*/ |
| | | public static final String CJH_PROJECT_NAME = "${xml.priject.name}"; |
| | | /**包所在的文件夹路径*/ |
| | | public static final String CJH_PACKAGE_FILE_NAME_URL = "${xml.package.file.name}"; |
| | | /**生成DAO路径*/ |
| | | public static final String CJH_CREATE_DAO_URL = "${xml.create.dao.url}"; |
| | | /**生成路径*/ |
| | | public static final String CJH_CREATE_XML_URL = "${xml.create.xml.url}"; |
| | | /**实体类包路径*/ |
| | | public static final String CJH_PACKAGE_MODEL_URL = "${xml.model.name}"; |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.auto.manage.xml.scan.util; |
| | | |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Column; |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Table; |
| | | import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant; |
| | | import com.hx.auto.GeneratorMapperUtil; |
| | | import com.hx.auto.GeneratorReadXmlUtil; |
| | | import com.hx.auto.common.JdbcType; |
| | | import com.hx.auto.common.ReadEntityData; |
| | | import com.hx.auto.util.CommonTool; |
| | | import com.hx.auto.util.GeneratorClassParentUtil; |
| | | import freemarker.template.Configuration; |
| | | import freemarker.template.DefaultObjectWrapper; |
| | | import freemarker.template.Template; |
| | | |
| | | import java.io.*; |
| | | import java.lang.reflect.Field; |
| | | import java.util.HashMap; |
| | | |
| | | /** |
| | | * 自动生成mapper.xml |
| | | * |
| | | * @author chenjiahe 2019年09月08日23:57:47 |
| | | * |
| | | */ |
| | | public class CreateMapperUtil { |
| | | |
| | | private static String templateDir = "/ftl";//获取模板路径 |
| | | private static String templateName = "Mapper.tpl";//action模板名称 |
| | | |
| | | /**生成mapper.xml |
| | | * @param cl 实体类 |
| | | * @param configUtil 生成配置信息 |
| | | * @throws Exception |
| | | */ |
| | | public static void generatorMapper(Class<?> cl, ConfigUtil configUtil) throws Exception { |
| | | try { |
| | | |
| | | // 反射start |
| | | // 类名 |
| | | String entityName = cl.getSimpleName(); |
| | | |
| | | //生成文件路径 |
| | | String targetFile = configUtil.getXmlUrl().replace(".", "/")+"/"; |
| | | //生成文件名称 |
| | | targetFile += entityName + "Mapper.xml"; |
| | | //补全路径 |
| | | targetFile = "./"+configUtil.getPackFileName().replace(".", "/")+"/"+targetFile; |
| | | //获取是否已经生成过文件,拿取自定义的内容 |
| | | String xmlData = GeneratorReadXmlUtil.readMapperXml(targetFile); |
| | | |
| | | //如果不存在就直接跳过 |
| | | if("false".equals(xmlData)){ |
| | | return; |
| | | } |
| | | |
| | | // 类名首字母小写 |
| | | String initial = entityName.substring(0, 1).toLowerCase(); |
| | | String entityNameSmall = initial + entityName.substring(1, entityName.length()); |
| | | |
| | | //获取实体类包名 |
| | | String[] strs = cl.getName().split("\\."); |
| | | String packageName = ""; |
| | | //去掉类名 |
| | | for(int i=0;i<strs.length-1;i++) { |
| | | packageName += "."+strs[i]; |
| | | } |
| | | packageName = packageName.replaceFirst(".", ""); |
| | | |
| | | //获取模板 |
| | | Configuration configuration = new Configuration(Configuration.getVersion()); |
| | | configuration.setClassForTemplateLoading(GeneratorMapperUtil.class, templateDir); |
| | | // 获取或创建模板 |
| | | Template template = configuration.getTemplate(templateName); |
| | | |
| | | //实体类所有的字段 |
| | | //用来存储数据 |
| | | ReadEntityData readEntityData = new ReadEntityData(); |
| | | //表名称 |
| | | Table table = cl.getAnnotation(Table.class); |
| | | readEntityData.setTableName(table.name()); |
| | | // 取得本类的全部属性 |
| | | Field[] fields = cl.getDeclaredFields(); |
| | | fields = GeneratorClassParentUtil.getPatentFields(fields,cl); |
| | | for (Field field:fields) { |
| | | // 判断方法中是否有指定注解类型的注解 |
| | | boolean hasAnnotation = field.isAnnotationPresent(Column.class); |
| | | if (hasAnnotation) { |
| | | // 根据注解类型返回方法的指定类型注解 |
| | | Column column = field.getAnnotation(Column.class); |
| | | |
| | | //判断是不是 |
| | | boolean isBol = false; |
| | | Integer isBlob = 0; |
| | | if(column.type().equals(MySqlTypeConstant.TEXT)||column.type().equals(MySqlTypeConstant.LONGTEXT) |
| | | ||column.type().equals(MySqlTypeConstant.LONGBLOB)){ |
| | | isBol = true; |
| | | isBlob = 1; |
| | | } |
| | | |
| | | //类型 |
| | | //String type = column.type().toUpperCase(); |
| | | String type = JdbcType.jdbcTypeData(field.getType().getTypeName().toUpperCase(),isBol); |
| | | //主键 |
| | | if (column.isKey()) { |
| | | readEntityData.setEntityIdName(field.getName()); |
| | | readEntityData.setEntityIdData("#{"+field.getName()+"}"); |
| | | if(!CommonTool.checkNotNull(column.name())) { |
| | | readEntityData.setTableIdName(field.getName()); |
| | | }else { |
| | | readEntityData.setTableIdName(column.name()); |
| | | } |
| | | readEntityData.setKeyType(type); |
| | | continue; |
| | | } |
| | | //存储数据 |
| | | if(!CommonTool.checkNotNull(column.name())) { |
| | | readEntityData.fielData(field.getName(),field.getName(),type,isBlob,"#{"+field.getName()+"}"); |
| | | }else { |
| | | readEntityData.fielData(field.getName(),column.name(),type,isBlob,"#{"+field.getName()+"}"); |
| | | } |
| | | } |
| | | } |
| | | // 创建数据模型 |
| | | HashMap<String, Object> root = new HashMap<String, Object>(); |
| | | |
| | | root.put("packageEntityName",packageName); |
| | | //实体类的类名 |
| | | root.put("entityName", entityName); |
| | | //实体类的类名(首字母小写) |
| | | root.put("entityNameSmall", entityNameSmall); |
| | | //表字段 数据 |
| | | root.put("fieldData",readEntityData); |
| | | |
| | | root.put("sqlSentence","${sqlSentence}"); |
| | | |
| | | root.put("DAOPackageName",configUtil.getDaoUrl()); |
| | | //实体类的包名 |
| | | root.put("entityPackageName",packageName); |
| | | |
| | | //获取是否已经生成过文件,拿取自定义的内容 |
| | | root.put("customData",xmlData); |
| | | |
| | | System.out.println("mapperUrl:"+targetFile); |
| | | // 将模板和数据模型合并 输出到Console |
| | | Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "UTF-8")); |
| | | template.process(root, out); |
| | | out.flush(); |
| | | out.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.auto.util; |
| | | |
| | | public class CommonTool { |
| | | |
| | | /** |
| | | * 判断是否为空 |
| | | */ |
| | | public static boolean checkNotNull(Object o) { |
| | | boolean b = false; |
| | | if (o != null && !"".equals(o)&&!"undefind".equals(o)) { |
| | | b = true; |
| | | } |
| | | return b; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.auto.util; |
| | | |
| | | import org.w3c.dom.Document; |
| | | import org.w3c.dom.NamedNodeMap; |
| | | import org.w3c.dom.Node; |
| | | import org.w3c.dom.NodeList; |
| | | import org.xml.sax.SAXException; |
| | | |
| | | import javax.xml.parsers.DocumentBuilder; |
| | | import javax.xml.parsers.DocumentBuilderFactory; |
| | | import javax.xml.parsers.ParserConfigurationException; |
| | | import javax.xml.transform.OutputKeys; |
| | | import javax.xml.transform.Transformer; |
| | | import javax.xml.transform.TransformerException; |
| | | import javax.xml.transform.TransformerFactory; |
| | | import javax.xml.transform.dom.DOMSource; |
| | | import javax.xml.transform.stream.StreamResult; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.io.StringWriter; |
| | | import java.lang.reflect.Field; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * |
| | | * @author chenjiahe 2020-06-28 |
| | | * |
| | | */ |
| | | public class GeneratorClassParentUtil { |
| | | |
| | | /** |
| | | * 获取父类的字段 |
| | | * @param fields |
| | | * @param clas |
| | | * @return |
| | | */ |
| | | public static Field[] getPatentFields(Field[] fields,Class<?> clas){ |
| | | if (clas.getSuperclass() != null) { |
| | | Class clsSup = clas.getSuperclass(); |
| | | List<Field> fieldList = new ArrayList<Field>(); |
| | | fieldList.addAll(Arrays.asList(fields)); |
| | | fieldList.addAll(Arrays.asList(clsSup.getDeclaredFields())); |
| | | fields = new Field[fieldList.size()]; |
| | | int i = 0; |
| | | for (Object field : fieldList.toArray()) { |
| | | fields[i] = (Field) field; |
| | | i++; |
| | | } |
| | | fields = getPatentFields(fields,clsSup); |
| | | } |
| | | return fields; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package ${packageName}; |
| | | |
| | | import java.util.List; |
| | | import javax.annotation.Resource; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import com.github.pagehelper.PageHelper; |
| | | import com.github.pagehelper.PageInfo; |
| | | |
| | | import com.hx.common.BaseController; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import ${DAOPackageName}.${entityName}Mapper; |
| | | import ${entityPackageName}.${entityName}; |
| | | import ${servicePackageName}.${entityName}Service; |
| | | import com.hx.resultTool.Result; |
| | | import com.hx.util.SimpleTool; |
| | | import net.sf.json.JSONObject; |
| | | import com.hx.phitab.common.AuthConstants; |
| | | |
| | | @RestController |
| | | @RequestMapping("${entityNameSmall}") |
| | | public class ${entityName}Controller extends BaseController { |
| | | |
| | | @Resource |
| | | private ${entityName}Service service; |
| | | |
| | | /**列表*/ |
| | | @Authority(tag = AuthConstants.${entityName}.SEE) |
| | | @RequestMapping("/list") |
| | | public Result listData(Integer pageNum,Integer pageSize) { |
| | | //pageNum当前第几页 |
| | | //rowCount 拿几条 |
| | | |
| | | //分页插件 |
| | | PageHelper.startPage(pageNum==null?1:pageNum,pageSize==null?20:pageSize); |
| | | SqlSentence sqlSentence = new SqlSentence(); |
| | | List<${entityName}> ${entityNameSmall}s = service.selectList(sqlSentence); |
| | | PageInfo pageInfo = new PageInfo<${entityName}>(${entityNameSmall}s); |
| | | Map<String,Object> data = new HashMap<>(); |
| | | data.put("pageNum",pageInfo.getPageNum()); |
| | | data.put("pageSize",pageInfo.getPageSize()); |
| | | data.put("total",pageInfo.getTotal()); |
| | | data.put("isLastPage",pageInfo.isIsLastPage()); |
| | | data.put("list",pageInfo.getList()); |
| | | return Result.success(data); |
| | | } |
| | | |
| | | /**新增*/ |
| | | @Authority(tag = AuthConstants.${entityName}.ADD) |
| | | @RequestMapping("/add") |
| | | public Result addData(${entityName} ${entityNameSmall}) { |
| | | service.insert(${entityNameSmall}); |
| | | return Result.success(); |
| | | } |
| | | |
| | | /**获取数据*/ |
| | | @Authority(tag = AuthConstants.${entityName}.SEE) |
| | | @RequestMapping("/see") |
| | | public Result editeData(String id) { |
| | | ${entityName} ${entityNameSmall} = service.selectOneByKeyBlob(id); |
| | | return Result.success(${entityNameSmall}); |
| | | } |
| | | |
| | | /**修改数据*/ |
| | | @Authority(tag = AuthConstants.${entityName}.EDIT) |
| | | @RequestMapping("/update") |
| | | public Result updateData(${entityName} ${entityNameSmall}) { |
| | | service.updateAll(${entityNameSmall}); |
| | | return Result.success(); |
| | | } |
| | | |
| | | /**删除数据(单个)*/ |
| | | @Authority(tag = AuthConstants.${entityName}.DELETE) |
| | | @RequestMapping("/delete/one") |
| | | public Result deleteData(String id) { |
| | | service.deleteOne(id); |
| | | return Result.success(); |
| | | } |
| | | } |
New file |
| | |
| | | package ${DAOPackageName}; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import ${entityPackageName}.${entityName}; |
| | | |
| | | public interface ${entityName}Mapper { |
| | | /**新增,返回主键*/ |
| | | int insert(${entityName} ${entityNameSmall}); |
| | | /**新增,返回主键*/ |
| | | int insertById(${entityName} ${entityNameSmall}); |
| | | /**查询条数*/ |
| | | int selectCount(SqlSentence sqlSentence); |
| | | /**查询条数*/ |
| | | int selectCountSql(SqlSentence sqlSentence); |
| | | /**查询列表,返回实体类的List*/ |
| | | List<${entityName}> selectList(SqlSentence sqlSentence); |
| | | /**查询列表,返回Map的List*/ |
| | | List<Map<String,Object>> selectListMap(SqlSentence sqlSentence); |
| | | /**查询,返回单个实体*/ |
| | | ${entityName} selectOne(SqlSentence sqlSentence); |
| | | /**查询,返回单个map*/ |
| | | Map<String,Object> selectOneMap(SqlSentence sqlSentence); |
| | | /**查询,返回实体类没有大数据的*/ |
| | | ${entityName} selectOneByKey(Object object); |
| | | /**查询,返回实体类有大数据的*/ |
| | | ${entityName} selectOneByKeyBlob(Object object); |
| | | /**更新,返回更新数量*/ |
| | | int updateWhere(SqlSentence sqlSentence); |
| | | /**更新,返回更新数量*/ |
| | | int updateAll(${entityName} ${entityNameSmall}); |
| | | /**删除,返回删除数量*/ |
| | | int deleteWhere(SqlSentence sqlSentence); |
| | | /**删除,返回删除数量*/ |
| | | int deleteById(Object object); |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <!-- namespace:该mapper.xml映射文件的 唯一标识 --> |
| | | <mapper namespace="${DAOPackageName}.${entityName}Mapper"> |
| | | |
| | | <!-- 整个实体类修改,表字段=实体类字段--> |
| | | <sql id="Update_Column_All"> |
| | | <trim prefixOverrides=","> |
| | | <#list fieldData.fields as item>,${item.tableName} = ${item.mybatisName}</#list> |
| | | </trim> |
| | | </sql> |
| | | |
| | | <!-- 后续通过 namespace.id--> |
| | | <!--parameterType:输入参数的类型 |
| | | resultType:查询返回结果值的类型 ,返回类型 --> |
| | | <insert id="insert" parameterType="${packageEntityName}.${entityName}"> |
| | | <selectKey keyProperty="id" resultType="String" order="BEFORE"> |
| | | select replace(uuid(),'-','') from dual |
| | | </selectKey> |
| | | insert into ${fieldData.tableName} (${fieldData.tableIdName}<#list fieldData.fields as item>,${item.tableName}</#list>) values (${fieldData.entityIdData}<#list fieldData.fields as item>,${item.mybatisName}</#list>) |
| | | </insert> |
| | | |
| | | <insert id="insertById" parameterType="${packageEntityName}.${entityName}"> |
| | | insert into ${fieldData.tableName} (${fieldData.tableIdName}<#list fieldData.fields as item>,${item.tableName}</#list>) values (${fieldData.entityIdData}<#list fieldData.fields as item>,${item.mybatisName}</#list>) |
| | | </insert> |
| | | |
| | | <select id="selectList" resultType="${packageEntityName}.${entityName}" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectListMap" resultType="java.util.Map" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectOne" resultType="${packageEntityName}.${entityName}" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectOneMap" resultType="java.util.Map" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectCount" resultType="int" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | select |
| | | COUNT(*) |
| | | from ${fieldData.tableName} |
| | | WHERE ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectCountSql" resultType="int" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectOneByKey" resultType="${packageEntityName}.${entityName}" parameterType="java.lang.Object" > |
| | | select |
| | | ${fieldData.tableIdName}<#list fieldData.fields as item>,${item.tableName}</#list> |
| | | from ${fieldData.tableName} |
| | | WHERE ${fieldData.tableIdName} = ${fieldData.valueData} |
| | | </select> |
| | | |
| | | <select id="selectOneByKeyBlob" resultType="${packageEntityName}.${entityName}" parameterType="java.lang.Object" > |
| | | select |
| | | ${fieldData.tableIdName}<#list fieldData.fields as item>,${item.tableName}</#list> |
| | | from ${fieldData.tableName} |
| | | WHERE ${fieldData.tableIdName} = ${fieldData.valueData} |
| | | </select> |
| | | |
| | | <update id="updateWhere" parameterType="com.hx.mybatisTool.SqlSentence"> |
| | | update |
| | | ${fieldData.tableName} |
| | | SET ${sqlSentence} |
| | | </update> |
| | | |
| | | <update id="updateAll" parameterType="${packageEntityName}.${entityName}"> |
| | | update ${fieldData.tableName} |
| | | SET <include refid="Update_Column_All"/> |
| | | WHERE ${fieldData.tableIdName} = ${fieldData.entityIdData} |
| | | </update> |
| | | |
| | | <delete id="deleteWhere" parameterType="com.hx.mybatisTool.SqlSentence"> |
| | | delete from ${fieldData.tableName} WHERE ${sqlSentence} |
| | | </delete> |
| | | |
| | | <delete id="deleteById" parameterType="java.lang.Object"> |
| | | delete from ${fieldData.tableName} WHERE ${fieldData.tableIdName} = ${fieldData.valueData} |
| | | </delete> |
| | | ${customData} |
| | | </mapper> |
New file |
| | |
| | | package ${servicePack}; |
| | | |
| | | import ${packageName}.${classNameUP}; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface ${classNameUP}Service { |
| | | |
| | | int selectCount(SqlSentence sqlSentence); |
| | | |
| | | void insert(${classNameUP} ${className}); |
| | | |
| | | List<${classNameUP}> selectList(SqlSentence sqlSentence); |
| | | |
| | | List<Map<String,Object>> selectListMap(SqlSentence sqlSentence); |
| | | |
| | | ${classNameUP} selectOne(SqlSentence sqlSentence); |
| | | |
| | | Map<String,Object> selectOneMap(SqlSentence sqlSentence); |
| | | |
| | | ${classNameUP} selectOneByKey(Object object); |
| | | |
| | | ${classNameUP} selectOneByKeyBlob(Object object); |
| | | |
| | | void updateAll(${classNameUP} ${className}); |
| | | |
| | | void updateWhere(SqlSentence sqlSentence); |
| | | |
| | | void deleteOne(String delId); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package ${serviceImpPack}; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import ${daoPack}.${classNameUP}Mapper; |
| | | import ${packageName}.${classNameUP}; |
| | | import ${servicePack}.${classNameUP}Service; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Transactional |
| | | @Service |
| | | public class ${classNameUP}ServiceImpl implements ${classNameUP}Service { |
| | | |
| | | @Resource |
| | | private ${classNameUP}Mapper ${className}Mapper; |
| | | |
| | | /**查询列表*/ |
| | | @Override |
| | | public List<${classNameUP}> selectList(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectList(sqlSentence); |
| | | } |
| | | |
| | | /**查询列表*/ |
| | | @Override |
| | | public List<Map<String,Object>> selectListMap(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectListMap(sqlSentence); |
| | | } |
| | | |
| | | /**查询单个*/ |
| | | @Override |
| | | public ${classNameUP} selectOne(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectOne(sqlSentence); |
| | | } |
| | | |
| | | /**查询单个*/ |
| | | @Override |
| | | public Map<String,Object> selectOneMap(SqlSentence sqlSentence) { |
| | | return ${className}Mapper.selectOneMap(sqlSentence); |
| | | } |
| | | |
| | | /**查询单个,大数据不拿取*/ |
| | | @Override |
| | | public ${classNameUP} selectOneByKey(Object object) { |
| | | return ${className}Mapper.selectOneByKey(object); |
| | | } |
| | | |
| | | /**查询单个,大数据拿取*/ |
| | | @Override |
| | | public ${classNameUP} selectOneByKeyBlob(Object object) { |
| | | return ${className}Mapper.selectOneByKeyBlob(object); |
| | | } |
| | | |
| | | /**新增*/ |
| | | @Override |
| | | public void insert(${classNameUP} ${className}) { |
| | | int count = ${className}Mapper.insert(${className}); |
| | | if(count != 1) { |
| | | throw new TipsException("新增失败!"); |
| | | } |
| | | } |
| | | |
| | | /**修改*/ |
| | | @Override |
| | | public void updateAll(${classNameUP} ${className}) { |
| | | int count = ${className}Mapper.updateAll(${className}); |
| | | if(count!=1) { |
| | | throw new TipsException("保存失败!"); |
| | | } |
| | | } |
| | | |
| | | /**修改*/ |
| | | @Override |
| | | public void updateWhere(SqlSentence sqlSentence) { |
| | | int count = ${className}Mapper.updateWhere(sqlSentence); |
| | | if(count!=1) { |
| | | throw new TipsException("保存失败!"); |
| | | } |
| | | } |
| | | |
| | | /**删除一个*/ |
| | | @Override |
| | | public void deleteOne(String delId) { |
| | | int count = ${className}Mapper.deleteById(delId); |
| | | if(count!=1) { |
| | | throw new TipsException("删除失败!"); |
| | | } |
| | | } |
| | | |
| | | /**查询条数*/ |
| | | @Override |
| | | public int selectCount(SqlSentence sqlSentence) { |
| | | int count = ${className}Mapper.selectCount(sqlSentence); |
| | | return count; |
| | | } |
| | | } |
New file |
| | |
| | | # Compiled class file |
| | | *.class |
| | | |
| | | # Log file |
| | | *.log |
| | | |
| | | # BlueJ files |
| | | *.ctxt |
| | | |
| | | # Mobile Tools for Java (J2ME) |
| | | .mtj.tmp/ |
| | | |
| | | # Package Files # |
| | | *.jar |
| | | *.war |
| | | *.nar |
| | | *.ear |
| | | *.zip |
| | | *.tar.gz |
| | | *.rar |
| | | |
| | | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
| | | hs_err_pid* |
| | | /target/ |
| | | /.idea |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <parent> |
| | | <groupId>com.hx.gitee</groupId> |
| | | <artifactId>hx-parent</artifactId> |
| | | <version>stander</version> |
| | | </parent> |
| | | |
| | | <artifactId>hx-common</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <dependencies> |
| | | |
| | | <!--对象与XML处理--> |
| | | <dependency> |
| | | <groupId>javax.xml.bind</groupId> |
| | | <artifactId>jaxb-api</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- <dependency> |
| | | <groupId>org.apache.poi</groupId> |
| | | <artifactId>poi-ooxml</artifactId> |
| | | <version>3.9</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>dom4j</artifactId> |
| | | <groupId>dom4j</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency>--> |
| | | |
| | | <!--腾讯云 cos--> |
| | | <dependency> |
| | | <groupId>com.qcloud</groupId> |
| | | <artifactId>cos_api</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>commons-fileupload</groupId> |
| | | <artifactId>commons-fileupload</artifactId> |
| | | </dependency> |
| | | |
| | | <!--发送邮件--> |
| | | <dependency> |
| | | <groupId>com.sun.mail</groupId> |
| | | <artifactId>javax.mail</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.apache.commons</groupId> |
| | | <artifactId>commons-csv</artifactId> |
| | | <version>1.6</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.aliyun.oss</groupId> |
| | | <artifactId>aliyun-sdk-oss</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.huaweicloud</groupId> |
| | | <artifactId>esdk-obs-java</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --> |
| | | <dependency> |
| | | <groupId>org.bouncycastle</groupId> |
| | | <artifactId>bcprov-jdk15on</artifactId> |
| | | </dependency> |
| | | |
| | | <!--微信支付用到的包--> |
| | | <dependency> |
| | | <groupId>org.dom4j</groupId> |
| | | <artifactId>dom4j</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.jdom</groupId> |
| | | <artifactId>jdom</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.httpcomponents</groupId> |
| | | <artifactId>httpcore</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.httpcomponents</groupId> |
| | | <artifactId>httpclient</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cglib</groupId> |
| | | <artifactId>cglib</artifactId> |
| | | </dependency> |
| | | <!--<dependency> |
| | | <groupId>log4j</groupId> |
| | | <artifactId>log4j</artifactId> |
| | | </dependency>--> |
| | | |
| | | <!--生成二维码支持包--> |
| | | <dependency> |
| | | <groupId>com.google.zxing</groupId> |
| | | <artifactId>core</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>net.glxn</groupId> |
| | | <artifactId>qrgen</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- 字符串工具类jar:StringUtils --> |
| | | <dependency> |
| | | <groupId>org.apache.commons</groupId> |
| | | <artifactId>commons-lang3</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>commons-io</groupId> |
| | | <artifactId>commons-io</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>redis.clients</groupId> |
| | | <artifactId>jedis</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.auth0</groupId> |
| | | <artifactId>java-jwt</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.jsonwebtoken</groupId> |
| | | <artifactId>jjwt</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>javax.servlet.jsp.jstl</groupId> |
| | | <artifactId>jstl-api</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>javax.servlet</groupId> |
| | | <artifactId>jstl</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-tomcat</artifactId> |
| | | <!--<scope>provided</scope>--> |
| | | </dependency> |
| | | |
| | | <!-- mybatis自动生成 --> |
| | | <dependency> |
| | | <groupId>com.gitee.sunchenbin.mybatis.actable</groupId> |
| | | <artifactId>mybatis-enhance-actable</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- 模板生成jar --> |
| | | <dependency> |
| | | <groupId>org.freemarker</groupId> |
| | | <artifactId>freemarker</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-redis</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter</artifactId> |
| | | </exclusion> |
| | | <exclusion> |
| | | <groupId>org.slf4j</groupId> |
| | | <artifactId>slf4j-api</artifactId> |
| | | </exclusion> |
| | | <exclusion> |
| | | <groupId>org.slf4j</groupId> |
| | | <artifactId>jcl-over-slf4j</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.hibernate</groupId> |
| | | <artifactId>hibernate-validator</artifactId> |
| | | </exclusion> |
| | | <exclusion> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-tomcat</artifactId> |
| | | </exclusion> |
| | | <exclusion> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-logging</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.mybatis.spring.boot</groupId> |
| | | <artifactId>mybatis-spring-boot-starter</artifactId><exclusions> |
| | | <exclusion> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-logging</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>mysql</groupId> |
| | | <artifactId>mysql-connector-java</artifactId> |
| | | <scope>runtime</scope> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>druid</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>fastjson</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.google.code.gson</groupId> |
| | | <artifactId>gson</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>net.sf.json-lib</groupId> |
| | | <artifactId>json-lib</artifactId> |
| | | <classifier>jdk15</classifier> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.belerweb</groupId> |
| | | <artifactId>pinyin4j</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>net.sourceforge.jexcelapi</groupId> |
| | | <artifactId>jxl</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>commons-beanutils</groupId> |
| | | <artifactId>commons-beanutils</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>commons-logging</artifactId> |
| | | <groupId>commons-logging</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>commons-collections</groupId> |
| | | <artifactId>commons-collections</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>commons-lang</groupId> |
| | | <artifactId>commons-lang</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>net.sf.ezmorph</groupId> |
| | | <artifactId>ezmorph</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>junit</groupId> |
| | | <artifactId>junit</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.pagehelper</groupId> |
| | | <artifactId>pagehelper</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.dtflys.forest</groupId> |
| | | <artifactId>spring-boot-starter-forest</artifactId> |
| | | <version>1.5.0-RC2</version> |
| | | </dependency> |
| | | |
| | | <!-- redis --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- https://mvnrepository.com/artifact/com.monitorjbl/xlsx-streamer --> |
| | | <dependency> |
| | | <groupId>com.monitorjbl</groupId> |
| | | <artifactId>xlsx-streamer</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | <build> |
| | | <finalName>hx-common</finalName> |
| | | <resources> |
| | | <resource> |
| | | <directory>src/main/java</directory> |
| | | <includes> |
| | | <include>**/*.properties</include> |
| | | <include>**/*.xml</include> |
| | | <include>**/*.tld</include> |
| | | <include>**/*.tpl</include> |
| | | </includes> |
| | | <filtering>false</filtering> |
| | | </resource> |
| | | <resource> |
| | | <directory>src/main/resources</directory> |
| | | <excludes> |
| | | <exclude>profile-active/**</exclude> |
| | | </excludes> |
| | | </resource> |
| | | <resource> |
| | | <directory>${runtime.env}</directory> |
| | | </resource> |
| | | </resources> |
| | | </build> |
| | | |
| | | </project> |
New file |
| | |
| | | package com.hx.annotation; |
| | | |
| | | import java.lang.annotation.Documented; |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Inherited; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | |
| | | /**权限注解 |
| | | * @author chenjiahe |
| | | * @version 2019年09月14日 下午6:13:37 |
| | | */ |
| | | //表示注解加在接口、类、枚举等 |
| | | @Target(ElementType.METHOD) |
| | | //VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息 |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | //将此注解包含在javadoc中 |
| | | @Documented |
| | | //允许子类继承父类中的注解 |
| | | @Inherited |
| | | public @interface Jurisdiction { |
| | | /**权限名*/ |
| | | String privilege(); |
| | | } |
New file |
| | |
| | | package com.hx.api; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.dtflys.forest.annotation.DataVariable; |
| | | import com.dtflys.forest.annotation.JSONBody; |
| | | import com.dtflys.forest.annotation.Post; |
| | | |
| | | /** |
| | | * 企业微信微盘接口API |
| | | * @Author: cmg |
| | | * @Date: 2023-7-13 11:08 |
| | | */ |
| | | public interface CorpMpSpaceApi { |
| | | |
| | | /** |
| | | * 增加空间 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/space_create?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject addSpace(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 重命名空间 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/space_rename?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject renameSpace(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 解散空间 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/space_dismiss?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject dismissSpace(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 空间安全设置 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/space_setting?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject spaceSetting(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 新建文件夹/文档 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_create?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject createFile(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 文件重命名 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_rename?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject renameFile(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 移除文件 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_delete?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject deleteFile(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 分块上传初始化 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_upload_init?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject fileUploadInit(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 分块上传文件 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_upload_part?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject fileUploadPart(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 分块上传完成 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_upload_finish?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject fileUploadFinish(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 上传文件 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_upload?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject fileUpload(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 删除文件 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_delete?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject fileDelete(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | |
| | | /** |
| | | * 获取下载路径 |
| | | * @param accessToken |
| | | * @param param |
| | | * @return |
| | | */ |
| | | @Post( |
| | | url = "https://qyapi.weixin.qq.com/cgi-bin/wedrive/file_download?access_token=${accessToken}", |
| | | headers = { |
| | | "Content-Type: application/json" |
| | | } |
| | | ) |
| | | JSONObject getDownloadUrl(@DataVariable("accessToken") String accessToken, @JSONBody String param); |
| | | } |
New file |
| | |
| | | package com.hx.bean.annotations; |
| | | |
| | | import com.hx.mybatis.aes.springbean.ConstantBean; |
| | | import com.hx.mybatis.aes.springbean.InitMysqlData; |
| | | import com.hx.mybatis.aes.springbean.MySqlInterceptor; |
| | | import com.hx.mybatis.aes.springbean.VariableAesKey; |
| | | import com.hx.security.request.RequestRestriction; |
| | | import org.springframework.context.annotation.Import; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /**自动加Mysql的AES加密程序 |
| | | *这里的Import的两个类就是需要加载的bean,这样就可以通过简单的添加一个注解来加载自己自定义的bean了,而且可 |
| | | *以是很多个,可以打到jar包里面通过Maven引入都是ok的; |
| | | * @author CJH |
| | | * @date 202-06-17 |
| | | */ |
| | | @Target(ElementType.TYPE) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | @Import({ConstantBean.class, InitMysqlData.class, MySqlInterceptor.class, VariableAesKey.class}) |
| | | public @interface MysqlAutoAes { |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.bean.annotations; |
| | | |
| | | import com.hx.mybatis.aes.springbean.ConstantBean; |
| | | import com.hx.mybatis.aes.springbean.InitMysqlData; |
| | | import com.hx.mybatis.aes.springbean.MySqlInterceptor; |
| | | import com.hx.mybatis.aes.springbean.VariableAesKey; |
| | | import com.hx.redis.RedisConfig; |
| | | import com.hx.redis.RedisUtil; |
| | | import org.springframework.context.annotation.Import; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /**使用redis链接 |
| | | *这里的Import的两个类就是需要加载的bean,这样就可以通过简单的添加一个注解来加载自己自定义的bean了,而且可 |
| | | *以是很多个,可以打到jar包里面通过Maven引入都是ok的; |
| | | * @author CJH |
| | | * @date 202-06-17 |
| | | */ |
| | | @Target(ElementType.TYPE) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | @Import({RedisConfig.class, RedisUtil.class}) |
| | | public @interface RedisClient { |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.bean.annotations; |
| | | |
| | | import com.hx.security.request.RequestRestriction; |
| | | import org.springframework.context.annotation.Import; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /**请求安全bean加载 |
| | | *这里的Import的两个类就是需要加载的bean,这样就可以通过简单的添加一个注解来加载自己自定义的bean了,而且可 |
| | | *以是很多个,可以打到jar包里面通过Maven引入都是ok的; |
| | | * @author CJH |
| | | * @date 202-06-17 |
| | | */ |
| | | @Target(ElementType.TYPE) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | @Import({RequestRestriction.class}) |
| | | public @interface RequestSecurity { |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.common; |
| | | |
| | | import com.hx.common.service.CommonService; |
| | | import com.hx.exception.ParamException; |
| | | import com.hx.exception.ServiceException; |
| | | import org.springframework.beans.propertyeditors.CustomDateEditor; |
| | | import org.springframework.web.bind.WebDataBinder; |
| | | import org.springframework.web.bind.annotation.InitBinder; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | import org.springframework.web.context.request.WebRequest; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpSession; |
| | | import java.text.DateFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /**公共初始化 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-06-11 |
| | | */ |
| | | |
| | | public class BaseController { |
| | | |
| | | @Resource |
| | | protected CommonService commonService; |
| | | /*请不要声明变量,会导致不安全,因为这个是单列*/ |
| | | |
| | | //只需要加上下面这段即可,注意不能忘记注解 |
| | | @InitBinder |
| | | public void initBinder(WebDataBinder binder, WebRequest request) { |
| | | //转换日期 注意这里的转化要和传进来的字符串的格式一直 如2015-9-9 就应该为yyyy-MM-dd |
| | | DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));// CustomDateEditor为自定义日期编辑器 |
| | | } |
| | | |
| | | public HttpServletRequest getRequest() { |
| | | //获取参数对象 |
| | | ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
| | | return attributes.getRequest(); |
| | | } |
| | | |
| | | public HttpSession getSession() { |
| | | //获取参数对象 |
| | | return getRequest() .getSession(); |
| | | } |
| | | |
| | | /** |
| | | * 获取request里某个属性 |
| | | * @param attrName 属性名称 |
| | | * @return 对象 |
| | | */ |
| | | public Object getRequestAttribute(String attrName) |
| | | { |
| | | return getRequest().getAttribute(attrName); |
| | | } |
| | | |
| | | /** |
| | | * 设置一个request属性 |
| | | * @param attrName 属性名称 |
| | | * @param attrObject 属性值 |
| | | */ |
| | | public void setRequestAttribute(String attrName, Object attrObject) { |
| | | getRequest().setAttribute(attrName, attrObject); |
| | | } |
| | | |
| | | /** |
| | | * 抛出服务异常 |
| | | * @param msg 错误信息 |
| | | */ |
| | | public void throwServiceException(String msg) |
| | | { |
| | | throw new ServiceException(msg); |
| | | } |
| | | |
| | | /** |
| | | * 抛出参数异常 |
| | | * @param msg 错误信息 |
| | | */ |
| | | public void throwParamException(String msg) |
| | | { |
| | | throw new ParamException(msg); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.common.annotations; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 指定mysql的AES加密字段 |
| | | * @author CJH |
| | | */ |
| | | @Target({ElementType.FIELD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface MysqlHexAes { |
| | | /**秘钥-没有就是配置文件设置*/ |
| | | String aesKey() default ""; |
| | | /**数据库数据初始化版本*/ |
| | | String initVersion() default ""; |
| | | /**xml生成查询解密*/ |
| | | boolean selectDec() default false; |
| | | /**xml更新加密*/ |
| | | boolean updateDec() default false; |
| | | /**xml新增加密*/ |
| | | boolean insertDec() default false; |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.common.annotations.repeat; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 重复校验注解 |
| | | * @author CJH |
| | | */ |
| | | @Target({ElementType.TYPE, ElementType.METHOD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface RequestRepeat { |
| | | /**是否重复校验,默认true*/ |
| | | boolean isRepeat() default true; |
| | | /**重复间隔时间,毫秒,默认1000毫秒*/ |
| | | long millisecond() default 1000; |
| | | } |
New file |
| | |
| | | package com.hx.common.dao; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | /** |
| | | * dao通用接口 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-10-14 |
| | | */ |
| | | public interface CommonDao { |
| | | |
| | | /**新增,返回主键 |
| | | * @param mapperClass mapper类 |
| | | * @param entity 实体类 |
| | | * @return 条数 |
| | | */ |
| | | <T extends Serializable> int insert(Class<?> mapperClass, T entity); |
| | | |
| | | /**新增,返回主键 |
| | | * @param mapperClass mapper类 |
| | | * @param entity 实体类 |
| | | * @return 条数 |
| | | */ |
| | | <T extends Serializable> int insertById(Class<?> mapperClass, T entity); |
| | | |
| | | /**查询条数 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int selectCount(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询条数 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int selectCountSql(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询列表,返回实体类的List |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回list |
| | | */ |
| | | <T extends Serializable> List<T> selectList(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询列表,返回Map的List |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return Map的List |
| | | */ |
| | | <T extends Serializable> List<Map<String,Object>> selectListMap(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询,返回单个实体 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> T selectOne(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询,返回单个map |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> Map<String,Object> selectOneMap(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询,返回实体类没有大数据的 |
| | | * @param mapperClass mapper类 |
| | | * @param object 数据标识key |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> T selectOneByKey(Class<?> mapperClass, Object object); |
| | | |
| | | /**查询,返回实体类有大数据的 |
| | | * @param mapperClass mapper类 |
| | | * @param object 数据标识key |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> T selectOneByKeyBlob(Class<?> mapperClass, Object object); |
| | | |
| | | /**更新,返回更新数量 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int updateWhere(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**更新,返回更新数量 |
| | | * @param mapperClass mapper类 |
| | | * @param entity 实体类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int updateAll(Class<?> mapperClass, T entity); |
| | | |
| | | /**删除,返回删除数量 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int deleteWhere(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**删除,返回删除数量 |
| | | * @param mapperClass mapper类 |
| | | * @param object 数据标识key |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int deleteById(Class<?> mapperClass, Object object); |
| | | |
| | | /**更新sql语句(全语句) |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int updateSentence( SqlSentence sqlSentence); |
| | | |
| | | /**查询条数语句(全语句) |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int selectCountSql( SqlSentence sqlSentence); |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.common.dao.mapper; |
| | | |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface CommonMapper { |
| | | |
| | | /**更新,返回更新数量*/ |
| | | int updateSentence(SqlSentence sqlSentence); |
| | | |
| | | /**查询列表,返回Map的List*/ |
| | | List<Map<String,Object>> selectListMap(SqlSentence sqlSentence); |
| | | |
| | | /**查询,返回条数数量*/ |
| | | int selectCountSql(SqlSentence sqlSentence); |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.common.service; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | /** |
| | | * dao通用接口 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-10-14 |
| | | */ |
| | | public interface CommonService { |
| | | |
| | | /**新增,返回主键 |
| | | * @param mapperClass mapper类 |
| | | * @param entity 实体类 |
| | | * @return 条数 |
| | | */ |
| | | <T extends Serializable> int insert(Class<?> mapperClass, T entity); |
| | | |
| | | /**新增,返回主键 |
| | | * @param mapperClass mapper类 |
| | | * @param entity 实体类 |
| | | * @return 条数 |
| | | */ |
| | | <T extends Serializable> int insertById(Class<?> mapperClass, T entity); |
| | | |
| | | /**查询条数 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int selectCount(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询条数 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int selectCountSql(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | |
| | | /**查询列表,返回实体类的List |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回list |
| | | */ |
| | | <T extends Serializable> List<T> selectList(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询列表,返回Map的List |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return Map的List |
| | | */ |
| | | <T extends Serializable> List<Map<String,Object>> selectListMap(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询,返回单个实体 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> T selectOne(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询,返回单个map |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> Map<String,Object> selectOneMap(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**查询,返回实体类没有大数据的 |
| | | * @param mapperClass mapper类 |
| | | * @param object 数据标识key |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> T selectOneByKey(Class<?> mapperClass, Object object); |
| | | |
| | | /**查询,返回实体类有大数据的 |
| | | * @param mapperClass mapper类 |
| | | * @param object 数据标识key |
| | | * @return 返回实体类 |
| | | */ |
| | | <T extends Serializable> T selectOneByKeyBlob(Class<?> mapperClass, Object object); |
| | | |
| | | /**更新,返回更新数量 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int updateWhere(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**更新,返回更新数量 |
| | | * @param mapperClass mapper类 |
| | | * @param entity 实体类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int updateAll(Class<?> mapperClass, T entity); |
| | | |
| | | /**删除,返回删除数量 |
| | | * @param mapperClass mapper类 |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int deleteWhere(Class<?> mapperClass, SqlSentence sqlSentence); |
| | | |
| | | /**删除,返回删除数量 |
| | | * @param mapperClass mapper类 |
| | | * @param object 数据标识key |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int deleteById(Class<?> mapperClass, Object object); |
| | | |
| | | /**更新sql语句(全语句) |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int updateSentence(SqlSentence sqlSentence); |
| | | |
| | | /**查询条数语句(全语句) |
| | | * @param sqlSentence 查询参数类 |
| | | * @return 返回条数 |
| | | */ |
| | | <T extends Serializable> int selectCountSql(SqlSentence sqlSentence); |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.common.service.impl; |
| | | |
| | | import com.hx.common.dao.CommonDao; |
| | | import com.hx.common.dao.mapper.CommonMapper; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import org.apache.ibatis.session.SqlSessionFactory; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /**当前是没有事务处理,切勿直接使用*/ |
| | | @Service |
| | | public class CommonDaoImpl implements CommonDao { |
| | | |
| | | @Resource(name = "sqlSessionFactory") |
| | | protected SqlSessionFactory sqlSessionFactory; |
| | | |
| | | /**组拼XML文件sql的id*/ |
| | | private <T> String getStatement(Class<T> clazz, String prefix){ |
| | | return clazz.getName()+"."+prefix; |
| | | } |
| | | |
| | | /**插入*/ |
| | | @Override |
| | | public <T extends Serializable> int insert(Class<?> mapperClass,T entity) { |
| | | return sqlSessionFactory.openSession().insert(getStatement(mapperClass,"insert"),entity); |
| | | } |
| | | |
| | | @Override |
| | | public <T extends Serializable> int insertById(Class<?> mapperClass, T entity) { |
| | | return sqlSessionFactory.openSession().insert(getStatement(mapperClass,"insertById"),entity); |
| | | } |
| | | |
| | | /**获取条数 |
| | | * @return*/ |
| | | @Override |
| | | public <T extends Serializable> int selectCount(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().selectOne(getStatement(mapperClass,"selectCount"),sqlSentence); |
| | | } |
| | | |
| | | /**获取条数 |
| | | * @return*/ |
| | | @Override |
| | | public <T extends Serializable> int selectCountSql(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().selectOne(getStatement(mapperClass,"selectCountSql"),sqlSentence); |
| | | } |
| | | |
| | | /**获取列表*/ |
| | | @Override |
| | | public <T extends Serializable> List<T> selectList(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().selectList(getStatement(mapperClass,"selectList"),sqlSentence); |
| | | } |
| | | |
| | | /**获取列表*/ |
| | | @Override |
| | | public <T extends Serializable> List<Map<String, Object>> selectListMap(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().selectList(getStatement(mapperClass,"selectListMap"),sqlSentence); |
| | | } |
| | | |
| | | /**获取单条数据*/ |
| | | @Override |
| | | public <T extends Serializable> T selectOne(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().selectOne(getStatement(mapperClass,"selectOne"),sqlSentence); |
| | | } |
| | | |
| | | /**获取单条数据*/ |
| | | @Override |
| | | public <T extends Serializable> Map<String, Object> selectOneMap(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().selectOne(getStatement(mapperClass,"selectOneMap"),sqlSentence); |
| | | } |
| | | |
| | | /**获取单条数据-不含longText的数据*/ |
| | | @Override |
| | | public <T extends Serializable> T selectOneByKey(Class<?> mapperClass,Object object) { |
| | | return sqlSessionFactory.openSession().selectOne(getStatement(mapperClass,"selectOneByKey"),object); |
| | | } |
| | | |
| | | /**获取单条数据-含longText的数据*/ |
| | | @Override |
| | | public <T extends Serializable> T selectOneByKeyBlob(Class<?> mapperClass,Object object) { |
| | | return sqlSessionFactory.openSession().selectOne(getStatement(mapperClass,"selectOneByKeyBlob"),object); |
| | | } |
| | | |
| | | /**更新*/ |
| | | @Override |
| | | public <T extends Serializable> int updateWhere(Class<?> mapperClass,SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().update(getStatement(mapperClass,"updateWhere"),sqlSentence); |
| | | } |
| | | |
| | | /**全部字段更新*/ |
| | | @Override |
| | | public <T extends Serializable> int updateAll(Class<?> mapperClass,T entity) { |
| | | return sqlSessionFactory.openSession().update(getStatement(mapperClass,"updateAll"),entity); |
| | | } |
| | | |
| | | /**删除*/ |
| | | @Override |
| | | public <T extends Serializable> int deleteWhere(Class<?> mapperClass,SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().delete(getStatement(mapperClass,"deleteWhere"),sqlSentence); |
| | | } |
| | | |
| | | /**删除*/ |
| | | @Override |
| | | public <T extends Serializable> int deleteById(Class<?> mapperClass,Object object) { |
| | | return sqlSessionFactory.openSession().delete(getStatement(mapperClass,"deleteById"),object); |
| | | } |
| | | |
| | | /**更新sql语句(全语句)*/ |
| | | @Override |
| | | public <T extends Serializable> int updateSentence(SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().update(getStatement(CommonMapper.class,"updateSentence"),sqlSentence); |
| | | } |
| | | |
| | | /**查询条数(全语句)*/ |
| | | @Override |
| | | public <T extends Serializable> int selectCountSql(SqlSentence sqlSentence) { |
| | | return sqlSessionFactory.openSession().selectOne(getStatement(CommonMapper.class,"selectCountSql"),sqlSentence); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.common.service.impl; |
| | | |
| | | import com.hx.common.dao.CommonDao; |
| | | import com.hx.common.service.CommonService; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /**当前是有事务处理*/ |
| | | @Transactional |
| | | @Service |
| | | public class CommonServiceImpl implements CommonService { |
| | | |
| | | @Resource |
| | | private CommonDao commonDao; |
| | | |
| | | /**插入*/ |
| | | @Override |
| | | public <T extends Serializable> int insert(Class<?> mapperClass,T entity) { |
| | | return commonDao.insert(mapperClass,entity); |
| | | } |
| | | |
| | | @Override |
| | | public <T extends Serializable> int insertById(Class<?> mapperClass, T entity) { |
| | | return commonDao.insertById(mapperClass,entity); |
| | | } |
| | | |
| | | /**获取条数*/ |
| | | @Override |
| | | public <T extends Serializable> int selectCount(Class<?> mapperClass,SqlSentence sqlSentence) { |
| | | return commonDao.selectCount(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**获取条数*/ |
| | | @Override |
| | | public <T extends Serializable> int selectCountSql(Class<?> mapperClass,SqlSentence sqlSentence) { |
| | | return commonDao.selectCountSql(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**获取列表*/ |
| | | @Override |
| | | public <T extends Serializable> List<T> selectList(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return commonDao.selectList(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**获取列表*/ |
| | | @Override |
| | | public <T extends Serializable> List<Map<String, Object>> selectListMap(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return commonDao.selectListMap(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**获取单条数据*/ |
| | | @Override |
| | | public <T extends Serializable> T selectOne(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return commonDao.selectOne(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**获取单条数据*/ |
| | | @Override |
| | | public <T extends Serializable> Map<String, Object> selectOneMap(Class<?> mapperClass, SqlSentence sqlSentence) { |
| | | return commonDao.selectOneMap(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**获取单条数据-不含longText的数据*/ |
| | | @Override |
| | | public <T extends Serializable> T selectOneByKey(Class<?> mapperClass,Object object) { |
| | | return commonDao.selectOneByKey(mapperClass,object); |
| | | } |
| | | |
| | | /**获取单条数据-含longText的数据*/ |
| | | @Override |
| | | public <T extends Serializable> T selectOneByKeyBlob(Class<?> mapperClass,Object object) { |
| | | return commonDao.selectOneByKeyBlob(mapperClass,object); |
| | | } |
| | | |
| | | /**更新*/ |
| | | @Override |
| | | public <T extends Serializable> int updateWhere(Class<?> mapperClass,SqlSentence sqlSentence) { |
| | | return commonDao.updateWhere(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**全部字段更新*/ |
| | | @Override |
| | | public <T extends Serializable> int updateAll(Class<?> mapperClass,T entity) { |
| | | return commonDao.updateAll(mapperClass,entity); |
| | | } |
| | | |
| | | /**删除*/ |
| | | @Override |
| | | public <T extends Serializable> int deleteWhere(Class<?> mapperClass,SqlSentence sqlSentence) { |
| | | return commonDao.deleteWhere(mapperClass,sqlSentence); |
| | | } |
| | | |
| | | /**删除*/ |
| | | @Override |
| | | public <T extends Serializable> int deleteById(Class<?> mapperClass,Object object) { |
| | | return commonDao.deleteById(mapperClass,object); |
| | | } |
| | | |
| | | |
| | | /**更新sql语句(全语句)*/ |
| | | @Override |
| | | public <T extends Serializable> int updateSentence(SqlSentence sqlSentence) { |
| | | return commonDao.updateSentence(sqlSentence); |
| | | } |
| | | |
| | | /**更新sql语句(全语句)*/ |
| | | @Override |
| | | public <T extends Serializable> int selectCountSql(SqlSentence sqlSentence) { |
| | | return commonDao.selectCountSql(sqlSentence); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <!-- namespace:该mapper.xml映射文件的 唯一标识 --> |
| | | <mapper namespace="com.hx.common.dao.mapper.CommonMapper"> |
| | | <update id="updateSentence" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </update> |
| | | |
| | | <select id="selectListMap" resultType="java.util.Map" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | <select id="selectCountSql" resultType="int" parameterType="com.hx.mybatisTool.SqlSentence" > |
| | | ${sqlSentence} |
| | | </select> |
| | | |
| | | </mapper> |
New file |
| | |
| | | package com.hx.corp.entity; |
| | | |
| | | import java.util.UUID; |
| | | |
| | | /**企业付款请求参数实体 |
| | | * |
| | | */ |
| | | public class CorpPayRequest { |
| | | |
| | | /*(Y)商户账号appid,申请商户号的appid或商户号绑定的appid*/ |
| | | private String mch_appid; |
| | | /*(Y)商户号*/ |
| | | private String mchid; |
| | | /*(N)设备号*/ |
| | | private String device_info; |
| | | /*(Y)随机字符串*/ |
| | | private String nonce_str = UUID.randomUUID().toString().substring(0, 30); |
| | | /*(Y)随签名*/ |
| | | private String sign; |
| | | /*(Y)商户订单号*/ |
| | | private String partner_trade_no; |
| | | /*(Y)用户openid*/ |
| | | private String openid; |
| | | /*(Y)校验用户姓名选项,NO_CHECK:不校验真实姓名 ;FORCE_CHECK:强校验真实姓名*/ |
| | | private String check_name = "NO_CHECK"; |
| | | /*(O)收款用户姓名,如果check_name设置为FORCE_CHECK,则必填用户真实姓名*/ |
| | | private String re_user_name; |
| | | /*(Y)金额*/ |
| | | private Integer amount; |
| | | /*(Y)企业付款备注*/ |
| | | private String desc; |
| | | /*(N)Ip地址,该IP同在商户平台设置的IP白名单中的IP没有关联,该IP可传用户端或者服务端的IP*/ |
| | | private String spbill_create_ip = "8.8.8.8"; |
| | | |
| | | public CorpPayRequest() { |
| | | } |
| | | |
| | | //////////////////////////////////////////////////////// |
| | | |
| | | public String getMch_appid() { |
| | | return mch_appid; |
| | | } |
| | | |
| | | public void setMch_appid(String mch_appid) { |
| | | this.mch_appid = mch_appid; |
| | | } |
| | | |
| | | public String getMchid() { |
| | | return mchid; |
| | | } |
| | | |
| | | public void setMchid(String mchid) { |
| | | this.mchid = mchid; |
| | | } |
| | | |
| | | public String getDevice_info() { |
| | | return device_info; |
| | | } |
| | | |
| | | public void setDevice_info(String device_info) { |
| | | this.device_info = device_info; |
| | | } |
| | | |
| | | public String getSign() { |
| | | return sign; |
| | | } |
| | | |
| | | public void setSign(String sign) { |
| | | this.sign = sign; |
| | | } |
| | | |
| | | public String getPartner_trade_no() { |
| | | return partner_trade_no; |
| | | } |
| | | |
| | | public void setPartner_trade_no(String partner_trade_no) { |
| | | this.partner_trade_no = partner_trade_no; |
| | | } |
| | | |
| | | public String getOpenid() { |
| | | return openid; |
| | | } |
| | | |
| | | public void setOpenid(String openid) { |
| | | this.openid = openid; |
| | | } |
| | | |
| | | public String getCheck_name() { |
| | | return check_name; |
| | | } |
| | | |
| | | public void setCheck_name(String check_name) { |
| | | this.check_name = check_name; |
| | | } |
| | | |
| | | public String getRe_user_name() { |
| | | return re_user_name; |
| | | } |
| | | |
| | | public void setRe_user_name(String re_user_name) { |
| | | this.re_user_name = re_user_name; |
| | | } |
| | | |
| | | public Integer getAmount() { |
| | | return amount; |
| | | } |
| | | |
| | | public void setAmount(Integer amount) { |
| | | this.amount = amount; |
| | | } |
| | | |
| | | public String getDesc() { |
| | | return desc; |
| | | } |
| | | |
| | | public void setDesc(String desc) { |
| | | this.desc = desc; |
| | | } |
| | | |
| | | public String getSpbill_create_ip() { |
| | | return spbill_create_ip; |
| | | } |
| | | |
| | | public void setSpbill_create_ip(String spbill_create_ip) { |
| | | this.spbill_create_ip = spbill_create_ip; |
| | | } |
| | | |
| | | public String getNonce_str() { |
| | | return nonce_str; |
| | | } |
| | | |
| | | public void setNonce_str(String nonce_str) { |
| | | this.nonce_str = nonce_str; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.corp.entity; |
| | | |
| | | /**企业付款返回参数实体 |
| | | * |
| | | */ |
| | | public class CorpPayResponse { |
| | | |
| | | /*(Y)业务结果,SUCCESS/FAIL,注意:当状态为FAIL时,存在业务结果未明确的情况。如果状态为FAIL,请务必关注错误代码(err_code字段),通过查询接口确认此次付款的结果*/ |
| | | private String result_code = "FAIL"; |
| | | /*(Y)返回状态码,SUCCESS/FAIL,此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断*/ |
| | | private String return_code = "FAIL"; |
| | | /*(Y) 返回信息 */ |
| | | private String return_msg; |
| | | /*(Y)错误代码*/ |
| | | private String err_code; |
| | | /*(Y)错误代码描述*/ |
| | | private String err_code_des; |
| | | /*(Y)商户appid*/ |
| | | private String mch_appid; |
| | | /*(Y)商户号*/ |
| | | private String mchid; |
| | | /*(N)设备号*/ |
| | | private String device_info; |
| | | /*(Y)随机字符串*/ |
| | | private String nonce_str; |
| | | |
| | | //以下字段在return_code 和result_code都为SUCCESS的时候有返回 |
| | | /*(O)商户订单号*/ |
| | | private String partner_trade_no; |
| | | /*(O)商户订单号*/ |
| | | private String payment_no; |
| | | /*(O)付款成功时间*/ |
| | | private String payment_time; |
| | | |
| | | |
| | | public CorpPayResponse() { |
| | | } |
| | | |
| | | public static final String CODE_SUC = "SUCCESS"; |
| | | public static final String CODE_FAIL = "FAIL"; |
| | | |
| | | //////////////////////////////////////////////////////// |
| | | |
| | | public String getMch_appid() { |
| | | return mch_appid; |
| | | } |
| | | |
| | | public void setMch_appid(String mch_appid) { |
| | | this.mch_appid = mch_appid; |
| | | } |
| | | |
| | | public String getMchid() { |
| | | return mchid; |
| | | } |
| | | |
| | | public void setMchid(String mchid) { |
| | | this.mchid = mchid; |
| | | } |
| | | |
| | | public String getDevice_info() { |
| | | return device_info; |
| | | } |
| | | |
| | | public void setDevice_info(String device_info) { |
| | | this.device_info = device_info; |
| | | } |
| | | |
| | | public String getResult_code() { |
| | | return result_code; |
| | | } |
| | | |
| | | public void setResult_code(String result_code) { |
| | | this.result_code = result_code; |
| | | } |
| | | |
| | | public String getErr_code() { |
| | | return err_code; |
| | | } |
| | | |
| | | public void setErr_code(String err_code) { |
| | | this.err_code = err_code; |
| | | } |
| | | |
| | | public String getErr_code_des() { |
| | | return err_code_des; |
| | | } |
| | | |
| | | public void setErr_code_des(String err_code_des) { |
| | | this.err_code_des = err_code_des; |
| | | } |
| | | |
| | | public String getNonce_str() { |
| | | return nonce_str; |
| | | } |
| | | |
| | | public void setNonce_str(String nonce_str) { |
| | | this.nonce_str = nonce_str; |
| | | } |
| | | |
| | | public String getPartner_trade_no() { |
| | | return partner_trade_no; |
| | | } |
| | | |
| | | public void setPartner_trade_no(String partner_trade_no) { |
| | | this.partner_trade_no = partner_trade_no; |
| | | } |
| | | |
| | | public String getPayment_no() { |
| | | return payment_no; |
| | | } |
| | | |
| | | public void setPayment_no(String payment_no) { |
| | | this.payment_no = payment_no; |
| | | } |
| | | |
| | | public String getPayment_time() { |
| | | return payment_time; |
| | | } |
| | | |
| | | public void setPayment_time(String payment_time) { |
| | | this.payment_time = payment_time; |
| | | } |
| | | |
| | | public String getReturn_code() { |
| | | return return_code; |
| | | } |
| | | |
| | | public void setReturn_code(String return_code) { |
| | | this.return_code = return_code; |
| | | } |
| | | |
| | | public String getReturn_msg() { |
| | | return return_msg; |
| | | } |
| | | |
| | | public void setReturn_msg(String return_msg) { |
| | | this.return_msg = return_msg; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "CorpPayResponse{" + |
| | | "result_code='" + result_code + '\'' + |
| | | ", return_code='" + return_code + '\'' + |
| | | ", return_msg='" + return_msg + '\'' + |
| | | ", err_code='" + err_code + '\'' + |
| | | ", err_code_des='" + err_code_des + '\'' + |
| | | ", mch_appid='" + mch_appid + '\'' + |
| | | ", mchid='" + mchid + '\'' + |
| | | ", device_info='" + device_info + '\'' + |
| | | ", nonce_str='" + nonce_str + '\'' + |
| | | ", partner_trade_no='" + partner_trade_no + '\'' + |
| | | ", payment_no='" + payment_no + '\'' + |
| | | ", payment_time='" + payment_time + '\'' + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.corp.util; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.hx.util.corp.entity.AppLetInfo; |
| | | import com.hx.corp.entity.CorpPayRequest; |
| | | import com.hx.corp.entity.CorpPayResponse; |
| | | import com.hx.exception.ServiceException; |
| | | import com.hx.mp.util.*; |
| | | import com.hx.util.HttpMethodUtil; |
| | | import com.hx.util.SimpleTool; |
| | | import com.hx.util.StringUtils; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.http.HttpEntity; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpPost; |
| | | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
| | | import org.apache.http.entity.StringEntity; |
| | | import org.apache.http.impl.client.CloseableHttpClient; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | import org.apache.http.ssl.SSLContexts; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.dom4j.Document; |
| | | import org.dom4j.Element; |
| | | import org.dom4j.io.SAXReader; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.security.KeyStore; |
| | | import java.util.*; |
| | | |
| | | |
| | | /** 企业微信支付/退款 |
| | | * @author ChenJiaHe |
| | | */ |
| | | public class WxCorpPayUtil { |
| | | |
| | | //log4j日志 |
| | | private static Logger logger = LoggerFactory.getLogger(WxCorpPayUtil.class.getName()); |
| | | |
| | | // 退款接口连接 |
| | | private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund"; |
| | | /**查询订单链接*/ |
| | | @SuppressWarnings("unused") |
| | | private static final String QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; |
| | | /**同意下单链接*/ |
| | | private static final String FIRST_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; |
| | | |
| | | // 企业付款 |
| | | private static final String CORP_PAY_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; |
| | | |
| | | |
| | | /** 企业付款 |
| | | * @param corpPayRequest 请求对象 |
| | | * @param mchKey 商户号秘钥 |
| | | * @param certPath 支付证书 |
| | | * @return CorpPayResponse |
| | | * @throws Exception |
| | | */ |
| | | public static CorpPayResponse qdCorpPay(CorpPayRequest corpPayRequest, String mchKey, String certPath) |
| | | throws Exception { |
| | | |
| | | CorpPayResponse corpPayResponse = new CorpPayResponse(); |
| | | |
| | | SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); |
| | | parameters.put("mch_appid", corpPayRequest.getMch_appid()); |
| | | parameters.put("mchid", corpPayRequest.getMchid()); |
| | | parameters.put("partner_trade_no", corpPayRequest.getPartner_trade_no()); |
| | | //parameters.put("nonce_str", UUID.randomUUID().toString().substring(0, 30)); |
| | | parameters.put("nonce_str", corpPayRequest.getNonce_str()); |
| | | parameters.put("openid", corpPayRequest.getOpenid()); |
| | | parameters.put("check_name", corpPayRequest.getCheck_name()); |
| | | parameters.put("amount", corpPayRequest.getAmount().toString()); |
| | | parameters.put("spbill_create_ip", corpPayRequest.getSpbill_create_ip()); |
| | | parameters.put("desc", corpPayRequest.getDesc()); |
| | | |
| | | corpPayRequest.setSign(WXSignUtils.createSign("UTF-8", parameters, mchKey)); |
| | | parameters.put("sign", corpPayRequest.getSign()); |
| | | String xmlInfo = HttpXmlUtils.transferXml(parameters); |
| | | try { |
| | | CloseableHttpResponse response = HttpUtil.Post(CORP_PAY_URL, xmlInfo, true, certPath, corpPayRequest.getMchid()); |
| | | String transfersXml = EntityUtils.toString(response.getEntity(), "utf-8"); |
| | | |
| | | //Map<String, String> transferMap = HttpXmlUtils.parseRefundXml(transfersXml); |
| | | |
| | | Map<String,Object> transferMap = XMLUtil.doXMLParse(transfersXml); |
| | | |
| | | // 将 Map 转换为 实体类 |
| | | corpPayResponse = JSON.parseObject(JSON.toJSONString(transferMap),CorpPayResponse.class); |
| | | } catch (Exception e) { |
| | | logger.error("企业付款接口报错",e); |
| | | } |
| | | return corpPayResponse; |
| | | } |
| | | |
| | | |
| | | /**统一支付 |
| | | * @param request 方法获取 |
| | | * @param appId 小程序号 |
| | | * @param partner 商户号 |
| | | * @param key 秘钥 |
| | | * @param notifyUrl 回调链接 |
| | | * @param out_trade_no 订单号 |
| | | * @param body 商品描述 |
| | | * @param total_fee 支付金额 |
| | | * @param openid 用户openId |
| | | * @param attach 附带数据包 |
| | | * @param notifyUrl 回调通知地址 |
| | | * @param trade_type 交易类型 |
| | | * @return JSON status = "SUC"为成功 |
| | | */ |
| | | public static JSONObject unifiedPay(HttpServletRequest request,String appId,String partner,String key,String notifyUrl,String out_trade_no, String body, String total_fee, String openid, |
| | | String attach,String trade_type) throws Exception { |
| | | |
| | | if (!SimpleTool.checkNotNull(notifyUrl)) { |
| | | throw new ServiceException("支付功能故障!"); |
| | | } |
| | | |
| | | // 创建查询请求对象 |
| | | RequestHandler reqHandler = new RequestHandler(null, null); |
| | | // 通信对象 |
| | | TenpayHttpClient httpClient = new TenpayHttpClient(); |
| | | // 应答对象 |
| | | ClientResponseHandler resHandler = new ClientResponseHandler(); |
| | | |
| | | // ----------------------------- |
| | | // 设置请求参数 |
| | | // ----------------------------- |
| | | // reqHandler.init(); |
| | | reqHandler.setKey(key); |
| | | reqHandler.setGateUrl(FIRST_ORDER_URL);// 请求URL |
| | | |
| | | // ----------------------------- |
| | | // 设置接口参数(sign后台自动生成) |
| | | // ----------------------------- |
| | | reqHandler.setParameter("appid", appId); // 公众号/小程序 |
| | | reqHandler.setParameter("mch_id", partner); // 商户号 |
| | | reqHandler.setParameter("nonce_str", SimpleTool.getUUIDName().substring(0, 30));// 随机乱码 |
| | | reqHandler.setParameter("body", body);// 商品描述 |
| | | reqHandler.setParameter("out_trade_no", out_trade_no);// 商户订单号 |
| | | reqHandler.setParameter("total_fee", total_fee);// 总金额 |
| | | reqHandler.setParameter("spbill_create_ip", "8.8.8.8");// 终端IP |
| | | reqHandler.setParameter("notify_url",notifyUrl);// 通知地址 |
| | | reqHandler.setParameter("trade_type", trade_type);// 交易类型 |
| | | // JSAPI,NATIVE,APP |
| | | reqHandler.setParameter("openid", openid);// openId |
| | | reqHandler.setParameter("attach", attach);// 附带数据包 |
| | | |
| | | // ----------------------------- |
| | | // 设置通信参数 |
| | | // ----------------------------- |
| | | // 设置请求返回的等待时间 |
| | | httpClient.setTimeOut(5); |
| | | |
| | | // 设置ca证书 |
| | | // httpClient.setCaInfo(new File(CA_PATH)); |
| | | |
| | | // 设置个人(商户)证书 |
| | | // httpClient.setCertInfo(new File(CERT_PATH), CERT_PWD); |
| | | |
| | | // 设置发送类型POST |
| | | httpClient.setMethod("POST"); |
| | | |
| | | // 设置请求内容(生成sign) |
| | | String requestUrl = reqHandler.getRequestURL();// 组拼https://www.baidu.com?a=x&b=xx |
| | | |
| | | httpClient.setReqContent(requestUrl);// https://www.baidu.com?a=x&b=xx |
| | | String rescontent = "null"; |
| | | |
| | | httpClient.setRequestHandler(reqHandler);// 把处理对象,像是参数各种东西都设置进去方便获取(quan) |
| | | |
| | | // 返回出去的对象(状态,错误原因,该操作相关信息(参数,返回值)) |
| | | JSONObject returnObj = new JSONObject(); |
| | | |
| | | // 后台调用 |
| | | if (httpClient.call()) { |
| | | System.out.println("统一下单,成功cll了::"); |
| | | |
| | | // 设置结果参数 |
| | | rescontent = httpClient.getResContent(); |
| | | System.out.println("统一下单返回结果:" + rescontent); |
| | | resHandler.setContent(rescontent);// 解析xml |
| | | resHandler.setKey(key); |
| | | |
| | | // 获取返回参数 |
| | | String return_code = resHandler.getParameter("return_code"); |
| | | String return_msg = resHandler.getParameter("return_msg"); |
| | | |
| | | // 判断签名及结果 |
| | | if (resHandler.isTenpaySign() && "SUCCESS".equals(return_code)) { |
| | | String prepay_id = resHandler.getParameter("prepay_id");// 预支付交易会话标识 |
| | | String code_url = resHandler.getParameter("code_url");// 二维码链接 |
| | | |
| | | String result_code = resHandler.getParameter("result_code");// 业务结果 |
| | | String appid = resHandler.getParameter("appid");// 公众账号ID |
| | | String mch_id = resHandler.getParameter("mch_id");// 商户号 |
| | | String nonce_str = resHandler.getParameter("nonce_str");// 随机码 |
| | | String sign = resHandler.getParameter("sign");// 签名 |
| | | |
| | | if (result_code.equals("SUCCESS")) { |
| | | returnObj.put("status", "suc"); |
| | | returnObj.put("sign", sign); |
| | | returnObj.put("nonce_str", nonce_str); |
| | | returnObj.put("mch_id", mch_id); |
| | | returnObj.put("appid", appid); |
| | | returnObj.put("prepay_id", prepay_id); |
| | | returnObj.put("code_url", code_url); |
| | | returnObj.put("out_trade_no", out_trade_no); |
| | | } else { |
| | | String errMsg = "[ERROR]result_code:" + resHandler.getParameter("result_code") + " err_code:" |
| | | + resHandler.getParameter("err_code") + "err_code_des:" |
| | | + resHandler.getParameter("err_code_des"); |
| | | |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-C"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | String errMsg = "return_code:" + return_code + "err_code:" + resHandler.getParameter("err_code") |
| | | + " return_msg:" + return_msg; |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-B"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | // 有可能因为网络原因,请求已经处理,但未收到应答。 |
| | | returnObj.put("status", "ERROR-A"); |
| | | returnObj.put("errMsg", httpClient.getResponseCode() + ":" + httpClient.getErrInfo()); |
| | | } |
| | | |
| | | // 获取debug信息,建议把请求、应答内容、debug信息,通信返回码写入日志,方便定位问题 |
| | | String detail = "http res:" + httpClient.getResponseCode() + "," + httpClient.getErrInfo() + ";" + "req url:" |
| | | + requestUrl + ";" + ";" + "req debug:" + reqHandler.getDebugInfo() + ";" + "res content:" + rescontent |
| | | + ";" + "res debug:" + resHandler.getDebugInfo() + ";"; |
| | | |
| | | returnObj.put("detail", detail); |
| | | |
| | | |
| | | return returnObj; |
| | | } |
| | | |
| | | /**统一支付(分账) |
| | | * @param request 方法获取 |
| | | * @param appId 小程序号 |
| | | * @param partner 商户号 |
| | | * @param key 秘钥 |
| | | * @param notifyUrl 回调链接 |
| | | * @param out_trade_no 订单号 |
| | | * @param body 商品描述 |
| | | * @param total_fee 支付金额 |
| | | * @param openid 用户openId |
| | | * @param attach 附带数据包 |
| | | * @param notifyUrl 回调通知地址 |
| | | * @param trade_type 交易类型 |
| | | * @param profit_sharing 是否分账:N不,Y是 |
| | | * @return JSON status = "SUC"为成功 |
| | | */ |
| | | public static JSONObject unifiedPay(HttpServletRequest request,String appId,String partner,String key,String notifyUrl,String out_trade_no, String body, String total_fee, String openid, |
| | | String attach,String trade_type,String profit_sharing) throws Exception { |
| | | |
| | | if (!SimpleTool.checkNotNull(notifyUrl)) { |
| | | throw new ServiceException("支付功能故障!"); |
| | | } |
| | | |
| | | // 创建查询请求对象 |
| | | RequestHandler reqHandler = new RequestHandler(null, null); |
| | | // 通信对象 |
| | | TenpayHttpClient httpClient = new TenpayHttpClient(); |
| | | // 应答对象 |
| | | ClientResponseHandler resHandler = new ClientResponseHandler(); |
| | | |
| | | // ----------------------------- |
| | | // 设置请求参数 |
| | | // ----------------------------- |
| | | // reqHandler.init(); |
| | | reqHandler.setKey(key); |
| | | reqHandler.setGateUrl(FIRST_ORDER_URL);// 请求URL |
| | | |
| | | // ----------------------------- |
| | | // 设置接口参数(sign后台自动生成) |
| | | // ----------------------------- |
| | | |
| | | reqHandler.setParameter("appid", appId); // 公众号/小程序 |
| | | reqHandler.setParameter("mch_id", partner); // 商户号 |
| | | reqHandler.setParameter("nonce_str", SimpleTool.getUUIDName().substring(0, 30));// 随机乱码 |
| | | reqHandler.setParameter("body", body);// 商品描述 |
| | | reqHandler.setParameter("out_trade_no", out_trade_no);// 商户订单号 |
| | | reqHandler.setParameter("total_fee", total_fee);// 总金额 |
| | | reqHandler.setParameter("spbill_create_ip", "8.8.8.8");// 终端IP |
| | | reqHandler.setParameter("notify_url",notifyUrl);// 通知地址 |
| | | reqHandler.setParameter("trade_type", trade_type);// 交易类型 |
| | | //JSAPI,NATIVE,APP |
| | | reqHandler.setParameter("openid", openid);// openId |
| | | reqHandler.setParameter("attach", attach);// 附带数据包 |
| | | reqHandler.setParameter("profit_sharing", profit_sharing);// 附带数据包 |
| | | |
| | | // ----------------------------- |
| | | // 设置通信参数 |
| | | // ----------------------------- |
| | | // 设置请求返回的等待时间 |
| | | httpClient.setTimeOut(5); |
| | | |
| | | // 设置ca证书 |
| | | // httpClient.setCaInfo(new File(CA_PATH)); |
| | | |
| | | // 设置个人(商户)证书 |
| | | // httpClient.setCertInfo(new File(CERT_PATH), CERT_PWD); |
| | | |
| | | // 设置发送类型POST |
| | | httpClient.setMethod("POST"); |
| | | |
| | | // 设置请求内容(生成sign) |
| | | String requestUrl = reqHandler.getRequestURL();// 组拼https://www.baidu.com?a=x&b=xx |
| | | |
| | | httpClient.setReqContent(requestUrl);// https://www.baidu.com?a=x&b=xx |
| | | String rescontent = "null"; |
| | | |
| | | httpClient.setRequestHandler(reqHandler);// 把处理对象,像是参数各种东西都设置进去方便获取(quan) |
| | | |
| | | // 返回出去的对象(状态,错误原因,该操作相关信息(参数,返回值)) |
| | | JSONObject returnObj = new JSONObject(); |
| | | |
| | | // 后台调用 |
| | | if (httpClient.call()) { |
| | | System.out.println("统一下单,成功cll了::"); |
| | | |
| | | // 设置结果参数 |
| | | rescontent = httpClient.getResContent(); |
| | | System.out.println("统一下单返回结果:" + rescontent); |
| | | resHandler.setContent(rescontent);// 解析xml |
| | | resHandler.setKey(key); |
| | | |
| | | // 获取返回参数 |
| | | String return_code = resHandler.getParameter("return_code"); |
| | | String return_msg = resHandler.getParameter("return_msg"); |
| | | |
| | | // 判断签名及结果 |
| | | if (resHandler.isTenpaySign() && "SUCCESS".equals(return_code)) { |
| | | String prepay_id = resHandler.getParameter("prepay_id");// 预支付交易会话标识 |
| | | String code_url = resHandler.getParameter("code_url");// 二维码链接 |
| | | |
| | | String result_code = resHandler.getParameter("result_code");// 业务结果 |
| | | String appid = resHandler.getParameter("appid");// 公众账号ID |
| | | String mch_id = resHandler.getParameter("mch_id");// 商户号 |
| | | String nonce_str = resHandler.getParameter("nonce_str");// 随机码 |
| | | String sign = resHandler.getParameter("sign");// 签名 |
| | | |
| | | if (result_code.equals("SUCCESS")) { |
| | | returnObj.put("status", "suc"); |
| | | returnObj.put("sign", sign); |
| | | returnObj.put("nonce_str", nonce_str); |
| | | returnObj.put("mch_id", mch_id); |
| | | returnObj.put("appid", appid); |
| | | returnObj.put("prepay_id", prepay_id); |
| | | returnObj.put("code_url", code_url); |
| | | returnObj.put("out_trade_no", out_trade_no); |
| | | } else { |
| | | String errMsg = "[ERROR]result_code:" + resHandler.getParameter("result_code") + " err_code:" |
| | | + resHandler.getParameter("err_code") + "err_code_des:" |
| | | + resHandler.getParameter("err_code_des"); |
| | | |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-C"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | String errMsg = "return_code:" + return_code + "err_code:" + resHandler.getParameter("err_code") |
| | | + " return_msg:" + return_msg; |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-B"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | // 有可能因为网络原因,请求已经处理,但未收到应答。 |
| | | returnObj.put("status", "ERROR-A"); |
| | | returnObj.put("errMsg", httpClient.getResponseCode() + ":" + httpClient.getErrInfo()); |
| | | } |
| | | |
| | | // 获取debug信息,建议把请求、应答内容、debug信息,通信返回码写入日志,方便定位问题 |
| | | String detail = "http res:" + httpClient.getResponseCode() + "," + httpClient.getErrInfo() + ";" + "req url:" |
| | | + requestUrl + ";" + ";" + "req debug:" + reqHandler.getDebugInfo() + ";" + "res content:" + rescontent |
| | | + ";" + "res debug:" + resHandler.getDebugInfo() + ";"; |
| | | |
| | | returnObj.put("detail", detail); |
| | | |
| | | |
| | | return returnObj; |
| | | } |
| | | |
| | | /**处理信息 |
| | | */ |
| | | public static JSONObject paymentData(JSONObject payObj,String key){ |
| | | JSONObject wxObj = new JSONObject(); |
| | | /**统一下单*/ |
| | | String payStatus = payObj.getString("status"); |
| | | if (payStatus.equals("suc")) { |
| | | // JSONObject payObj = po.getJSONObject("inf"); |
| | | String appId = payObj.getString("appid"); |
| | | String nonceStr = payObj.getString("nonce_str"); |
| | | String prepay_id = payObj.getString("prepay_id"); |
| | | // JSAPI调用支付返回的数据 |
| | | String timeStamp = SimpleTool.getTenTime(new Date()).toString(); |
| | | String signType = "MD5"; |
| | | String packagef = "prepay_id=" + prepay_id; |
| | | RequestHandler reqHandler = new RequestHandler(null, null); |
| | | reqHandler.setParameter("appId", appId); |
| | | reqHandler.setParameter("nonceStr", nonceStr); |
| | | reqHandler.setParameter("timeStamp", timeStamp); |
| | | reqHandler.setParameter("package", packagef); |
| | | reqHandler.setParameter("signType", signType); |
| | | reqHandler.setKey(key); |
| | | String paySign = reqHandler.createSign();// 生成签名 |
| | | wxObj.put("orderNo", payObj.getString("out_trade_no")); |
| | | wxObj.put("paySign", paySign); |
| | | wxObj.put("appId", appId); |
| | | wxObj.put("nonceStr", nonceStr); |
| | | wxObj.put("package", packagef); |
| | | wxObj.put("timeStamp", timeStamp); |
| | | } else { |
| | | throw new RuntimeException(payObj.toString()); |
| | | } |
| | | return wxObj; |
| | | } |
| | | |
| | | /** |
| | | * 退款 |
| | | * @param appId 小程序/公众号 appId |
| | | * @param partner 商户号 |
| | | * @param key 商户号秘钥 |
| | | * @param certPath 个人商户证书 |
| | | * @param out_trade_no 商户订单号 |
| | | * @param transaction_id 财付通订单号(微信订单号) |
| | | * @param out_refund_no 商户退单号 |
| | | * @param total_fee 订单总额(单位:分) |
| | | * @param refund_fee 退款金额(单位:分) |
| | | * @return JSON status="SUCCESS"(成功) (状态,错误原因,该操作相关信息(参数,返回值)) |
| | | */ |
| | | public static JSONObject refund(String appId,String partner,String key,String certPath,String out_trade_no, String transaction_id, String out_refund_no, String total_fee, |
| | | String refund_fee) { |
| | | try{ |
| | | KeyStore keyStore = KeyStore.getInstance("PKCS12"); |
| | | FileInputStream instream = new FileInputStream(new File(certPath)); |
| | | try { |
| | | keyStore.load(instream,partner.toCharArray()); |
| | | }finally { |
| | | instream.close(); |
| | | } |
| | | // Trust own CA and all self-signed certs |
| | | SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,partner.toCharArray()).build(); |
| | | // Allow TLSv1 protocol only |
| | | SSLConnectionSocketFactory sslsf; |
| | | sslsf = new SSLConnectionSocketFactory( |
| | | sslcontext, new String[] { "TLSv1" }, null, |
| | | SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); |
| | | CloseableHttpClient httpclient = HttpClients.custom() |
| | | .setSSLSocketFactory(sslsf).build(); |
| | | HttpPost httppost = new HttpPost(REFUND_URL); |
| | | String xml = wxPayRefundData(appId, partner, key, out_trade_no, transaction_id, out_refund_no, total_fee, refund_fee); |
| | | try { |
| | | StringEntity se = new StringEntity(xml); |
| | | httppost.setEntity(se); |
| | | |
| | | CloseableHttpResponse responseEntry = httpclient.execute(httppost); |
| | | try { |
| | | HttpEntity entity = responseEntry.getEntity(); |
| | | if (entity != null) { |
| | | |
| | | SAXReader saxReader = new SAXReader(); |
| | | Document document = saxReader.read(entity.getContent()); |
| | | Element rootElt = document.getRootElement(); |
| | | String returnCode = rootElt.elementText("return_code"); |
| | | JSONObject result = new JSONObject(); |
| | | |
| | | if(returnCode.equals("SUCCESS")){ |
| | | String resultCode = rootElt.elementText("result_code"); |
| | | if(resultCode.equals("SUCCESS")) { |
| | | result.put("weixinPayUrl", rootElt.elementText("code_url")); |
| | | result.put("prepayId", rootElt.elementText("prepay_id")); |
| | | result.put("msg", "success"); |
| | | |
| | | String refund_id = rootElt.elementText("refund_id");//微信退款单号 |
| | | String r_out_refund_no = rootElt.elementText("out_refund_no"); |
| | | String errMsg = "商户号" + r_out_refund_no + "的退款流水号是:" + refund_id; |
| | | result.put("status", "SUCCESS"); |
| | | result.put("errMsg", errMsg); |
| | | result.put("refund_id", refund_id); |
| | | }else{ |
| | | String errMsg = "[ERROR]result_code:" + rootElt.elementText("result_code")+ |
| | | " err_code:" + rootElt.elementText("err_code"); |
| | | |
| | | //错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | result.put("errMsg", errMsg); |
| | | result.put("status","false"); |
| | | result.put("msg",rootElt.elementText("err_code_des")); |
| | | } |
| | | }else{ |
| | | String errMsg = "[ERROR]return_code:" + rootElt.elementText("return_code"); |
| | | |
| | | //错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | result.put("errMsg", errMsg); |
| | | result.put("status","false"); |
| | | result.put("msg",rootElt.elementText("return_msg")); |
| | | } |
| | | return result; |
| | | } |
| | | EntityUtils.consume(entity); |
| | | } |
| | | finally { |
| | | responseEntry.close(); |
| | | } |
| | | } |
| | | finally { |
| | | httpclient.close(); |
| | | } |
| | | return null; |
| | | }catch(Exception e){ |
| | | e.printStackTrace(); |
| | | JSONObject result = new JSONObject(); |
| | | result.put("status","error"); |
| | | result.put("msg",e.getMessage()); |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | /** 封装参数数据 |
| | | * @param appId 小程序/公众号 appId |
| | | * @param partner 商户号 |
| | | * @param key 商户号秘钥 |
| | | * @param out_trade_no 商户订单号 |
| | | * @param transaction_id 财付通订单号(微信订单号) |
| | | * @param out_refund_no 商户退单号 |
| | | * @param total_fee 订单总额(单位:分) |
| | | * @param refund_fee 退款金额(单位:分) |
| | | * @return |
| | | */ |
| | | public static String wxPayRefundData(String appId,String partner,String key,String out_trade_no, String transaction_id,String out_refund_no,String total_fee,String refund_fee) { |
| | | StringBuffer xml = new StringBuffer(); |
| | | String data = null; |
| | | try { |
| | | String nonceStr = SimpleTool.getUUIDName().substring(0,30); |
| | | xml.append("</xml>"); |
| | | SortedMap<String,String> parameters = new TreeMap<String,String>(); |
| | | parameters.put("appid",appId); |
| | | parameters.put("mch_id",partner); |
| | | parameters.put("nonce_str", nonceStr); |
| | | if(!StringUtils.isEmpty(out_trade_no)) { |
| | | parameters.put("out_trade_no", out_trade_no); |
| | | } |
| | | if(!StringUtils.isEmpty(transaction_id)) { |
| | | parameters.put("transaction_id", transaction_id); |
| | | } |
| | | parameters.put("out_refund_no", out_refund_no); |
| | | parameters.put("fee_type", "CNY"); |
| | | parameters.put("total_fee", total_fee);//总金额 |
| | | parameters.put("refund_fee", refund_fee);//退款金额 |
| | | parameters.put("op_user_id",partner); |
| | | parameters.put("sign", createSign(parameters,key)); |
| | | |
| | | data =SortedMaptoXml(parameters); |
| | | } catch (Exception e) { |
| | | System.err.println(e.getMessage()); |
| | | return null; |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | /** |
| | | * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 |
| | | */ |
| | | public static String createSign(SortedMap<String, String> packageParams, String AppKey) { |
| | | StringBuffer sb; |
| | | sb = new StringBuffer(); |
| | | Set es = packageParams.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while (it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry) it.next(); |
| | | String k = (String) entry.getKey(); |
| | | String v = (String) entry.getValue(); |
| | | if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { |
| | | sb.append(k + "=" + v + "&"); |
| | | } |
| | | } |
| | | sb.append("key=" + AppKey); |
| | | String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); |
| | | return sign; |
| | | } |
| | | |
| | | /** |
| | | * @Author: HONGLINCHEN |
| | | * @Description:请求值转换为xml格式 SortedMap转xml |
| | | * @param params |
| | | * @Date: 2017-9-7 17:18 |
| | | */ |
| | | private static String SortedMaptoXml(SortedMap<String,String> params) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | Set es = params.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | sb.append("<xml>\n"); |
| | | while(it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry)it.next(); |
| | | String k = (String)entry.getKey(); |
| | | Object v = entry.getValue(); |
| | | sb.append("<"+k+">"); |
| | | sb.append(v); |
| | | sb.append("</"+k+">\n"); |
| | | } |
| | | sb.append("</xml>"); |
| | | return sb.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.encryption; |
| | | |
| | | /** |
| | | * 接口解密返回结果配置 |
| | | * @author wangrenhuang |
| | | * @Data 2020-06-09 |
| | | */ |
| | | public class PTConstant { |
| | | |
| | | public static String PT_SIGN_EEMPLY = "签名为空!"; |
| | | public static String PT_TIMELS_EMPLY = "时间为空!"; |
| | | public static String PT_SIGN_ERROR = "签名错误"; |
| | | public static String PT_ORER_TIME = "接口超时"; |
| | | |
| | | |
| | | private boolean success; |
| | | private String errCode; |
| | | |
| | | |
| | | /*************************************************************************/ |
| | | |
| | | public boolean isSuccess() { |
| | | return success; |
| | | } |
| | | public void setSuccess(boolean success) { |
| | | this.success = success; |
| | | } |
| | | public String getErrCode() { |
| | | return errCode; |
| | | } |
| | | public void setErrCode(String errCode) { |
| | | this.errCode = errCode; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.encryption; |
| | | |
| | | import com.hx.util.DateUtil; |
| | | import com.hx.util.MD5Util; |
| | | import com.hx.util.StringUtils; |
| | | |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | |
| | | /* |
| | | * @Description: his助手调用 phitab 订单加密工具 |
| | | * @Author: wangrenhuang |
| | | * @Date: 2022/2/15-11:20 |
| | | */ |
| | | public class PTEncryptionUtil { |
| | | |
| | | |
| | | /* |
| | | * 日期加密 |
| | | * date 要加密的日期 |
| | | * */ |
| | | public static String encryption(Date date){ |
| | | Calendar cal=Calendar.getInstance(); |
| | | cal.setTime(date); |
| | | StringBuffer data = new StringBuffer(); |
| | | data.append(cal.get(Calendar.DATE)); |
| | | data.append(cal.get(Calendar.MONTH)); |
| | | data.append(cal.get(Calendar.YEAR)); |
| | | data.append(cal.get(Calendar.SECOND)); |
| | | data.append(cal.get(Calendar.MINUTE)); |
| | | data.append(cal.get(Calendar.HOUR_OF_DAY)); |
| | | |
| | | return com.hx.mp.util.MD5Util.MD5Encode(data.toString(),""); |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param data 签名 |
| | | * @param date 时间 |
| | | * @param time 有效时间 秒 |
| | | * @return |
| | | */ |
| | | public static PTConstant decode(String data,Date date,Integer time){ |
| | | PTConstant ptConstant = new PTConstant(); |
| | | ptConstant.setSuccess(true); |
| | | if (StringUtils.isEmpty(data)){ |
| | | ptConstant.setSuccess(false); |
| | | ptConstant.setErrCode(PTConstant.PT_SIGN_EEMPLY); |
| | | return ptConstant; |
| | | } |
| | | if (null == date){ |
| | | ptConstant.setSuccess(false); |
| | | ptConstant.setErrCode(PTConstant.PT_TIMELS_EMPLY); |
| | | return ptConstant; |
| | | } |
| | | |
| | | if(!encryption(date).equals(data)){ |
| | | ptConstant.setSuccess(false); |
| | | ptConstant.setErrCode(PTConstant.PT_SIGN_ERROR); |
| | | return ptConstant; |
| | | } |
| | | if(time == null){ |
| | | ptConstant.setSuccess(true); |
| | | return ptConstant; |
| | | } |
| | | //有效时间判断 |
| | | if (DateUtil.calLastedTime(date) > time){ |
| | | ptConstant.setSuccess(false); |
| | | ptConstant.setErrCode(PTConstant.PT_ORER_TIME); |
| | | return ptConstant; |
| | | } |
| | | |
| | | return ptConstant; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.exception; |
| | | |
| | | /** |
| | | * 登录提示异常 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-11-17 |
| | | */ |
| | | public class LoginException extends RuntimeException { |
| | | |
| | | private Integer code; |
| | | |
| | | public LoginException(String message) { |
| | | super(message); |
| | | } |
| | | |
| | | public LoginException(String message, Integer code) { |
| | | super(message); |
| | | this.code = code; |
| | | } |
| | | |
| | | public LoginException(String message, Throwable cause, Integer code) { |
| | | super(message, cause); |
| | | this.code = code; |
| | | } |
| | | |
| | | public LoginException(Throwable cause, Integer code) { |
| | | super(cause); |
| | | this.code = code; |
| | | } |
| | | |
| | | //@Override |
| | | public int getCode() { |
| | | return this.code; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.exception; |
| | | |
| | | /** 参数异常 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-06-19 |
| | | */ |
| | | public class ParamException extends RuntimeException { |
| | | |
| | | public ParamException(String message) { |
| | | super(message); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.exception; |
| | | |
| | | /** 判断异常/业务异常 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-06-19 |
| | | */ |
| | | public class ServiceException extends RuntimeException { |
| | | |
| | | private Integer code; |
| | | |
| | | public ServiceException(String message) { |
| | | super(message); |
| | | } |
| | | |
| | | public ServiceException(String message, Integer code) { |
| | | super(message); |
| | | this.code = code; |
| | | } |
| | | |
| | | public ServiceException(String message, Throwable cause, Integer code) { |
| | | super(message, cause); |
| | | this.code = code; |
| | | } |
| | | |
| | | public ServiceException(Throwable cause, Integer code) { |
| | | super(cause); |
| | | this.code = code; |
| | | } |
| | | |
| | | public Integer getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(Integer code) { |
| | | this.code = code; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.exception; |
| | | |
| | | /** |
| | | * 前端提示异常 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-06-19 |
| | | */ |
| | | public class TipsException extends RuntimeException { |
| | | |
| | | private Integer code; |
| | | |
| | | public TipsException(String message) { |
| | | super(message); |
| | | } |
| | | |
| | | public TipsException(String message, Integer code) { |
| | | super(message); |
| | | this.code = code; |
| | | } |
| | | |
| | | public TipsException(String message, Throwable cause, Integer code) { |
| | | super(message, cause); |
| | | this.code = code; |
| | | } |
| | | |
| | | public TipsException(Throwable cause, Integer code) { |
| | | super(cause); |
| | | this.code = code; |
| | | } |
| | | |
| | | public Integer getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(Integer code) { |
| | | this.code = code; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
| | | import org.apache.http.conn.ssl.SSLContexts; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.security.KeyStore; |
| | | |
| | | @SuppressWarnings("deprecation") |
| | | public class CertUtil { |
| | | /** |
| | | * 加载证书 |
| | | */ |
| | | public static SSLConnectionSocketFactory initCert(String certPath, String mchId) throws Exception { |
| | | FileInputStream instream = null; |
| | | KeyStore keyStore = KeyStore.getInstance("PKCS12"); |
| | | instream = new FileInputStream(new File(certPath)); |
| | | keyStore.load(instream, mchId.toCharArray()); |
| | | |
| | | if (null != instream) { |
| | | instream.close(); |
| | | } |
| | | |
| | | SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,mchId.toCharArray()).build(); |
| | | SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); |
| | | |
| | | return sslsf; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import org.jdom.JDOMException; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * ��̨Ӧ����<br/> |
| | | * ========================================================================<br/> |
| | | * api˵����<br/> |
| | | * getKey()/setKey(),��ȡ/������Կ<br/> |
| | | * getContent() / setContent(), ��ȡ/����ԭʼ����<br/> |
| | | * getParameter()/setParameter(),��ȡ/���ò���ֵ<br/> |
| | | * getAllParameters(),��ȡ���в���<br/> |
| | | * isTenpaySign(),�Ƿ�Ƹ�ͨǩ��,true:�� false:��<br/> |
| | | * getDebugInfo(),��ȡdebug��Ϣ<br/> |
| | | * |
| | | * ========================================================================<br/> |
| | | * |
| | | */ |
| | | public class ClientResponseHandler { |
| | | |
| | | /** Ӧ��ԭʼ���� */ |
| | | private String content; |
| | | |
| | | /** Ӧ��IJ��� */ |
| | | @SuppressWarnings("rawtypes") |
| | | private SortedMap parameters; |
| | | |
| | | /** debug��Ϣ */ |
| | | private String debugInfo; |
| | | |
| | | /** ��Կ */ |
| | | private String key; |
| | | |
| | | /** �ַ� */ |
| | | private String charset; |
| | | |
| | | /*@SuppressWarnings("rawtypes") |
| | | public ClientResponseHandler() { |
| | | this.content = ""; |
| | | this.parameters = new TreeMap(); |
| | | this.debugInfo = ""; |
| | | this.key = ""; |
| | | this.charset = "UTF-8"; |
| | | }*/ |
| | | |
| | | public ClientResponseHandler() { |
| | | this.content = ""; |
| | | this.parameters = new TreeMap(); |
| | | this.debugInfo = ""; |
| | | this.key = ""; |
| | | this.charset = "UTF-8"; |
| | | } |
| | | |
| | | public String getContent() { |
| | | return content; |
| | | } |
| | | |
| | | public void setContent(String content) throws Exception { |
| | | this.content = content; |
| | | |
| | | this.doParse(); |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ����ֵ |
| | | * |
| | | * @param parameter |
| | | * ������� |
| | | * @return String |
| | | */ |
| | | public String getParameter(String parameter) { |
| | | String s = (String) this.parameters.get(parameter); |
| | | return (null == s) ? "" : s; |
| | | } |
| | | |
| | | /** |
| | | * ���ò���ֵ |
| | | * |
| | | * @param parameter |
| | | * ������� |
| | | * @param parameterValue |
| | | * ����ֵ |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public void setParameter(String parameter, String parameterValue) { |
| | | String v = ""; |
| | | if (null != parameterValue) { |
| | | v = parameterValue.trim(); |
| | | } |
| | | this.parameters.put(parameter, v); |
| | | } |
| | | |
| | | /** |
| | | * �������еIJ��� |
| | | * |
| | | * @return SortedMap |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public SortedMap getAllParameters() { |
| | | return this.parameters; |
| | | } |
| | | |
| | | public String getDebugInfo() { |
| | | return debugInfo; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ��Կ |
| | | */ |
| | | public String getKey() { |
| | | return key; |
| | | } |
| | | |
| | | /** |
| | | * ������Կ |
| | | */ |
| | | public void setKey(String key) { |
| | | this.key = key; |
| | | } |
| | | |
| | | public String getCharset() { |
| | | return this.charset; |
| | | } |
| | | |
| | | public void setCharset(String charset) { |
| | | this.charset = charset; |
| | | } |
| | | |
| | | /** |
| | | * �Ƿ�Ƹ�ͨǩ��,������:���������a-z����,������ֵ�IJ���μ�ǩ�� |
| | | * |
| | | * @return boolean |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public boolean isTenpaySign() { |
| | | StringBuffer sb = new StringBuffer(); |
| | | Set es = this.parameters.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while (it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry) it.next(); |
| | | String k = (String) entry.getKey(); |
| | | String v = (String) entry.getValue(); |
| | | if (!"sign".equals(k) && null != v && !"".equals(v)) { |
| | | sb.append(k + "=" + v + "&"); |
| | | } |
| | | } |
| | | |
| | | sb.append("key=" + this.getKey()); |
| | | |
| | | System.out.println("返回的参数:" + sb); |
| | | // ���ժҪ |
| | | String sign = MD5Util.MD5Encode(sb.toString(), this.charset) |
| | | .toUpperCase(); |
| | | |
| | | String tenpaySign = this.getParameter("sign").toUpperCase(); |
| | | |
| | | // debug��Ϣ |
| | | this.setDebugInfo(sb.toString() + " => sign:" + sign + " tenpaySign:" |
| | | + tenpaySign); |
| | | |
| | | Boolean b = tenpaySign.equals(sign); |
| | | |
| | | System.out.println("验证返回来的数据是否微信返回的:" + b); |
| | | |
| | | return b; |
| | | } |
| | | |
| | | /** |
| | | * �Ƿ�Ƹ�ͨǩ�� |
| | | * |
| | | * @param signParameterArray |
| | | * ǩ��IJ������� |
| | | * @return boolean |
| | | */ |
| | | protected boolean isTenpaySign(String signParameterArray[]) { |
| | | |
| | | StringBuffer signPars = new StringBuffer(); |
| | | for (int index = 0; index < signParameterArray.length; index++) { |
| | | String k = signParameterArray[index]; |
| | | String v = this.getParameter(k); |
| | | if (null != v && !"".equals(v)) { |
| | | signPars.append(k + "=" + v + "&"); |
| | | } |
| | | } |
| | | |
| | | signPars.append("key=" + this.getKey()); |
| | | |
| | | // ���ժҪ |
| | | String sign = MD5Util.MD5Encode(signPars.toString(), this.charset) |
| | | .toLowerCase(); |
| | | |
| | | String tenpaySign = this.getParameter("sign").toLowerCase(); |
| | | |
| | | // debug��Ϣ |
| | | this.setDebugInfo(signPars.toString() + " => sign:" + sign |
| | | + " tenpaySign:" + tenpaySign); |
| | | |
| | | return tenpaySign.equals(sign); |
| | | } |
| | | |
| | | protected void setDebugInfo(String debugInfo) { |
| | | this.debugInfo = debugInfo; |
| | | } |
| | | |
| | | /** |
| | | * ����XML���� |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | protected void doParse() throws JDOMException, IOException, JDOMException { |
| | | String xmlContent = this.getContent(); |
| | | |
| | | // ����xml,�õ�map |
| | | Map m = XMLUtil.doXMLParse(xmlContent); |
| | | |
| | | // ���� |
| | | Iterator it = m.keySet().iterator(); |
| | | while (it.hasNext()) { |
| | | String k = (String) it.next(); |
| | | String v = (String) m.get(k); |
| | | this.setParameter(k, v); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.hx.util.StringUtils; |
| | | import com.hz.util.http.HttpHzUtil; |
| | | import com.hz.util.http.dto.HttpHzResponse; |
| | | import net.sf.json.JSONArray; |
| | | import net.sf.json.JSONException; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.commons.io.IOUtils; |
| | | |
| | | import java.io.OutputStream; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 企业微信客户工具 |
| | | */ |
| | | public class CorpMpClientUtil { |
| | | |
| | | /** |
| | | * 生成联系我按钮参数的链接(生成config_id) |
| | | */ |
| | | public static final String CREATE_CONTACT_ID_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token="; |
| | | /** |
| | | * 获取企业客户详情链接 |
| | | */ |
| | | public static final String GET_CLIENT_DETAIL_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get"; |
| | | /** |
| | | * 获取获取企业标签库链接 |
| | | */ |
| | | public static final String GET_CORP_TAG_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token="; |
| | | /** |
| | | * 添加客户联系人标签 |
| | | */ |
| | | public static final String ADD_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?access_token="; |
| | | /** |
| | | * 编辑企业客户标签 |
| | | */ |
| | | public static final String EDIT_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag?access_token="; |
| | | /** |
| | | * 删除客户联系人标签 |
| | | */ |
| | | public static final String DEL_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?access_token="; |
| | | /** |
| | | * 客户关联企业微信的标签url |
| | | */ |
| | | public static final String RELATION_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token="; |
| | | |
| | | /** |
| | | * 获取员工客户列表url |
| | | */ |
| | | public static final String EXTERNAL_CONTACT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list"; |
| | | |
| | | /** |
| | | * 创建获客链接url |
| | | */ |
| | | public static final String CUSTOMER_ACQUISITION_CREATE_LINK = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/create_link?access_token="; |
| | | |
| | | /** |
| | | * 获取获客客户列表 |
| | | */ |
| | | public static final String CUSTOMER_ACQUISITION_CUSTOMER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/customer?access_token="; |
| | | |
| | | /** |
| | | * 获取配置过客户群管理的客户群列表 |
| | | */ |
| | | public static final String GROUP_CHAT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token="; |
| | | |
| | | |
| | | /** |
| | | * 通过客户群ID,获取详情。包括群名、群成员列表、群成员入群时间、入群方式。(客户群是由具有客户群使用权限的成员创建的外部群) |
| | | */ |
| | | public static final String GROUP_CHAT_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token="; |
| | | |
| | | /** |
| | | * 企业微信发送普通邮件 |
| | | */ |
| | | public static final String GROUP_SENT_EMAIL = "https://qyapi.weixin.qq.com/cgi-bin/exmail/app/compose_send?access_token="; |
| | | |
| | | /** |
| | | * 客户群「加入群聊」查看 |
| | | */ |
| | | public static final String GROUP_JOIN_WAY_SEE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get_join_way?access_token="; |
| | | /** |
| | | * 客户群「加入群聊」新增 |
| | | * 企业可调用此接口来生成并配置「加入群聊」的二维码或者小程序按钮 |
| | | * 客户通过扫描二维码或点击小程序上的按钮,即可加入特定的客户群 |
| | | */ |
| | | public static final String GROUP_JOIN_WAY_ADD = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/add_join_way?access_token="; |
| | | /** |
| | | * 客户群「加入群聊」修改 |
| | | */ |
| | | public static final String GROUP_JOIN_WAY_EDIT = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/update_join_way?access_token="; |
| | | /** |
| | | * 客户群「加入群聊」删除 |
| | | */ |
| | | public static final String GROUP_JOIN_WAY_EDL= "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/del_join_way?access_token="; |
| | | |
| | | |
| | | /** |
| | | * 生成企业成员联系我的id-单人 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param userId 企业成员的userId |
| | | * @param state 企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情”时会返回该参数值,不超过30个字符 |
| | | * @param remark 联系方式的备注信息,用于助记,不超过30个字符 |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject createContactId(String accessToken, String userId, String state, String remark) { |
| | | |
| | | String configId = null; |
| | | JSONObject data = new JSONObject(); |
| | | data.put("type", 1); |
| | | data.put("scene", 1); |
| | | data.put("state", state); |
| | | data.put("remark", remark); |
| | | JSONArray userIds = new JSONArray(); |
| | | userIds.add(userId); |
| | | data.put("user", userIds); |
| | | |
| | | //请求,返回格式 |
| | | /*{ |
| | | "errcode": 0, |
| | | "errmsg": "ok", |
| | | "config_id":"42b34949e138eb6e027c123cba77fAAA" |
| | | }*/ |
| | | |
| | | return HttpURLUtil(CREATE_CONTACT_ID_URL + accessToken, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 获取客户列表 |
| | | * @param accessToken 企业的accessToken |
| | | * @param userId 企业成员的userId |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject getExternalContactList(String accessToken, String userId) { |
| | | return HttpURLUtil(EXTERNAL_CONTACT_LIST + "?access_token=" + accessToken + "&userid=" + userId, null); |
| | | } |
| | | |
| | | /** |
| | | * 获取企业客户详情信息 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param externalUserId 外部人员的userId |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject getClientData(String accessToken, String externalUserId) { |
| | | return HttpURLUtil(GET_CLIENT_DETAIL_URL + "?access_token=" + accessToken + "&external_userid=" + externalUserId, null); |
| | | } |
| | | |
| | | /** |
| | | * 企业可通过此接口获取企业客户标签详情 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param tagId 标签id |
| | | * @param groupId 标签组id |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject getCorpTagList(String accessToken, JSONArray tagId, JSONArray groupId) { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("tag_id", tagId); |
| | | data.put("group_id", groupId); |
| | | return HttpURLUtil(GET_CORP_TAG_LIST + accessToken, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 添加客户联系人标签, |
| | | * 如果要向指定的标签组下添加标签,需要填写group_id参数;如果要创建一个全新的标签组以及标签, |
| | | * 则需要通过group_name参数指定新标签组名称,如果填写的groupname已经存在,则会在此标签组下新建标签 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param groupId 组id(组名称和组id必填一个) |
| | | * @param groupName 组名称 组名称和组id必填一个) |
| | | * @param groupOrder 组排序,不填默认企业微信生成规则 |
| | | * @param tagArray 数组,格式:[{ "name": "TAG_NAME_1", "order": 1 }] |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject addTable(String accessToken, String groupId, String groupName, String groupOrder, JSONArray tagArray) { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("group_id", groupId); |
| | | data.put("group_name", groupName); |
| | | data.put("order", groupOrder); |
| | | data.put("tag", tagArray); |
| | | return HttpURLUtil(ADD_TAG + accessToken, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 编辑企业客户标签, |
| | | * 注意:修改后的标签组不能和已有的标签组重名,标签也不能和同一标签组下的其他标签重名。 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param id 标签或标签组的id |
| | | * @param name 新的标签或标签组名称,最长为30个字符 |
| | | * @param order 标签/标签组的次序值。order值大的排序靠前。有效的值范围是[0, 2^32) |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject editTable(String accessToken, String id, String name, String order) { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("id", id); |
| | | data.put("name", name); |
| | | data.put("order", order); |
| | | return HttpURLUtil(EDIT_TAG + accessToken, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 删除客户联系人标签 |
| | | * groupArr和tagArr不可同时为空。 |
| | | * 如果一个标签组下所有的标签均被删除,则标签组会被自动删除。 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param groupArr 组id数组 |
| | | * @param tagArr 标签id数组 |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject delTable(String accessToken, JSONArray groupArr, JSONArray tagArr) { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("tag_id", tagArr); |
| | | data.put("group_id", groupArr); |
| | | return HttpURLUtil(DEL_TAG + accessToken, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 客户关联企业微信的标签 |
| | | * 注意:请确保external_userid是userid的外部联系人。 |
| | | * add_tag和remove_tag不可同时为空。 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param userId 企业成员的userid |
| | | * @param externalUserId 外部联系人的id |
| | | * @param addTag 新增的标签id(企业标签的id)数组 |
| | | * @param removeTag 删除的标签id(企业标签的id)数组 |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject relationTag(String accessToken, String userId, String externalUserId, JSONArray addTag, JSONArray removeTag) { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("userid", userId); |
| | | data.put("external_userid", externalUserId); |
| | | data.put("add_tag", addTag); |
| | | data.put("remove_tag", removeTag); |
| | | return HttpURLUtil(RELATION_TAG + accessToken, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 请求http协议 获取信息工具 |
| | | **/ |
| | | public static JSONObject HttpURLUtil(String url, String data) { |
| | | HttpURLConnection con = null; |
| | | URL u = null; |
| | | String wxMsgXml = null; |
| | | JSONObject obj = null; |
| | | try { |
| | | u = new URL(url); |
| | | con = (HttpURLConnection) u.openConnection(); |
| | | con.setRequestMethod("POST"); |
| | | con.setDoOutput(true); |
| | | con.setDoInput(true); |
| | | con.setUseCaches(false); |
| | | con.setReadTimeout(5000); |
| | | con.setRequestProperty("Charset", "UTF-8"); |
| | | con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); |
| | | |
| | | if (data != null) { |
| | | OutputStream os = con.getOutputStream(); |
| | | os.write(data.getBytes("utf-8")); |
| | | } |
| | | |
| | | if (con.getResponseCode() != 200) |
| | | throw new RuntimeException("请求url失败"); |
| | | // 读取返回内容 |
| | | wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8"); |
| | | obj = JSONObject.fromObject(wxMsgXml); |
| | | // //System.out.println("HttpURLUtil:"+wxMsgXml); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | obj = new JSONObject(); |
| | | try { |
| | | obj.put("status", 1); |
| | | obj.put("errMsg", e.getMessage()); |
| | | } catch (JSONException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } finally { |
| | | if (con != null) { |
| | | con.disconnect(); |
| | | } |
| | | } |
| | | return obj; |
| | | } |
| | | |
| | | /**生成企业成员联系我的id-单人 |
| | | * @param accessToken 企业的accessToken |
| | | * @param userId 企业成员的userId |
| | | * @param scene 场景,1-在小程序中联系,2-通过二维码联系 |
| | | * @param state 企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情”时会返回该参数值,不超过30个字符 |
| | | * @param remark 联系方式的备注信息,用于助记,不超过30个字符 |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject createContactId(String accessToken,String userId,int scene,String state,String remark){ |
| | | String configId = null; |
| | | JSONObject data = new JSONObject(); |
| | | data.put("type",1); |
| | | data.put("scene",scene); |
| | | data.put("state",state); |
| | | data.put("remark",remark); |
| | | JSONArray userIds = new JSONArray(); |
| | | userIds.add(userId); |
| | | data.put("user",userIds); |
| | | |
| | | //请求,返回格式 |
| | | /*{ |
| | | "errcode": 0, |
| | | "errmsg": "ok", |
| | | "config_id":"42b34949e138eb6e027c123cba77fAAA" |
| | | }*/ |
| | | |
| | | return HttpURLUtil(CREATE_CONTACT_ID_URL+accessToken,data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 创建获客链接 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param linkName 链接名称 |
| | | * @param userList 员工用户userId |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject createCustomerAcquisitionLink(String accessToken, String linkName, JSONArray userList) { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("link_name", linkName); |
| | | JSONObject subData = new JSONObject(); |
| | | subData.accumulate("user_list", userList); |
| | | data.put("range", subData); |
| | | /** 返回数据 |
| | | * { |
| | | * "link_id":"LINK_ID", |
| | | * "link_name":"获客链接1号", |
| | | * "range": |
| | | * { |
| | | * "user_list":["zhangsan","lisi"], |
| | | * "department_list":[2,3] |
| | | * }, |
| | | * "skip_verify":true |
| | | * } |
| | | */ |
| | | return HttpURLUtil(CUSTOMER_ACQUISITION_CREATE_LINK + accessToken, data.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 获取获客客户列表 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param linkId 链接id |
| | | * @param cursor 分页游标 |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject getCustomerAcquisitionCustomerList(String accessToken, String linkId, String cursor) { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("link_id", linkId); |
| | | data.put("limit", 1000); |
| | | // 分页游标 |
| | | if (!StringUtils.isEmpty(cursor)) { |
| | | data.put("cursor", cursor); |
| | | } |
| | | /** 返回数据 |
| | | * { |
| | | * "errcode": 0, |
| | | * "errmsg": "ok", |
| | | * "customer_list": |
| | | * [ |
| | | * { |
| | | * "external_userid":"woAJ2GCAAAXtWyujaWJHDDGi0mACAAA", |
| | | * "userid":"zhangsan", |
| | | * "chat_status":0, |
| | | * "state":"CHANNEL_A" |
| | | * } |
| | | * ], |
| | | * "next_cursor":"CURSOR" |
| | | * } |
| | | */ |
| | | return HttpURLUtil(CUSTOMER_ACQUISITION_CUSTOMER_LIST + accessToken, data.toString()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 该接口用于获取配置过客户群管理的客户群列表。 |
| | | * |
| | | * @param accessToken 企业的accessToken |
| | | * @param statusFilter 客户群跟进状态过滤。0 - 所有列表(即不过滤) 1 - 离职待继承 2 - 离职继承中 3 - 离职继承完成 |
| | | * @param userIdList 群主过滤 如果不填,表示获取应用可见范围内全部群主的数据可见范围人数超过1000人,为了防止数据包过大,会报错 81017 用户ID列表。最多100个 |
| | | * @param cursor 分页下标 |
| | | * @param limit 列表 |
| | | * @return 返回 |
| | | */ |
| | | public static HttpHzResponse getGroupChatList(String accessToken, Integer statusFilter, List<String> userIdList, String cursor, Integer limit) { |
| | | JSONObject bodyData = new JSONObject(); |
| | | bodyData.put("status_filter", statusFilter); |
| | | //分页下标 |
| | | if (StringUtils.noNull(cursor)) { |
| | | bodyData.put("cursor", cursor); |
| | | } |
| | | //默认100条 |
| | | if (limit == null) { |
| | | limit = 100; |
| | | } |
| | | bodyData.put("limit", limit); |
| | | //过滤 |
| | | if (userIdList != null && userIdList.size() > 0) { |
| | | JSONObject filter = new JSONObject(); |
| | | filter.put("userid_list", userIdList); |
| | | bodyData.put("owner_filter", filter); |
| | | } |
| | | return HttpHzUtil.HttpURLUtilJson(GROUP_CHAT_LIST + accessToken, bodyData.toString(), null, null, "GET", null); |
| | | } |
| | | |
| | | /** |
| | | * 通过客户群ID,获取详情。包括群名、群成员列表、群成员入群时间、入群方式。(客户群是由具有客户群使用权限的成员创建的外部群) |
| | | * |
| | | * @param chatId 客户群ID |
| | | * @param needName 是否需要返回群成员的名字0-不返回;1-返回 |
| | | */ |
| | | public static HttpHzResponse getGroupChatDetail(String accessToken, String chatId, Integer needName) { |
| | | JSONObject bodyData = new JSONObject(); |
| | | bodyData.put("chat_id", chatId); |
| | | if (needName == null) { |
| | | needName = 0; |
| | | } |
| | | bodyData.put("need_name", needName); |
| | | return HttpHzUtil.HttpURLUtilJson(GROUP_CHAT_DETAIL + accessToken, bodyData.toString(), null, null, "GET", null); |
| | | } |
| | | |
| | | /** |
| | | * 企业微信发送普通邮件 |
| | | * 接口地址: https://developer.work.weixin.qq.com/document/path/97445 |
| | | * @param bodyData 参数 |
| | | */ |
| | | public static JSONObject sentEmail(String accessToken, JSONObject bodyData) { |
| | | return HttpURLUtil(GROUP_SENT_EMAIL + accessToken, bodyData.toString()); |
| | | } |
| | | |
| | | /** |
| | | * 客户群「加入群聊」查看详情 |
| | | * @param config_id 联系方式配置ID |
| | | * */ |
| | | public static HttpHzResponse groupJoinSee(String accessToken, String config_id) { |
| | | JSONObject bodyData = new JSONObject(); |
| | | bodyData.put("config_id", config_id); |
| | | return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_SEE + accessToken, bodyData.toString(), null, null, "POST", null); |
| | | } |
| | | |
| | | /** |
| | | * 客户群「加入群聊」新增 |
| | | * @param scene 场景。1 - 群的小程序插件, 2 - 群的二维码插件 |
| | | * @param remark 联系方式的备注信息,用于助记,超过30个字符将被截断 |
| | | * @param auto_create_room 当群满了后,是否自动新建群。0-否;1-是。 默认为1 |
| | | * @param room_base_name 自动建群的群名前缀,当auto_create_room为1时有效。最长40个utf8字符 |
| | | * @param room_base_id 自动建群的群起始序号,当auto_create_room为1时有效 |
| | | * @param chat_id_list 使用该配置的客户群ID列表,最多支持5个 |
| | | * */ |
| | | public static HttpHzResponse groupJoinAdd(String accessToken, Integer scene, String remark |
| | | ,Integer auto_create_room,String room_base_name,Integer room_base_id,List<String> chat_id_list,String state) { |
| | | JSONObject bodyData = new JSONObject(); |
| | | bodyData.put("scene", scene); |
| | | bodyData.put("remark", remark); |
| | | bodyData.put("auto_create_room", auto_create_room); |
| | | bodyData.put("room_base_name", room_base_name); |
| | | bodyData.put("room_base_id", room_base_id); |
| | | bodyData.put("chat_id_list", chat_id_list); |
| | | bodyData.put("state", state); |
| | | return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_ADD + accessToken, bodyData.toString(), null, null, "POST", null); |
| | | } |
| | | |
| | | /** |
| | | * 客户群「加入群聊」修改 |
| | | * @param config_id 联系方式配置ID |
| | | * @param scene 场景。1 - 群的小程序插件, 2 - 群的二维码插件 |
| | | * @param remark 联系方式的备注信息,用于助记,超过30个字符将被截断 |
| | | * @param auto_create_room 当群满了后,是否自动新建群。0-否;1-是。 默认为1 |
| | | * @param room_base_name 自动建群的群名前缀,当auto_create_room为1时有效。最长40个utf8字符 |
| | | * @param room_base_id 自动建群的群起始序号,当auto_create_room为1时有效 |
| | | * @param chat_id_list 使用该配置的客户群ID列表,最多支持5个 |
| | | * */ |
| | | public static HttpHzResponse groupJoinEdit(String accessToken,String config_id, Integer scene, String remark |
| | | ,Integer auto_create_room,String room_base_name,Integer room_base_id,List<String> chat_id_list,String state) { |
| | | JSONObject bodyData = new JSONObject(); |
| | | bodyData.put("config_id", config_id); |
| | | bodyData.put("scene", scene); |
| | | bodyData.put("remark", remark); |
| | | bodyData.put("auto_create_room", auto_create_room); |
| | | bodyData.put("room_base_name", room_base_name); |
| | | bodyData.put("room_base_id", room_base_id); |
| | | bodyData.put("chat_id_list", chat_id_list); |
| | | bodyData.put("state", state); |
| | | return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_EDIT + accessToken, bodyData.toString(), null, null, "POST", null); |
| | | } |
| | | |
| | | /** |
| | | * 客户群「加入群聊」删除 |
| | | * @param config_id 联系方式配置ID |
| | | * */ |
| | | public static HttpHzResponse groupJoinDel(String accessToken, String config_id) { |
| | | JSONObject bodyData = new JSONObject(); |
| | | bodyData.put("config_id", config_id); |
| | | return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_EDL + accessToken, bodyData.toString(), null, null, "POST", null); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.hx.api.CorpMpSpaceApi; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 企业微信微盘接口API |
| | | * @Author: cmg |
| | | * @Date: 2023-7-13 11:08 |
| | | */ |
| | | public class CorpMpSpaceUtil { |
| | | |
| | | /** |
| | | * 增加空间 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param name 空间名称 |
| | | * @param depId 部门id |
| | | * @param adminId 管理员的企业微信id |
| | | * @return |
| | | */ |
| | | public static JSONObject addSpace(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String name, Integer depId, String adminId) |
| | | { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("space_name", name); |
| | | JSONArray arr = new JSONArray(); |
| | | |
| | | //设置部门的可下载权限 |
| | | JSONObject temp = new JSONObject(); |
| | | temp.put("type", 2); |
| | | temp.put("departmentid", depId); |
| | | temp.put("auth", 1); |
| | | arr.add(temp); |
| | | |
| | | //设置管理员 |
| | | temp = new JSONObject(); |
| | | temp.put("type", 1); |
| | | temp.put("userid", adminId); |
| | | temp.put("auth", 7); |
| | | arr.add(temp); |
| | | |
| | | obj.put("auth_info", arr); |
| | | |
| | | return corpMpSpaceApi.addSpace(accessToken, obj.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 空间重命名 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param spaceId |
| | | * @param name |
| | | * @return |
| | | */ |
| | | public static JSONObject editSpaceName(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String spaceId, String name) |
| | | { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("space_name", name); |
| | | obj.put("spaceid", spaceId); |
| | | |
| | | return corpMpSpaceApi.renameSpace(accessToken, obj.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 空间设置 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param spaceId |
| | | * @param enableConfidentialMode |
| | | * @return |
| | | */ |
| | | public static JSONObject spaceSetting(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String spaceId, boolean enableConfidentialMode) |
| | | { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("spaceid", spaceId); |
| | | obj.put("enable_confidential_mode", enableConfidentialMode); |
| | | |
| | | return corpMpSpaceApi.spaceSetting(accessToken, obj.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 创建文件夹 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param spaceId 空间id |
| | | * @param fatherId 上级目录id,如果是空间下第一级,则是空间id |
| | | * @param fileName 文件夹名称 |
| | | * @return |
| | | */ |
| | | public static JSONObject createDir(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String spaceId, String fatherId, String fileName) |
| | | { |
| | | JSONObject param = new JSONObject(); |
| | | param.put("spaceid", spaceId); |
| | | param.put("fatherid", fatherId); |
| | | param.put("file_type", 1); |
| | | param.put("file_name", fileName); |
| | | |
| | | |
| | | return corpMpSpaceApi.createFile(accessToken, param.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 文件/文件夹重命名 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param fileId |
| | | * @param fileName |
| | | * @return |
| | | */ |
| | | public static JSONObject editDirName(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String fileId, String fileName) |
| | | { |
| | | JSONObject param = new JSONObject(); |
| | | param.put("fileid", fileId); |
| | | param.put("new_name", fileName); |
| | | |
| | | return corpMpSpaceApi.renameFile(accessToken, param.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 移除文件夹 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param fileId |
| | | * @return |
| | | */ |
| | | public static JSONObject deleteDir(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String fileId) |
| | | { |
| | | JSONObject param = new JSONObject(); |
| | | |
| | | JSONArray arr = new JSONArray(); |
| | | arr.add(fileId); |
| | | |
| | | param.put("fileid", arr); |
| | | |
| | | return corpMpSpaceApi.deleteFile(accessToken, param.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 传10M以内文件 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param name |
| | | * @param fileBase64Content |
| | | * @param spaceId |
| | | * @param fatherId |
| | | * @return |
| | | */ |
| | | public static JSONObject uploadFile(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String name, String fileBase64Content, String spaceId, String fatherId) { |
| | | JSONObject param = new JSONObject(); |
| | | param.put("spaceid", spaceId); |
| | | param.put("fatherid", fatherId); |
| | | param.put("file_name", name); |
| | | param.put("file_base64_content", fileBase64Content); |
| | | |
| | | return corpMpSpaceApi.fileUpload(accessToken, param.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 分块上传文件-初始化 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param spaceId |
| | | * @param fatherId |
| | | * @param selectTicket |
| | | * @param fileName |
| | | * @param size |
| | | * @param skipPushCard |
| | | * @param blockSha |
| | | * @return |
| | | */ |
| | | public static JSONObject uploadBigFileInit(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String spaceId, String fatherId, |
| | | String selectTicket, String fileName, Long size, boolean skipPushCard, List<String> blockSha) { |
| | | JSONObject param = new JSONObject(); |
| | | param.put("spaceid", spaceId); |
| | | param.put("fatherid", fatherId); |
| | | param.put("selected_ticket", selectTicket); |
| | | param.put("file_name", fileName); |
| | | param.put("size", size); |
| | | param.put("skip_push_card", skipPushCard); |
| | | |
| | | JSONArray arr = new JSONArray(); |
| | | for(String sha : blockSha) |
| | | { |
| | | arr.add(sha); |
| | | } |
| | | param.put("block_sha", arr); |
| | | |
| | | return corpMpSpaceApi.fileUploadInit(accessToken, param.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 分块上传文件-部分上传 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param uploadKey |
| | | * @param index |
| | | * @param fileBase64Content |
| | | * @return |
| | | */ |
| | | public static JSONObject uploadBigFilePart(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String uploadKey, int index, String fileBase64Content) { |
| | | JSONObject param = new JSONObject(); |
| | | param.put("upload_key", uploadKey); |
| | | param.put("index", index); |
| | | param.put("file_base64_content", fileBase64Content); |
| | | |
| | | return corpMpSpaceApi.fileUploadPart(accessToken, param.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 分块上传文件-上传完成 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param uploadKey |
| | | * @return |
| | | */ |
| | | public static JSONObject uploadBigFileFin(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String uploadKey) { |
| | | JSONObject param = new JSONObject(); |
| | | param.put("upload_key", uploadKey); |
| | | |
| | | return corpMpSpaceApi.fileUploadFinish(accessToken, param.toJSONString()); |
| | | } |
| | | |
| | | /** |
| | | * 获取下载路径 |
| | | * @param corpMpSpaceApi |
| | | * @param accessToken |
| | | * @param fileId |
| | | * @return |
| | | */ |
| | | public static JSONObject getDownloadUrl(CorpMpSpaceApi corpMpSpaceApi, String accessToken, String fileId){ |
| | | JSONObject param = new JSONObject(); |
| | | param.put("fileid", fileId); |
| | | |
| | | return corpMpSpaceApi.getDownloadUrl(accessToken, param.toJSONString()); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.hx.util.corp.entity.AppLetInfo; |
| | | import com.hx.exception.TipsException; |
| | | import com.hx.util.HttpMethodUtil; |
| | | import com.hx.util.StringUtils; |
| | | import net.sf.json.JSONException; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.commons.io.IOUtils; |
| | | |
| | | import java.io.OutputStream; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.text.MessageFormat; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 企业微信工具类 |
| | | */ |
| | | public class CorpMpUtil { |
| | | |
| | | /**链接-获取应用accessToken*/ |
| | | public static final String URL_GET_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}"; |
| | | /**链接-获取session信息*/ |
| | | public static final String URL_CODE_2_SESSION = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session?access_token={0}&js_code={1}&grant_type=authorization_code"; |
| | | /**链接-添加标签*/ |
| | | public static final String URL_ADD_LABEL = "https://qyapi.weixin.qq.com/cgi-bin/tag/create?access_token={0}"; |
| | | /**链接-添加部门*/ |
| | | public static final String URL_ADD_DEPARTMENT = "https://qyapi.weixin.qq.com/cgi-bin/department/create?access_token={0}"; |
| | | /**链接-修改部门*/ |
| | | public static final String URL_UPDATE_DEPARTMENT = "https://qyapi.weixin.qq.com/cgi-bin/department/update?access_token={0}"; |
| | | /**链接-删除部门*/ |
| | | public static final String URL_DELETE_DEPARTMENT = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?access_token={0}&id={1}"; |
| | | /**链接-添加成员*/ |
| | | public static final String URL_ADD_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token={0}"; |
| | | /**链接-更新成员*/ |
| | | public static final String URL_UPDATE_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/update?access_token={0}"; |
| | | /**链接-删除成员*/ |
| | | public static final String URL_DELETE_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token={0}&userid={1}"; |
| | | /**链接-成员详情*/ |
| | | public static final String URL_INFO_USER = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={0}&userid={1}"; |
| | | /**发送消息*/ |
| | | public static final String URL_MESSAGE_SEND = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="; |
| | | |
| | | |
| | | /** |
| | | * 添加工作人员 |
| | | * @param at 访问at |
| | | * @param userId 用户id |
| | | * @param name 名称 |
| | | * @param depId 部门id |
| | | * @param position 职位 |
| | | * @param tel 电话 |
| | | * @param email 邮箱 |
| | | * @return 返回 |
| | | */ |
| | | public static int addUser(String at, String userId, String name, int depId |
| | | , String position,String tel,String email) { |
| | | |
| | | if(StringUtils.isEmpty(tel)&&StringUtils.isEmpty(email)){ |
| | | throw new TipsException("添加企业微信手机号和邮箱不能都为空!"); |
| | | } |
| | | |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("userid", userId); |
| | | obj.put("name", name); |
| | | obj.put("department", depId); |
| | | obj.put("position", position); |
| | | obj.put("mobile", tel); |
| | | obj.put("email", email); |
| | | obj = HttpURLUtil(MessageFormat.format(URL_ADD_USER, at), obj.toString()); |
| | | if(obj != null) { |
| | | return obj.optInt("errcode", -1); |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * 添加工作人员 |
| | | * @param at 访问at |
| | | * @param userId 用户id |
| | | * @param name 名称 |
| | | * @param depId 部门id |
| | | * @param position 职位 |
| | | * @param tel 电话 |
| | | * @param email 邮箱 |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject addUserObj(String at, String userId, String name, int depId |
| | | , String position,String tel,String email) { |
| | | |
| | | if(StringUtils.isEmpty(tel)&&StringUtils.isEmpty(email)){ |
| | | throw new TipsException("添加企业微信手机号和邮箱不能都为空!"); |
| | | } |
| | | |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("userid", userId); |
| | | obj.put("name", name); |
| | | obj.put("department", depId); |
| | | obj.put("position", position); |
| | | obj.put("mobile", tel); |
| | | obj.put("email", email); |
| | | obj = HttpURLUtil(MessageFormat.format(URL_ADD_USER, at), obj.toString()); |
| | | |
| | | if(obj == null){ |
| | | obj = new JSONObject(); |
| | | } |
| | | |
| | | return obj; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 更新工作人员 |
| | | * @param at 访问at |
| | | * @param userId 用户id |
| | | * @param name 名称 |
| | | * @param depId 部门id |
| | | * @param position 职位 |
| | | * @param tel 电话 |
| | | * @param email 邮箱 |
| | | * @return 返回 |
| | | */ |
| | | public static int updateUser(String at, String userId, String name, int depId |
| | | , String position,String tel,String email) { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("userid", userId); |
| | | obj.put("name", name); |
| | | obj.put("department", depId); |
| | | obj.put("position", position); |
| | | obj.put("mobile", tel); |
| | | obj.put("email", email); |
| | | |
| | | obj = HttpURLUtil(MessageFormat.format(URL_UPDATE_USER, at), obj.toString()); |
| | | if(obj != null && obj.optInt("errcode", -1) == 0) { |
| | | return obj.optInt("errcode", -1); |
| | | } |
| | | |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * 删除工作人员 |
| | | * @param at 访问at |
| | | * @param userId 企业用户id |
| | | * @return 返回 |
| | | */ |
| | | public static int deleteUser(String at, String userId) { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("userid", userId); |
| | | |
| | | obj = HttpURLUtil(MessageFormat.format(URL_DELETE_USER, at,userId), obj.toString()); |
| | | if(obj != null) { |
| | | return obj.optInt("errcode", -1); |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * 工作人员判断是否存在企业微信 |
| | | * @param at 访问at |
| | | * @param userId 用户id |
| | | * @return 返回 |
| | | */ |
| | | public static int infoUser(String at, String userId) { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("userid", userId); |
| | | |
| | | obj = HttpURLUtil(MessageFormat.format(URL_INFO_USER, at,userId), obj.toString()); |
| | | |
| | | if(obj != null) { |
| | | return obj.optInt("errcode", -1); |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * 获取企业用户信息 |
| | | * @param at 访问at |
| | | * @param userId 用户id |
| | | * @return 返回 |
| | | */ |
| | | public static JSONObject userData(String at, String userId) { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("userid", userId); |
| | | |
| | | return obj = HttpURLUtil(MessageFormat.format(URL_INFO_USER, at,userId), obj.toString()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 添加部门 |
| | | * @param name 部门名称 |
| | | * @return id |
| | | */ |
| | | public static int addDepartment(String at, String name, int parentId) { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("name", name); |
| | | obj.put("parentid", parentId); |
| | | |
| | | obj = HttpURLUtil(MessageFormat.format(URL_ADD_DEPARTMENT, at), obj.toString()); |
| | | |
| | | if(obj != null && obj.optInt("errcode", -1) == 0) { |
| | | return obj.optInt("id", -1); |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * 更新部门 |
| | | * @param name 部门名称 |
| | | * @param deaprtId 部门id |
| | | * @param parentid 父类部门id,可以为空 |
| | | * @return 状态,0成功 |
| | | */ |
| | | public static int updateDepartment(String at, String name, int deaprtId,int parentid) { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("name", name); |
| | | obj.put("id", deaprtId); |
| | | obj.put("parentid", parentid); |
| | | |
| | | obj = HttpURLUtil(MessageFormat.format(URL_UPDATE_DEPARTMENT, at), obj.toString()); |
| | | return obj.optInt("errcode", -1); |
| | | } |
| | | |
| | | /**删除部门 |
| | | * 删除的部门不能是根部门且没有成员 |
| | | * @param deaprtId 部门id |
| | | * @return 状态,0成功 |
| | | */ |
| | | public static int deleteDepartment(String at,int deaprtId) { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("id", deaprtId); |
| | | |
| | | obj = HttpURLUtil(MessageFormat.format(URL_DELETE_DEPARTMENT,at,deaprtId), obj.toString()); |
| | | System.out.println("删除部门:"+obj.toString()); |
| | | return obj.optInt("errcode", -1); |
| | | } |
| | | |
| | | /**发送企业应用消息 |
| | | * @param accessToken 企业accessToken |
| | | * @param data 发送数据结构 |
| | | * @return |
| | | */ |
| | | public static JSONObject messageSend(String accessToken,String data){ |
| | | return HttpURLUtil(URL_MESSAGE_SEND+accessToken,data); |
| | | } |
| | | |
| | | /**添加用户标签,标签名称不能重复 |
| | | * @param at 访问at |
| | | * @param label 标签名称 |
| | | * @return 返回 -1失败,0成功,1已存在 |
| | | */ |
| | | public static int addLabel(String at, String label) { |
| | | String url = MessageFormat.format(URL_ADD_LABEL, at); |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("tagname", label); |
| | | obj = HttpURLUtil(url, obj.toString()); |
| | | System.out.println("obj....:"+obj.toString()); |
| | | if(obj != null ) { |
| | | int errcode = obj.optInt("errcode", -1); |
| | | if( errcode== 0){ |
| | | //上传成功 |
| | | return obj.optInt("tagid", -1); |
| | | }if(errcode == 40071){ |
| | | //标签已经存在 |
| | | return 1; |
| | | } |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取应用accessToken |
| | | * @param corpId 企业id |
| | | * @param appSecret 应用密钥 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static JSONObject getApplicationAccessToken(String corpId, String appSecret) { |
| | | String url = MessageFormat.format(URL_GET_ACCESS_TOKEN, corpId, appSecret); |
| | | JSONObject obj = HttpURLUtil(url, null); |
| | | return obj; |
| | | } |
| | | |
| | | /** |
| | | * 使用临时登录凭证code获取 session_key、用户userId以及用户所在企业的corpId等信息 |
| | | * @param accessToken 访问token |
| | | * @param code 临时code |
| | | * @return |
| | | */ |
| | | public static JSONObject code2Session(String accessToken, String code) { |
| | | String url = MessageFormat.format(URL_CODE_2_SESSION, accessToken, code); |
| | | JSONObject obj = HttpURLUtil(url, null); |
| | | return obj; |
| | | } |
| | | |
| | | |
| | | |
| | | /** 请求http协议 获取信息工具 **/ |
| | | public static JSONObject HttpURLUtil(String url, String data) { |
| | | HttpURLConnection con = null; |
| | | URL u = null; |
| | | String wxMsgXml = null; |
| | | JSONObject obj = null; |
| | | try { |
| | | u = new URL(url); |
| | | con = (HttpURLConnection) u.openConnection(); |
| | | con.setRequestMethod("POST"); |
| | | con.setDoOutput(true); |
| | | con.setDoInput(true); |
| | | con.setUseCaches(false); |
| | | con.setReadTimeout(5000); |
| | | con.setRequestProperty("Charset", "UTF-8"); |
| | | con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); |
| | | |
| | | if (data != null) { |
| | | OutputStream os = con.getOutputStream(); |
| | | os.write(data.getBytes("utf-8")); |
| | | } |
| | | |
| | | if (con.getResponseCode() != 200) |
| | | throw new RuntimeException("请求url失败"); |
| | | // 读取返回内容 |
| | | wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8"); |
| | | obj = JSONObject.fromObject(wxMsgXml); |
| | | // //System.out.println("HttpURLUtil:"+wxMsgXml); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | obj = new JSONObject(); |
| | | try { |
| | | obj.put("status", 1); |
| | | obj.put("errMsg", e.getMessage()); |
| | | } catch (JSONException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } finally { |
| | | if (con != null) { |
| | | con.disconnect(); |
| | | } |
| | | } |
| | | return obj; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.hx.exception.ServiceException; |
| | | import com.hx.util.HttpUtil; |
| | | import com.hx.util.SimpleTool; |
| | | import com.hx.util.StringUtils; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.http.HttpEntity; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpPost; |
| | | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
| | | import org.apache.http.entity.StringEntity; |
| | | import org.apache.http.impl.client.CloseableHttpClient; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | import org.apache.http.ssl.SSLContexts; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.dom4j.Document; |
| | | import org.dom4j.Element; |
| | | import org.dom4j.io.SAXReader; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.security.KeyStore; |
| | | import java.util.*; |
| | | |
| | | |
| | | /** 服务商商户Native(二维码扫码支付) |
| | | * @author ChenJiaHe |
| | | */ |
| | | public class CorpWXPayQrUtil { |
| | | |
| | | |
| | | /**服务商-获取二维码支付数据*/ |
| | | private static final String PAY_NATIVE_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/native"; |
| | | |
| | | /**获取支付二维码数据 |
| | | * @param sp_appid 服务商申请的公众号appid |
| | | * @param sp_mchid 服务商户号 |
| | | * @param sub_appid 子商户申请的公众号appid 不必填 |
| | | * @param sub_mchid 子商户的商户号 |
| | | * @param description 商品描述 |
| | | * @param out_trade_no 商户系统内部订单号 |
| | | * @param amount 金额(分) |
| | | * @param notify_url 回调地址 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static JSONObject nativeQr(String sp_appid , String sp_mchid , String sub_appid |
| | | , String sub_mchid , String description , String out_trade_no , Integer amount |
| | | ,String notify_url ) |
| | | throws Exception { |
| | | |
| | | JSONObject parameters = new JSONObject(); |
| | | parameters.put("sp_appid", sp_appid); |
| | | parameters.put("sp_mchid", sp_mchid); |
| | | parameters.put("sub_appid", sub_appid); |
| | | parameters.put("sub_mchid", sub_mchid); |
| | | parameters.put("description", description); |
| | | parameters.put("out_trade_no", out_trade_no); |
| | | parameters.put("notify_url", notify_url); |
| | | |
| | | JSONObject amountObj = new JSONObject(); |
| | | amountObj.put("total",amount); |
| | | amountObj.put("currency","CNY"); |
| | | parameters.put("amount", amountObj); |
| | | |
| | | JSONObject returnObj = HttpUtil.HttpURLUtilJson(PAY_NATIVE_URL,parameters.toString()); |
| | | |
| | | return returnObj; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.security.KeyManagementException; |
| | | import java.security.KeyStore; |
| | | import java.security.KeyStoreException; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.security.SecureRandom; |
| | | import java.security.UnrecoverableKeyException; |
| | | import java.security.cert.Certificate; |
| | | import java.security.cert.CertificateException; |
| | | import java.security.cert.CertificateFactory; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | import javax.net.ssl.HttpsURLConnection; |
| | | import javax.net.ssl.KeyManagerFactory; |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.net.ssl.TrustManagerFactory; |
| | | |
| | | /** |
| | | * Http�ͻ��˹�����<br/> |
| | | * �����ڲ������࣬�벻Ҫ���ⲿ���á� |
| | | * @author miklchen |
| | | * |
| | | */ |
| | | public class HttpClientUtil { |
| | | |
| | | public static final String SunX509 = "SunX509"; |
| | | public static final String JKS = "JKS"; |
| | | public static final String PKCS12 = "PKCS12"; |
| | | public static final String TLS = "TLS"; |
| | | |
| | | /** |
| | | * get HttpURLConnection |
| | | * @param strUrl url��ַ |
| | | * @return HttpURLConnection |
| | | * @throws IOException |
| | | */ |
| | | public static HttpURLConnection getHttpURLConnection(String strUrl) |
| | | throws IOException { |
| | | URL url = new URL(strUrl); |
| | | HttpURLConnection httpURLConnection = (HttpURLConnection) url |
| | | .openConnection(); |
| | | return httpURLConnection; |
| | | } |
| | | |
| | | /** |
| | | * get HttpsURLConnection |
| | | * @param strUrl url��ַ |
| | | * @return HttpsURLConnection |
| | | * @throws IOException |
| | | */ |
| | | public static HttpsURLConnection getHttpsURLConnection(String strUrl) |
| | | throws IOException { |
| | | URL url = new URL(strUrl); |
| | | HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url |
| | | .openConnection(); |
| | | return httpsURLConnection; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ�����ѯ����url |
| | | * @param strUrl |
| | | * @return String |
| | | */ |
| | | public static String getURL(String strUrl) { |
| | | |
| | | if(null != strUrl) { |
| | | int indexOf = strUrl.indexOf("?"); |
| | | if(-1 != indexOf) { |
| | | return strUrl.substring(0, indexOf); |
| | | } |
| | | |
| | | return strUrl; |
| | | } |
| | | |
| | | return strUrl; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ��ѯ�� |
| | | * @param strUrl |
| | | * @return String |
| | | */ |
| | | public static String getQueryString(String strUrl) { |
| | | |
| | | if(null != strUrl) { |
| | | int indexOf = strUrl.indexOf("?"); |
| | | if(-1 != indexOf) { |
| | | return strUrl.substring(indexOf+1, strUrl.length()); |
| | | } |
| | | |
| | | return ""; |
| | | } |
| | | |
| | | return strUrl; |
| | | } |
| | | |
| | | /** |
| | | * ��ѯ�ַ�ת����Map<br/> |
| | | * name1=key1&name2=key2&... |
| | | * @param queryString |
| | | * @return |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public static Map queryString2Map(String queryString) { |
| | | if(null == queryString || "".equals(queryString)) { |
| | | return null; |
| | | } |
| | | |
| | | Map m = new HashMap(); |
| | | String[] strArray = queryString.split("&"); |
| | | for(int index = 0; index < strArray.length; index++) { |
| | | String pair = strArray[index]; |
| | | HttpClientUtil.putMapByPair(pair, m); |
| | | } |
| | | |
| | | return m; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * �Ѽ�ֵ�����Map<br/> |
| | | * pair:name=value |
| | | * @param pair name=value |
| | | * @param m |
| | | */ |
| | | @SuppressWarnings({ "unchecked", "rawtypes" }) |
| | | public static void putMapByPair(String pair, Map m) { |
| | | |
| | | if(null == pair || "".equals(pair)) { |
| | | return; |
| | | } |
| | | |
| | | int indexOf = pair.indexOf("="); |
| | | if(-1 != indexOf) { |
| | | String k = pair.substring(0, indexOf); |
| | | String v = pair.substring(indexOf+1, pair.length()); |
| | | if(null != k && !"".equals(k)) { |
| | | m.put(k, v); |
| | | } |
| | | } else { |
| | | m.put(pair, ""); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * BufferedReaderת����String<br/> |
| | | * ע��:���ر���Ҫ���д��� |
| | | * @param reader |
| | | * @return String |
| | | * @throws IOException |
| | | */ |
| | | public static String bufferedReader2String(BufferedReader reader) throws IOException { |
| | | StringBuffer buf = new StringBuffer(); |
| | | String line = null; |
| | | while( (line = reader.readLine()) != null) { |
| | | buf.append(line); |
| | | buf.append("\r\n"); |
| | | } |
| | | |
| | | return buf.toString(); |
| | | } |
| | | |
| | | /** |
| | | * �������<br/> |
| | | * ע��:���ر���Ҫ���д��� |
| | | * @param out |
| | | * @param data |
| | | * @param len |
| | | * @throws IOException |
| | | */ |
| | | public static void doOutput(OutputStream out, byte[] data, int len) |
| | | throws IOException { |
| | | int dataLen = data.length; |
| | | int off = 0; |
| | | while (off < data.length) { |
| | | if (len >= dataLen) { |
| | | out.write(data, off, dataLen); |
| | | off += dataLen; |
| | | } else { |
| | | out.write(data, off, len); |
| | | off += len; |
| | | dataLen -= len; |
| | | } |
| | | |
| | | // ˢ�»����� |
| | | out.flush(); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ��ȡSSLContext |
| | | * @param trustFile |
| | | * @param trustPasswd |
| | | * @param keyFile |
| | | * @param keyPasswd |
| | | * @return |
| | | * @throws NoSuchAlgorithmException |
| | | * @throws KeyStoreException |
| | | * @throws IOException |
| | | * @throws CertificateException |
| | | * @throws UnrecoverableKeyException |
| | | * @throws KeyManagementException |
| | | */ |
| | | public static SSLContext getSSLContext( |
| | | FileInputStream trustFileInputStream, String trustPasswd, |
| | | FileInputStream keyFileInputStream, String keyPasswd) |
| | | throws NoSuchAlgorithmException, KeyStoreException, |
| | | CertificateException, IOException, UnrecoverableKeyException, |
| | | KeyManagementException { |
| | | |
| | | // ca |
| | | TrustManagerFactory tmf = TrustManagerFactory.getInstance(HttpClientUtil.SunX509); |
| | | KeyStore trustKeyStore = KeyStore.getInstance(HttpClientUtil.JKS); |
| | | trustKeyStore.load(trustFileInputStream, HttpClientUtil |
| | | .str2CharArray(trustPasswd)); |
| | | tmf.init(trustKeyStore); |
| | | |
| | | final char[] kp = HttpClientUtil.str2CharArray(keyPasswd); |
| | | KeyManagerFactory kmf = KeyManagerFactory.getInstance(HttpClientUtil.SunX509); |
| | | KeyStore ks = KeyStore.getInstance(HttpClientUtil.PKCS12); |
| | | ks.load(keyFileInputStream, kp); |
| | | kmf.init(ks, kp); |
| | | |
| | | SecureRandom rand = new SecureRandom(); |
| | | SSLContext ctx = SSLContext.getInstance(HttpClientUtil.TLS); |
| | | ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), rand); |
| | | |
| | | return ctx; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡCA֤����Ϣ |
| | | * @param cafile CA֤���ļ� |
| | | * @return Certificate |
| | | * @throws CertificateException |
| | | * @throws IOException |
| | | */ |
| | | public static Certificate getCertificate(File cafile) |
| | | throws CertificateException, IOException { |
| | | CertificateFactory cf = CertificateFactory.getInstance("X.509"); |
| | | FileInputStream in = new FileInputStream(cafile); |
| | | Certificate cert = cf.generateCertificate(in); |
| | | in.close(); |
| | | return cert; |
| | | } |
| | | |
| | | /** |
| | | * �ַ�ת����char���� |
| | | * @param str |
| | | * @return char[] |
| | | */ |
| | | public static char[] str2CharArray(String str) { |
| | | if(null == str) return null; |
| | | |
| | | return str.toCharArray(); |
| | | } |
| | | |
| | | /** |
| | | * �洢ca֤���JKS��ʽ |
| | | * @param cert |
| | | * @param alias |
| | | * @param password |
| | | * @param out |
| | | * @throws KeyStoreException |
| | | * @throws NoSuchAlgorithmException |
| | | * @throws CertificateException |
| | | * @throws IOException |
| | | */ |
| | | public static void storeCACert(Certificate cert, String alias, |
| | | String password, OutputStream out) throws KeyStoreException, |
| | | NoSuchAlgorithmException, CertificateException, IOException { |
| | | KeyStore ks = KeyStore.getInstance("JKS"); |
| | | |
| | | ks.load(null, null); |
| | | |
| | | ks.setCertificateEntry(alias, cert); |
| | | |
| | | // store keystore |
| | | ks.store(out, HttpClientUtil.str2CharArray(password)); |
| | | |
| | | } |
| | | |
| | | public static InputStream String2Inputstream(String str) { |
| | | return new ByteArrayInputStream(str.getBytes()); |
| | | } |
| | | |
| | | /** |
| | | * InputStreamת����Byte |
| | | * ע��:���ر���Ҫ���д��� |
| | | * @param in |
| | | * @return byte |
| | | * @throws Exception |
| | | */ |
| | | public static byte[] InputStreamTOByte(InputStream in) throws IOException{ |
| | | |
| | | int BUFFER_SIZE = 4096; |
| | | ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| | | byte[] data = new byte[BUFFER_SIZE]; |
| | | int count = -1; |
| | | |
| | | while((count = in.read(data,0,BUFFER_SIZE)) != -1) |
| | | outStream.write(data, 0, count); |
| | | |
| | | data = null; |
| | | byte[] outByte = outStream.toByteArray(); |
| | | outStream.close(); |
| | | |
| | | return outByte; |
| | | } |
| | | |
| | | /** |
| | | * InputStreamת����String |
| | | * ע��:���ر���Ҫ���д��� |
| | | * @param in |
| | | * @param encoding ���� |
| | | * @return String |
| | | * @throws Exception |
| | | */ |
| | | public static String InputStreamTOString(InputStream in,String encoding) throws IOException{ |
| | | |
| | | return new String(InputStreamTOByte(in),encoding); |
| | | |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpPost; |
| | | import org.apache.http.entity.StringEntity; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | |
| | | public class HttpUtil { |
| | | /** |
| | | * 发送post请求 |
| | | * |
| | | * @param url |
| | | * 请求地址 |
| | | * @param outputEntity |
| | | * 发送内容 |
| | | * @param isLoadCert |
| | | * 是否加载证书 |
| | | */ |
| | | public static CloseableHttpResponse Post(String url, String outputEntity, boolean isLoadCert, String certPath, String mchId) throws Exception { |
| | | HttpPost httpPost = new HttpPost(url); |
| | | // 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别 |
| | | httpPost.addHeader("Content-Type", "text/xml"); |
| | | httpPost.setEntity(new StringEntity(outputEntity, "UTF-8")); |
| | | if (isLoadCert) { |
| | | // 加载含有证书的http请求 |
| | | return HttpClients.custom().setSSLSocketFactory(CertUtil.initCert(certPath, mchId)).build().execute(httpPost); |
| | | } else { |
| | | return HttpClients.custom().build().execute(httpPost); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import org.dom4j.Document; |
| | | import org.dom4j.DocumentHelper; |
| | | import org.dom4j.Element; |
| | | import org.jdom.JDOMException; |
| | | import org.jdom.input.SAXBuilder; |
| | | import org.xml.sax.InputSource; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.StringReader; |
| | | import java.util.*; |
| | | |
| | | public class HttpXmlUtils { |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | public static String transferXml(SortedMap<Object, Object> parameters) { |
| | | |
| | | Document document = DocumentHelper.createDocument(); |
| | | Element root = document.addElement("xml"); |
| | | |
| | | Set es = parameters.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while (it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry) it.next(); |
| | | String k = (String) entry.getKey(); |
| | | String v = (String) entry.getValue(); |
| | | |
| | | Element ToUserName = root.addElement(k); |
| | | ToUserName.addText(v); |
| | | } |
| | | |
| | | String queryString = document.asXML();// 转为String |
| | | |
| | | queryString = queryString.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "").trim(); |
| | | |
| | | // System.out.println("企业端付款参数:"+queryString); |
| | | return queryString; |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | public static Map<String, String> parseRefundXml(String refundXml) throws JDOMException, IOException { |
| | | |
| | | StringReader read = new StringReader(refundXml); |
| | | // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入 |
| | | InputSource source = new InputSource(read); |
| | | // 创建一个新的SAXBuilder |
| | | SAXBuilder sb = new SAXBuilder(); |
| | | // 通过输入源构造一个Document |
| | | Document doc; |
| | | doc = (Document) sb.build(source); |
| | | Element root = doc.getRootElement();// 指向根节点 |
| | | List<Element> list = root.elements(); |
| | | Map<String, String> refundOrderMap = new HashMap<String, String>(); |
| | | if (list != null && list.size() > 0) { |
| | | for (Element element : list) { |
| | | refundOrderMap.put(element.getName(), element.getText()); |
| | | } |
| | | return refundOrderMap; |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import java.security.MessageDigest; |
| | | |
| | | public class MD5Util { |
| | | |
| | | private static String byteArrayToHexString(byte b[]) { |
| | | StringBuffer resultSb = new StringBuffer(); |
| | | for (int i = 0; i < b.length; i++) |
| | | resultSb.append(byteToHexString(b[i])); |
| | | |
| | | return resultSb.toString(); |
| | | } |
| | | |
| | | private static String byteToHexString(byte b) { |
| | | int n = b; |
| | | if (n < 0) |
| | | n += 256; |
| | | int d1 = n / 16; |
| | | int d2 = n % 16; |
| | | return hexDigits[d1] + hexDigits[d2]; |
| | | } |
| | | |
| | | public static String MD5Encode(String origin, String charsetname) { |
| | | String resultString = null; |
| | | try { |
| | | resultString = new String(origin); |
| | | MessageDigest md = MessageDigest.getInstance("MD5"); |
| | | if (charsetname == null || "".equals(charsetname)) |
| | | resultString = byteArrayToHexString(md.digest(resultString |
| | | .getBytes())); |
| | | else |
| | | resultString = byteArrayToHexString(md.digest(resultString |
| | | .getBytes(charsetname))); |
| | | } catch (Exception exception) { |
| | | } |
| | | return resultString; |
| | | } |
| | | |
| | | private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", |
| | | "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.hx.util.OSSUtil; |
| | | import com.hx.util.SimpleTool; |
| | | import com.hx.util.StringUtils; |
| | | import com.hz.util.http.HttpHzUtil; |
| | | import com.hz.util.http.dto.HttpHzResponse; |
| | | import net.sf.json.JSONException; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.commons.codec.binary.Base64; |
| | | import org.apache.commons.io.FileUtils; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.*; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.text.MessageFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 微信获取权限基本工具类 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-07-14 |
| | | */ |
| | | @Component |
| | | public class MPWeixinBaseUtil { |
| | | |
| | | // 类型 |
| | | private static final String GRANT_TYPE = "client_credential"; |
| | | |
| | | /**获取access_token链接*/ |
| | | private static final String GETACCESS_TOKENURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type="; |
| | | /**通过code获取小程序信息链接*/ |
| | | private static final String JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?"; |
| | | /**发送订阅消息通知链接*/ |
| | | private static final String SEND_SUBSCRIBE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="; |
| | | /**生成小程序二维码地址(方形)*/ |
| | | public static final String MAKE_TWOCODE_SQUARE_URL = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token="; |
| | | /**生成小程序二维码地址(圆形)*/ |
| | | public static final String MAKE_TWOCODE_ROUND_URL = "https://api.weixin.qq.com/wxa/getwxacode?access_token={0}"; |
| | | /**生成无限二维码*/ |
| | | public static final String URL_UNLIMIT_SQUARE = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={0}"; |
| | | /**获取小程序订阅个人模板列表*/ |
| | | private static final String GET_APP_TEMPLATE = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token="; |
| | | /**获取公众号模板列表*/ |
| | | private static final String GET_GZH_TEMPLATE = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token="; |
| | | ////////////////////////////////////////////////// |
| | | |
| | | /** (小程序)通过code换取网页授权access_token/如果是snsapi_base模式的授权,这里就可以拿到openId了 ***/ |
| | | public static JSONObject getJscode2session(String appid,String secret,String code) { |
| | | |
| | | return HttpURLUtil(JSCODE2SESSION_URL+"appid="+appid+"&secret="+secret |
| | | +"&grant_type=authorization_code&js_code=" + code,null); |
| | | } |
| | | |
| | | /**发送订阅消息通知**/ |
| | | public static JSONObject sendSubscribeMessage(String data,String accessToken){ |
| | | return HttpURLUtil(SEND_SUBSCRIBE_MESSAGE+accessToken,data); |
| | | } |
| | | |
| | | /** 获取access_token */ |
| | | public static JSONObject getAccessToken(String appid,String secret) throws Exception { |
| | | String access_token; |
| | | // 通过WX接口获取access_token |
| | | JSONObject obj = getApplication_Access_tokenForUrl(appid,secret); |
| | | return obj; |
| | | } |
| | | |
| | | /** 从weixin接口获取Access_token **/ |
| | | public static JSONObject getApplication_Access_tokenForUrl(String appid,String secret) { |
| | | return HttpURLUtil(GETACCESS_TOKENURL+GRANT_TYPE +"&appid="+appid +"&secret="+secret,null); |
| | | } |
| | | |
| | | /**生成无限二维码,并上传到OSS*/ |
| | | public static String createUnlimitQrCode(String at, String scene, String page, int width, boolean autoColor, |
| | | JSONObject lineColor, boolean isHyaline, String fileName, String keyId, |
| | | String keySecret, String endPoint, String bucket) |
| | | { |
| | | String imgUrl = null; |
| | | InputStream in = null; |
| | | HttpURLConnection conn = null; |
| | | |
| | | try { |
| | | //生成发送数据 |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("scene", scene); |
| | | obj.put("width", width); |
| | | obj.put("page", page); |
| | | obj.put("auto_color", autoColor); |
| | | obj.put("line_color", lineColor); |
| | | obj.put("is_hyaline", isHyaline); |
| | | |
| | | // 创建url资源 |
| | | URL url = new URL(StringUtils.format(URL_UNLIMIT_SQUARE, at)); |
| | | // 建立http连接 |
| | | conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | conn.setDoInput(true); |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write((obj.toString()).getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | // 请求返回的数据 |
| | | in = conn.getInputStream(); |
| | | imgUrl = OSSUtil.uploadImg(fileName, in, keyId, keySecret, endPoint, bucket); |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | |
| | | if (in != null) { |
| | | in.close(); |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }catch (Exception e) |
| | | { |
| | | e.printStackTrace(); |
| | | |
| | | if (in != null) { |
| | | try { |
| | | in.close(); |
| | | }catch (Exception ep) |
| | | { |
| | | ep.printStackTrace(); |
| | | } |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | } |
| | | |
| | | return imgUrl; |
| | | } |
| | | |
| | | /**生成有限二维码,返回临时文 |
| | | * @param at 微信token |
| | | * @param page 跳转链接 |
| | | * @param width 宽度 |
| | | * @param autoColor 默认false |
| | | * @param lineColor 默认null |
| | | * @param isHyaline 默认false |
| | | * @return |
| | | */ |
| | | public static File createLimitedQrCode(String at, String page, int width, boolean autoColor, |
| | | JSONObject lineColor, boolean isHyaline) { |
| | | String imgUrl = null; |
| | | InputStream in = null; |
| | | HttpURLConnection conn = null; |
| | | |
| | | //创建临时文件 |
| | | File file = null; |
| | | try { |
| | | file = File.createTempFile("temp", ".jpg"); |
| | | //生成发送数据 |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("width", width); |
| | | obj.put("path", page); |
| | | obj.put("auto_color", autoColor); |
| | | obj.put("line_color", lineColor); |
| | | obj.put("is_hyaline", isHyaline); |
| | | |
| | | // 创建url资源 |
| | | URL url = new URL(StringUtils.format(MAKE_TWOCODE_ROUND_URL, at)); |
| | | // 建立http连接 |
| | | conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | conn.setDoInput(true); |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write((obj.toString()).getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | // 请求返回的数据 |
| | | in = conn.getInputStream(); |
| | | //输入到临时文件 |
| | | /*OutputStream os = new FileOutputStream(file); |
| | | int bytesRead = 0; |
| | | byte[] buffer = new byte[8192]; |
| | | while ((bytesRead = in.read(buffer, 0, 8192)) != -1) { |
| | | os.write(buffer, 0, bytesRead); |
| | | }*/ |
| | | FileUtils.copyInputStreamToFile(in, file); |
| | | |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | |
| | | if (in != null) { |
| | | in.close(); |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | if (in != null) { |
| | | try { |
| | | in.close(); |
| | | }catch (Exception ep) { |
| | | ep.printStackTrace(); |
| | | } |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }finally { |
| | | if(file != null){ |
| | | file.deleteOnExit(); |
| | | } |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | |
| | | /**生成有限二维码,返回临时文 |
| | | * @param at 微信token |
| | | * @param page 跳转链接 |
| | | * @param width 宽度 |
| | | * @param autoColor 默认false |
| | | * @param lineColor 默认null |
| | | * @param isHyaline 默认false |
| | | * @param envVersion 要打开的小程序版本。正式版为 release,体验版为 trial,开发版为 develop |
| | | * @return |
| | | */ |
| | | public static File createLimitedQrCode(String at, String page, int width, boolean autoColor, |
| | | JSONObject lineColor, boolean isHyaline,String envVersion) { |
| | | String imgUrl = null; |
| | | InputStream in = null; |
| | | HttpURLConnection conn = null; |
| | | |
| | | //创建临时文件 |
| | | File file = null; |
| | | try { |
| | | file = File.createTempFile("temp", ".jpg"); |
| | | //生成发送数据 |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("width", width); |
| | | obj.put("path", page); |
| | | obj.put("auto_color", autoColor); |
| | | obj.put("line_color", lineColor); |
| | | obj.put("is_hyaline", isHyaline); |
| | | obj.put("env_version", envVersion); |
| | | |
| | | // 创建url资源 |
| | | URL url = new URL(StringUtils.format(MAKE_TWOCODE_ROUND_URL, at)); |
| | | // 建立http连接 |
| | | conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | conn.setDoInput(true); |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write((obj.toString()).getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | // 请求返回的数据 |
| | | in = conn.getInputStream(); |
| | | //输入到临时文件 |
| | | /*OutputStream os = new FileOutputStream(file); |
| | | int bytesRead = 0; |
| | | byte[] buffer = new byte[8192]; |
| | | while ((bytesRead = in.read(buffer, 0, 8192)) != -1) { |
| | | os.write(buffer, 0, bytesRead); |
| | | }*/ |
| | | FileUtils.copyInputStreamToFile(in, file); |
| | | |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | |
| | | if (in != null) { |
| | | in.close(); |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | if (in != null) { |
| | | try { |
| | | in.close(); |
| | | }catch (Exception ep) { |
| | | ep.printStackTrace(); |
| | | } |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }finally { |
| | | if(file != null){ |
| | | file.deleteOnExit(); |
| | | } |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | /**生成无限二维码,返回临时文 |
| | | * @param at 微信token |
| | | * @param scene 参数,只能32位,最好不要中文 |
| | | * @param page 跳转链接 |
| | | * @param width 宽度 |
| | | * @param autoColor 默认false |
| | | * @param lineColor 默认null |
| | | * @param isHyaline 默认false |
| | | * @return |
| | | */ |
| | | public static File createUnlimitQrCode(String at, String scene, String page, int width, boolean autoColor, |
| | | JSONObject lineColor, boolean isHyaline) throws IOException { |
| | | String imgUrl = null; |
| | | InputStream in = null; |
| | | HttpURLConnection conn = null; |
| | | |
| | | //创建临时文件 |
| | | File file = File.createTempFile("temp", ".jpg"); |
| | | |
| | | try { |
| | | //生成发送数据 |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("scene", scene); |
| | | obj.put("width", width); |
| | | obj.put("page", page); |
| | | obj.put("auto_color", autoColor); |
| | | obj.put("line_color", lineColor); |
| | | obj.put("is_hyaline", isHyaline); |
| | | |
| | | // 创建url资源 |
| | | URL url = new URL(StringUtils.format(URL_UNLIMIT_SQUARE, at)); |
| | | // 建立http连接 |
| | | conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | conn.setDoInput(true); |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write((obj.toString()).getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | // 请求返回的数据 |
| | | in = conn.getInputStream(); |
| | | //输入到临时文件 |
| | | /*OutputStream os = new FileOutputStream(file); |
| | | int bytesRead = 0; |
| | | byte[] buffer = new byte[8192]; |
| | | while ((bytesRead = in.read(buffer, 0, 8192)) != -1) { |
| | | os.write(buffer, 0, bytesRead); |
| | | }*/ |
| | | FileUtils.copyInputStreamToFile(in, file); |
| | | |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | |
| | | if (in != null) { |
| | | in.close(); |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | if (in != null) { |
| | | try { |
| | | in.close(); |
| | | }catch (Exception ep) { |
| | | ep.printStackTrace(); |
| | | } |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }finally { |
| | | file.deleteOnExit(); |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | |
| | | /**生成小程序二维码工具(方形) |
| | | * path 二维码跳转链接 |
| | | * width 二维码宽度,默认是430 |
| | | * saveUrl 保存图片的全路径 |
| | | * seeUrl 显示图片路径 |
| | | * appid 小程序配置 |
| | | * secret 小程序配置 |
| | | * return 二维码显示图片链接 |
| | | * @throws Exception |
| | | * */ |
| | | public static String twoCodeImgSquare(String at, String path,Integer width,String saveUrl, |
| | | String seeUrl,String appid,String secret) throws Exception { |
| | | |
| | | if(!SimpleTool.checkNotNull(width)) { |
| | | width = 430; |
| | | } |
| | | //生成发送数据 |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("path", path); |
| | | obj.put("width", width); |
| | | |
| | | //二维码图片路径 |
| | | String codeUrl = ""; |
| | | codeUrl = HttpURLUtilMakeCodeImg(MAKE_TWOCODE_SQUARE_URL+at,obj,saveUrl,seeUrl); |
| | | if(SimpleTool.checkNotNull(codeUrl)){ |
| | | if(!codeUrl.startsWith("/")){ |
| | | codeUrl = "/"+codeUrl; |
| | | } |
| | | } |
| | | return codeUrl; |
| | | } |
| | | |
| | | public static String twoCodeImgSquare(String at, String path,Integer width, String fileName, String keyId, |
| | | String keySecret, String endPoint, String bucket) throws Exception { |
| | | |
| | | if(!SimpleTool.checkNotNull(width)) { |
| | | width = 430; |
| | | } |
| | | //生成发送数据 |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("path", path); |
| | | obj.put("width", width); |
| | | |
| | | String imgUrl = null; |
| | | InputStream in = null; |
| | | HttpURLConnection conn = null; |
| | | |
| | | try { |
| | | |
| | | // 创建url资源 |
| | | URL url = new URL(MAKE_TWOCODE_SQUARE_URL + at); |
| | | // 建立http连接 |
| | | conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | conn.setDoInput(true); |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write((obj.toString()).getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | // 请求返回的数据 |
| | | in = conn.getInputStream(); |
| | | imgUrl = OSSUtil.uploadImg(fileName, in, keyId, keySecret, endPoint, bucket); |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | |
| | | if (in != null) { |
| | | in.close(); |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }catch (Exception e) |
| | | { |
| | | e.printStackTrace(); |
| | | |
| | | if (in != null) { |
| | | try { |
| | | in.close(); |
| | | }catch (Exception ep) |
| | | { |
| | | ep.printStackTrace(); |
| | | } |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | } |
| | | |
| | | return imgUrl; |
| | | |
| | | |
| | | } |
| | | |
| | | /** 生成二维码的图片 返回图片路径 |
| | | * urlx 执行链接 |
| | | * objx 数据 |
| | | * saveUrl 保存图片路径 |
| | | * seeUrl 显示图片路径 |
| | | * |
| | | * **/ |
| | | public static String HttpURLUtilMakeCodeImg(String urlx,JSONObject objx,String saveUrl,String seeUrl) throws IOException { |
| | | String realpath = null; |
| | | |
| | | // 创建url资源 |
| | | URL url = new URL(urlx); |
| | | // 建立http连接 |
| | | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | |
| | | conn.setDoInput(true); |
| | | |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 转换为字节数组 |
| | | // byte[] data = (objx.toString()).getBytes(); |
| | | // 设置文件长度 |
| | | // conn.setRequestProperty("Content-Length",String.valueOf(data.length)); |
| | | |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write((objx.toString()).getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | System.out.println("连接成功"); |
| | | // 请求返回的数据 |
| | | InputStream in = conn.getInputStream(); |
| | | ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); |
| | | byte[] temp = new byte[1024]; |
| | | int rc = 0; |
| | | while ((rc = in.read(temp, 0, 100)) > 0) { |
| | | swapStream.write(temp, 0, rc); |
| | | } |
| | | byte[] buffer2 = swapStream.toByteArray(); |
| | | String base64 = Base64.encodeBase64String(buffer2); |
| | | |
| | | //生成名称 |
| | | java.util.Random r=new java.util.Random(); |
| | | StringBuilder str=new StringBuilder();//定义变长字符串 |
| | | for(int i=0;i<8;i++){ |
| | | str.append(r.nextInt(10)); |
| | | } |
| | | Date date = new Date(); |
| | | SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); |
| | | String imgName = sf.format(date); |
| | | imgName = imgName+str.toString(); |
| | | |
| | | //文件保存位置 |
| | | File saveDir = new File(saveUrl); |
| | | if(!saveDir.exists()){ |
| | | saveDir.mkdir(); |
| | | } |
| | | File file = new File(saveDir+"/"+imgName+".png"); |
| | | FileOutputStream fos = new FileOutputStream(file); |
| | | fos.write(buffer2); |
| | | if(fos!=null){ |
| | | fos.close(); |
| | | } |
| | | if(in!=null){ |
| | | in.close(); |
| | | } |
| | | realpath = seeUrl+"/"+imgName+".png"; |
| | | } else { |
| | | System.out.println("no++"); |
| | | } |
| | | return realpath; |
| | | } |
| | | |
| | | /** 请求http协议 获取信息工具 **/ |
| | | private static JSONObject HttpURLUtil(String url,String data) { |
| | | HttpURLConnection con = null; |
| | | URL u; |
| | | String wxMsgXml; |
| | | JSONObject obj; |
| | | try { |
| | | u = new URL(url); |
| | | con = (HttpURLConnection) u.openConnection(); |
| | | con.setRequestMethod("POST"); |
| | | con.setDoOutput(true); |
| | | con.setDoInput(true); |
| | | con.setUseCaches(false); |
| | | con.setReadTimeout(5000); |
| | | con.setRequestProperty("Charset", "UTF-8"); |
| | | con.setRequestProperty("Content-Type", |
| | | "application/x-www-form-urlencoded"); |
| | | if (data != null) { |
| | | OutputStream os = con.getOutputStream(); |
| | | os.write(data.getBytes("utf-8")); |
| | | } |
| | | if (con.getResponseCode() != 200) |
| | | throw new RuntimeException("请求url失败"); |
| | | // 读取返回内容 |
| | | wxMsgXml = IOUtils.toString(con.getInputStream(), StandardCharsets.UTF_8); |
| | | // 判断返回参数是否正确/成功 |
| | | obj = JSONObject.fromObject(wxMsgXml); |
| | | // System.out.println("HttpURLUtil:"+wxMsgXml); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | obj = new JSONObject(); |
| | | try { |
| | | obj.put("status", 1); |
| | | obj.put("errMsg", e.getMessage()); |
| | | } catch (JSONException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } finally { |
| | | if (con != null) { |
| | | con.disconnect(); |
| | | } |
| | | } |
| | | return obj; |
| | | } |
| | | |
| | | |
| | | |
| | | /**生成无限二维码,返回临时文 |
| | | * @param at 微信token |
| | | * @param scene 参数,只能32位,最好不要中文 |
| | | * @param page 跳转链接 |
| | | * @param width 宽度 |
| | | * @param autoColor 默认false |
| | | * @param lineColor 默认null |
| | | * @param isHyaline 默认false |
| | | * @return |
| | | */ |
| | | public static File createUnlimitQrCode(String at, String scene, String page, int width, boolean autoColor, |
| | | JSONObject lineColor, boolean isHyaline, String env_version) throws IOException { |
| | | String imgUrl = null; |
| | | InputStream in = null; |
| | | HttpURLConnection conn = null; |
| | | |
| | | //创建临时文件 |
| | | File file = File.createTempFile("temp", ".jpg"); |
| | | |
| | | try { |
| | | //生成发送数据 |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("scene", scene); |
| | | obj.put("width", width); |
| | | obj.put("page", page); |
| | | obj.put("auto_color", autoColor); |
| | | obj.put("line_color", lineColor); |
| | | obj.put("is_hyaline", isHyaline); |
| | | obj.put("env_version", env_version); |
| | | //体验版时,可不检查页面是否存在 |
| | | if("trial".equals(env_version)){ |
| | | obj.put("check_path", false); |
| | | } |
| | | // 创建url资源 |
| | | URL url = new URL(StringUtils.format(URL_UNLIMIT_SQUARE, at)); |
| | | // 建立http连接 |
| | | conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | conn.setDoInput(true); |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write((obj.toString()).getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | // 请求返回的数据 |
| | | in = conn.getInputStream(); |
| | | //输入到临时文件 |
| | | /*OutputStream os = new FileOutputStream(file); |
| | | int bytesRead = 0; |
| | | byte[] buffer = new byte[8192]; |
| | | while ((bytesRead = in.read(buffer, 0, 8192)) != -1) { |
| | | os.write(buffer, 0, bytesRead); |
| | | }*/ |
| | | FileUtils.copyInputStreamToFile(in, file); |
| | | |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | |
| | | if (in != null) { |
| | | in.close(); |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | if (in != null) { |
| | | try { |
| | | in.close(); |
| | | }catch (Exception ep) { |
| | | ep.printStackTrace(); |
| | | } |
| | | in = null; |
| | | } |
| | | |
| | | if (conn != null) { |
| | | conn.disconnect(); |
| | | conn = null; |
| | | } |
| | | }finally { |
| | | file.deleteOnExit(); |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | /** |
| | | * 获取小程序订阅模板 |
| | | * @param accessToken token |
| | | * **/ |
| | | public static HttpHzResponse appTemplateList(String accessToken) { |
| | | return HttpHzUtil.HttpURLUtilJson(GET_APP_TEMPLATE + accessToken, null,null,null,"GET",null); |
| | | } |
| | | |
| | | /** |
| | | * 公众号订阅模板 |
| | | * @param accessToken token |
| | | * **/ |
| | | public static HttpHzResponse gzhTemplateList(String accessToken) { |
| | | return HttpHzUtil.HttpURLUtilJson(GET_GZH_TEMPLATE+accessToken, null,null,null,"GET",null); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.hx.util.HttpMethodUtil; |
| | | import com.hx.util.StringUtils; |
| | | import net.sf.json.JSONException; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.commons.codec.binary.Base64; |
| | | import org.apache.commons.io.IOUtils; |
| | | |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.sql.Timestamp; |
| | | import java.text.MessageFormat; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 微信小程序工具类 |
| | | */ |
| | | public class MpUtil { |
| | | |
| | | /** 请求access_token */ |
| | | public static final String URL_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}"; |
| | | /** 请求服务器IP地址 */ |
| | | public static final String URL_SERVER_ADDR = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token="; |
| | | /** 微信js的code换去sessionKey */ |
| | | public static final String JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&grant_type=authorization_code&js_code="; |
| | | /** 请求小程序码 **/ |
| | | public static final String URL_WXACODE = "https://api.weixin.qq.com/wxa/getwxacode?access_token="; |
| | | /** 请求小程序码-无数量限制 **/ |
| | | public static final String URL_WXACODEUNLIMIT = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="; |
| | | /** 请求小程序二维码 */ |
| | | public static final String URL_QRCODE = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token="; |
| | | /** 发模版消息 */ |
| | | public static final String URL_SEND_TEMP_MSG = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token="; |
| | | /** 设置发票授权字段 */ |
| | | public static final String URL_SET_TICKET_FIELD = "https://api.weixin.qq.com/card/invoice/setbizattr?action=set_auth_field&access_token="; |
| | | /** 获取发票ticket */ |
| | | public static final String URL_GET_TICKET_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card&access_token="; |
| | | /** 获取发票授权页链接 */ |
| | | public static final String URL_GET_TICKET_AUTH_LINK = "https://api.weixin.qq.com/card/invoice/getauthurl?access_token="; |
| | | /** 查询发票授权字段 */ |
| | | public static final String URL_GET_AUTH_FIELD = "https://api.weixin.qq.com/card/invoice/getauthdata?access_token="; |
| | | /** 设置 支付后开发票 */ |
| | | public static final String URL_SET_PAY_INVOICE = "https://api.weixin.qq.com/card/invoice/setbizattr?action=set_pay_mch&access_token="; |
| | | /** 查询支付后开发票 */ |
| | | public static final String URL_GET_PAY_INVOICE = "https://api.weixin.qq.com/card/invoice/setbizattr?action=get_pay_mch&access_token="; |
| | | /** 发送客服消息 */ |
| | | public static final String URL_SEND_KF_MSG = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="; |
| | | |
| | | /************************************************* |
| | | * 小程序 |
| | | *************************/ |
| | | /** 利用code换取sessionKey */ |
| | | public static JSONObject jsCode2session(String code, String appId, String appSecret) { |
| | | JSONObject obj = new JSONObject(); |
| | | String url = StringUtils.format(JSCODE2SESSION_URL, appId, appSecret) + code; |
| | | obj = HttpURLUtil(url, null); |
| | | return obj; |
| | | } |
| | | |
| | | /** 获取小程序二维码图片 */ |
| | | public static String getQrCode(String accessToken, String jsonParam) |
| | | throws Exception { |
| | | JSONObject obj = HttpURLUtilJson(URL_QRCODE + accessToken, jsonParam); |
| | | String qrStr = obj.optString("data"); |
| | | return qrStr; |
| | | } |
| | | |
| | | /** 从weixin接口获取Access_token **/ |
| | | public static JSONObject getApplication_Access_tokenForUrl(String appId, String appSecret) |
| | | throws Exception { |
| | | String url = MessageFormat.format(URL_ACCESS_TOKEN, appId, appSecret); |
| | | JSONObject obj = HttpURLUtil(url, null); |
| | | return obj; |
| | | } |
| | | |
| | | /** 请求http协议 获取信息工具 **/ |
| | | public static InputStream HttpURLUtilStream(String url, String data) { |
| | | HttpURLConnection con = null; |
| | | URL u = null; |
| | | try { |
| | | u = new URL(url); |
| | | con = (HttpURLConnection) u.openConnection(); |
| | | con.setRequestMethod("POST"); |
| | | con.setDoOutput(true); |
| | | con.setDoInput(true); |
| | | con.setUseCaches(false); |
| | | con.setReadTimeout(200000); |
| | | con.setRequestProperty("Charset", "UTF-8"); |
| | | con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); |
| | | |
| | | if (data != null) { |
| | | OutputStream os = con.getOutputStream(); |
| | | os.write(data.getBytes("utf-8")); |
| | | } |
| | | |
| | | if (con.getResponseCode() != 200) |
| | | throw new RuntimeException("请求url失败"); |
| | | |
| | | return con.getInputStream(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | if (con != null) { |
| | | con.disconnect(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** 获取二维码图片 **/ |
| | | public static JSONObject HttpURLUtilJson(String urlx, String objx) { |
| | | JSONObject jo = new JSONObject(); |
| | | try { |
| | | // 创建url资源 |
| | | URL url = new URL(urlx); |
| | | // 建立http连接 |
| | | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
| | | // 设置允许输出 |
| | | conn.setDoOutput(true); |
| | | |
| | | conn.setDoInput(true); |
| | | |
| | | // 设置不用缓存 |
| | | conn.setUseCaches(false); |
| | | // 设置传递方式 |
| | | conn.setRequestMethod("POST"); |
| | | // 设置维持长连接 |
| | | conn.setRequestProperty("Connection", "Keep-Alive"); |
| | | // 设置文件字符集: |
| | | conn.setRequestProperty("Charset", "UTF-8"); |
| | | // 设置文件类型: |
| | | conn.setRequestProperty("contentType", "application/json"); |
| | | // 开始连接请求 |
| | | conn.connect(); |
| | | OutputStream out = conn.getOutputStream(); |
| | | // 写入请求的字符串 |
| | | out.write(objx.getBytes()); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | // 请求返回的状态 |
| | | if (conn.getResponseCode() == 200) { |
| | | // 请求返回的数据 |
| | | InputStream in = conn.getInputStream(); |
| | | try { |
| | | ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); |
| | | byte[] temp = new byte[1024]; |
| | | int rc = 0; |
| | | while ((rc = in.read(temp, 0, 100)) > 0) { |
| | | swapStream.write(temp, 0, rc); |
| | | } |
| | | byte[] buffer = swapStream.toByteArray(); |
| | | String base64 = Base64.encodeBase64String(buffer); |
| | | jo.put("data", base64); |
| | | } catch (Exception e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } else { |
| | | // System.out.println("no++"); |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return jo; |
| | | } |
| | | |
| | | /** 请求http协议 获取信息工具 **/ |
| | | public static JSONObject HttpURLUtil(String url, String data) { |
| | | HttpURLConnection con = null; |
| | | URL u = null; |
| | | String wxMsgXml = null; |
| | | JSONObject obj = null; |
| | | try { |
| | | u = new URL(url); |
| | | con = (HttpURLConnection) u.openConnection(); |
| | | con.setRequestMethod("POST"); |
| | | con.setDoOutput(true); |
| | | con.setDoInput(true); |
| | | con.setUseCaches(false); |
| | | con.setReadTimeout(5000); |
| | | con.setRequestProperty("Charset", "UTF-8"); |
| | | con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); |
| | | |
| | | if (data != null) { |
| | | OutputStream os = con.getOutputStream(); |
| | | os.write(data.getBytes("utf-8")); |
| | | } |
| | | |
| | | if (con.getResponseCode() != 200) |
| | | throw new RuntimeException("请求url失败"); |
| | | // 读取返回内容 |
| | | wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8"); |
| | | obj = JSONObject.fromObject(wxMsgXml); |
| | | // //System.out.println("HttpURLUtil:"+wxMsgXml); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | obj = new JSONObject(); |
| | | try { |
| | | obj.put("status", 1); |
| | | obj.put("errMsg", e.getMessage()); |
| | | } catch (JSONException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } finally { |
| | | if (con != null) { |
| | | con.disconnect(); |
| | | } |
| | | } |
| | | return obj; |
| | | } |
| | | |
| | | /** 发送模版消息 **/ |
| | | public static JSONObject sendTempMsg(String accessToken, String jsonStr) { |
| | | JSONObject obj = HttpURLUtil(URL_SEND_TEMP_MSG + accessToken, jsonStr); |
| | | return obj; |
| | | } |
| | | |
| | | public static Integer DateToTimestamp(Date time) { |
| | | Timestamp ts = new Timestamp(time.getTime()); |
| | | return (int) ((ts.getTime()) / 1000); |
| | | } |
| | | |
| | | /** |
| | | * 发送链接客服消息 |
| | | * |
| | | * @throws JSONException |
| | | */ |
| | | public static String sendKfLinkMsg(String at, String openId, String title, String description, String url, |
| | | String imgUrl) throws JSONException { |
| | | String result = "fail"; |
| | | |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("touser", openId); |
| | | obj.put("msgtype", "link"); |
| | | |
| | | JSONObject pObj = new JSONObject(); |
| | | pObj.put("title", title); |
| | | pObj.put("description", description); |
| | | pObj.put("url", url); |
| | | pObj.put("thumb_url", imgUrl); |
| | | obj.put("link", pObj); |
| | | |
| | | JSONObject rObj = HttpURLUtil(URL_SEND_KF_MSG + at, obj.toString()); |
| | | // System.out.println("rObj==="+rObj); |
| | | if (rObj != null) { |
| | | if (rObj.optInt("errcode", -1) == 0) { |
| | | result = "suc"; |
| | | } else { |
| | | result = rObj.optString("errmsg"); |
| | | } |
| | | } |
| | | rObj = null; |
| | | obj = null; |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 发送图片客户消息 |
| | | * |
| | | * @param access_token |
| | | * access_token |
| | | * @param toUser |
| | | * 用户openid |
| | | * @param media_id |
| | | * 素材id |
| | | * @return |
| | | */ |
| | | public static String sendKfImageMsg(String access_token, String toUser, String media_id) { |
| | | String result = "fail"; |
| | | |
| | | try { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("touser", toUser); |
| | | obj.put("msgtype", "image"); |
| | | |
| | | JSONObject pObj = new JSONObject(); |
| | | pObj.put("media_id", media_id); |
| | | obj.put("image", pObj); |
| | | |
| | | JSONObject rObj = HttpURLUtil(URL_SEND_KF_MSG + access_token, obj.toString()); |
| | | System.out.println("rObj==" + rObj.toString()); |
| | | if (rObj != null) { |
| | | if (rObj.optInt("errcode", -1) == 0) { |
| | | result = "suc"; |
| | | } else { |
| | | result = rObj.optString("errmsg"); |
| | | } |
| | | } |
| | | rObj = null; |
| | | obj = null; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 发送文本客户消息 |
| | | * |
| | | * @param access_token |
| | | * access_token |
| | | * @param toUser |
| | | * 用户openid |
| | | * @return |
| | | */ |
| | | public static String sendKfTextMsg(String access_token, String toUser, String content) { |
| | | String result = "fail"; |
| | | |
| | | try { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("touser", toUser); |
| | | obj.put("msgtype", "text"); |
| | | |
| | | JSONObject pObj = new JSONObject(); |
| | | pObj.put("content", content); |
| | | obj.put("text", pObj); |
| | | |
| | | JSONObject rObj = HttpURLUtil(URL_SEND_KF_MSG + access_token, obj.toString()); |
| | | if (rObj != null) { |
| | | if (rObj.optInt("errcode", -1) == 0) { |
| | | result = "suc"; |
| | | } else { |
| | | result = rObj.optString("errmsg"); |
| | | } |
| | | } |
| | | rObj = null; |
| | | obj = null; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** 获取小程序码图片 */ |
| | | public static String getWXACode(String accessToken, String jsonParam, String path) |
| | | throws Exception { |
| | | JSONObject obj = HttpURLUtilJson(URL_WXACODE + accessToken, jsonParam); |
| | | String qrStr = obj.optString("data"); |
| | | return qrStr; |
| | | } |
| | | |
| | | /** 获取小程序码图片 */ |
| | | public static String getWXACodeUnlimit(String accessToken, String jsonParam, String path) |
| | | throws Exception { |
| | | JSONObject obj = HttpURLUtilJson(URL_WXACODEUNLIMIT + accessToken, jsonParam); |
| | | String qrStr = obj.optString("data"); |
| | | return qrStr; |
| | | } |
| | | |
| | | /** |
| | | * 获取小程序链接 |
| | | * @param token 小程序token |
| | | * @param path 小程序页面路径 |
| | | * @param query 传值参数 |
| | | * @param env_version |
| | | * @return 要打开的小程序版本。正式版为 "release",体验版为"trial",开发版为"develop",仅在微信外打开时生效 |
| | | */ |
| | | public static String getAooLetUrl(String token, String path, String query, String env_version) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("access_token", token); |
| | | JSONObject data = new JSONObject(); |
| | | data.put("path", path); |
| | | data.put("query", query); |
| | | data.put("env_version", env_version); |
| | | return HttpMethodUtil.HttpURLUtilJson("https://api.weixin.qq.com/wxa/generate_urllink", data.toString(), map, null, "POST"); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 公众号发送小程序卡片客户消息 |
| | | * @param access_token access_token |
| | | * @param toUser 用户openid |
| | | * @param title 标题 |
| | | * @param appid 小程序appid |
| | | * @param pagepath 跳转页面路径 |
| | | * @param thumb_media_id 缩略图/小程序卡片图片的媒体ID,小程序卡片图片建议大小为520*416 |
| | | * @return |
| | | */ |
| | | public static String sendMpMsg(String access_token, String toUser, String title,String appid,String pagepath,String thumb_media_id) { |
| | | String result = "fail"; |
| | | |
| | | try { |
| | | JSONObject obj = new JSONObject(); |
| | | obj.put("touser", toUser); |
| | | obj.put("msgtype", "miniprogrampage"); |
| | | |
| | | JSONObject pObj = new JSONObject(); |
| | | pObj.put("title", title); |
| | | pObj.put("appid", appid); |
| | | pObj.put("pagepath", pagepath); |
| | | pObj.put("thumb_media_id", thumb_media_id); |
| | | obj.put("miniprogrampage", pObj); |
| | | |
| | | JSONObject rObj = HttpURLUtil(URL_SEND_KF_MSG + access_token, obj.toString()); |
| | | if (rObj != null) { |
| | | if (rObj.optInt("errcode", -1) == 0) { |
| | | result = "suc"; |
| | | } else { |
| | | result = rObj.optString("errmsg"); |
| | | } |
| | | } |
| | | rObj = null; |
| | | obj = null; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.net.URLEncoder; |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.SortedMap; |
| | | import java.util.TreeMap; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | /** |
| | | * �������� ��������̳д��࣬��дcreateSign�������ɡ� |
| | | *JX |
| | | *linhan |
| | | */ |
| | | public class RequestHandler { |
| | | |
| | | /** ���url��ַ */ |
| | | private String gateUrl; |
| | | |
| | | /** ��Կ */ |
| | | private String key; |
| | | |
| | | /** ����IJ��� */ |
| | | @SuppressWarnings("rawtypes") |
| | | private SortedMap parameters; |
| | | |
| | | /** debug��Ϣ */ |
| | | private String debugInfo; |
| | | |
| | | private HttpServletRequest request; |
| | | |
| | | private HttpServletResponse response; |
| | | |
| | | /** |
| | | * ���캯�� |
| | | * |
| | | * @param request |
| | | * @param response |
| | | */ |
| | | /*@SuppressWarnings("rawtypes") |
| | | public RequestHandler(HttpServletRequest request, |
| | | HttpServletResponse response) { |
| | | this.request = request; |
| | | this.response = response; |
| | | |
| | | this.gateUrl = "https://gw.tenpay.com/gateway/pay.htm"; |
| | | this.key = ""; |
| | | this.parameters = new TreeMap(); |
| | | this.debugInfo = ""; |
| | | }*/ |
| | | |
| | | /** |
| | | * ���캯�� |
| | | * @param request |
| | | * @param response |
| | | */ |
| | | public RequestHandler(HttpServletRequest request, HttpServletResponse response) { |
| | | this.request = request; |
| | | this.response = response; |
| | | |
| | | this.gateUrl = "https://gw.tenpay.com/gateway/pay.htm"; |
| | | this.key = ""; |
| | | this.parameters = new TreeMap(); |
| | | this.debugInfo = ""; |
| | | } |
| | | |
| | | /** |
| | | * ��ʼ������ |
| | | */ |
| | | public void init() { |
| | | // nothing to do |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ��ڵ�ַ,�������ֵ |
| | | */ |
| | | public String getGateUrl() { |
| | | return gateUrl; |
| | | } |
| | | |
| | | /** |
| | | * ������ڵ�ַ,�������ֵ |
| | | */ |
| | | public void setGateUrl(String gateUrl) { |
| | | this.gateUrl = gateUrl; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ��Կ |
| | | */ |
| | | public String getKey() { |
| | | return key; |
| | | } |
| | | |
| | | /** |
| | | * 秘钥 |
| | | */ |
| | | public void setKey(String key) { |
| | | this.key = key; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ����ֵ |
| | | * |
| | | * @param parameter |
| | | * ������� |
| | | * @return String |
| | | */ |
| | | public String getParameter(String parameter) { |
| | | String s = (String) this.parameters.get(parameter); |
| | | return (null == s) ? "" : s; |
| | | } |
| | | |
| | | /** |
| | | * ���ò���ֵ |
| | | * |
| | | * @param parameter |
| | | * ������� |
| | | * @param parameterValue |
| | | * ����ֵ |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public void setParameter(String parameter, String parameterValue) { |
| | | String v = ""; |
| | | if (null != parameterValue) { |
| | | v = parameterValue.trim(); |
| | | } |
| | | this.parameters.put(parameter, v); |
| | | } |
| | | |
| | | /** |
| | | * �������еIJ��� |
| | | * |
| | | * @return SortedMap |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public SortedMap getAllParameters() { |
| | | return this.parameters; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡdebug��Ϣ |
| | | */ |
| | | public String getDebugInfo() { |
| | | return debugInfo; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ����������URL |
| | | * |
| | | * @return String |
| | | * @throws UnsupportedEncodingException |
| | | */ |
| | | /*@SuppressWarnings("rawtypes") |
| | | public String getRequestURL() throws UnsupportedEncodingException { |
| | | |
| | | this.createSign(); |
| | | |
| | | StringBuffer sb = new StringBuffer(); |
| | | String enc = TenpayUtil.getCharacterEncoding(this.request, |
| | | this.response); |
| | | Set es = this.parameters.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while (it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry) it.next(); |
| | | String k = (String) entry.getKey(); |
| | | String v = (String) entry.getValue(); |
| | | |
| | | if (!"spbill_create_ip".equals(k)) { |
| | | sb.append(k + "=" + URLEncoder.encode(v, enc) + "&"); |
| | | } else { |
| | | sb.append(k + "=" + v.replace(".", "%2E") + "&"); |
| | | |
| | | } |
| | | } |
| | | |
| | | // ȥ�����һ��& |
| | | String reqPars = sb.substring(0, sb.lastIndexOf("&")); |
| | | |
| | | return this.getGateUrl() + "?" + reqPars; |
| | | |
| | | }*/ |
| | | |
| | | /** |
| | | * ��ȡ����������URL |
| | | * @return String |
| | | * @throws UnsupportedEncodingException |
| | | */ |
| | | public String getRequestURL() throws UnsupportedEncodingException { |
| | | |
| | | this.createSign(); |
| | | |
| | | StringBuffer sb = new StringBuffer(); |
| | | String enc = TenpayUtil.getCharacterEncoding(this.request, this.response); |
| | | Set es = this.parameters.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while(it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry)it.next(); |
| | | String k = (String)entry.getKey(); |
| | | String v = (String)entry.getValue(); |
| | | |
| | | if(!"spbill_create_ip".equals(k)) { |
| | | sb.append(k + "=" + URLEncoder.encode(v, enc) + "&"); |
| | | } else { |
| | | sb.append(k + "=" + v.replace(".", "%2E") + "&"); |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | //ȥ�����һ��& |
| | | String reqPars = sb.substring(0, sb.lastIndexOf("&")); |
| | | |
| | | return this.getGateUrl() + "?" + reqPars; |
| | | |
| | | } |
| | | |
| | | public void doSend() throws UnsupportedEncodingException, IOException { |
| | | this.response.sendRedirect(this.getRequestURL()); |
| | | } |
| | | |
| | | /** |
| | | * TODO 生成签名 |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public String createSign() { |
| | | StringBuffer sb = new StringBuffer(); |
| | | Set es = this.parameters.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while (it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry) it.next(); |
| | | String k = (String) entry.getKey(); |
| | | String v = (String) entry.getValue(); |
| | | if (null != v && !"".equals(v) && !"sign".equals(k) |
| | | && !"key".equals(k)) { |
| | | sb.append(k + "=" + v + "&"); |
| | | } |
| | | } |
| | | sb.append("key=" + this.getKey()); |
| | | System.out.println("sb="+sb); |
| | | String enc = TenpayUtil.getCharacterEncoding(this.request, |
| | | this.response); |
| | | String sign = MD5Util.MD5Encode(sb.toString(), enc).toUpperCase(); |
| | | |
| | | this.setParameter("sign", sign); |
| | | |
| | | // debug��Ϣ |
| | | this.setDebugInfo(sb.toString() + " => sign:" + sign); |
| | | |
| | | return sign; |
| | | } |
| | | |
| | | /** |
| | | * ����debug��Ϣ |
| | | */ |
| | | protected void setDebugInfo(String debugInfo) { |
| | | this.debugInfo = debugInfo; |
| | | } |
| | | |
| | | protected HttpServletRequest getHttpServletRequest() { |
| | | return this.request; |
| | | } |
| | | |
| | | protected HttpServletResponse getHttpServletResponse() { |
| | | return this.response; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.PrintWriter; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.SortedMap; |
| | | import java.util.TreeMap; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | /** |
| | | * Ӧ������ Ӧ������̳д��࣬��дisTenpaySign�������ɡ� |
| | | *JX |
| | | *linhan |
| | | */ |
| | | public class ResponseHandler { |
| | | |
| | | /** ��Կ */ |
| | | private String key; |
| | | |
| | | /** Ӧ��IJ��� */ |
| | | @SuppressWarnings("rawtypes") |
| | | private SortedMap parameters; |
| | | |
| | | /** debug��Ϣ */ |
| | | private String debugInfo; |
| | | |
| | | private HttpServletRequest request; |
| | | |
| | | private HttpServletResponse response; |
| | | |
| | | private String uriEncoding; |
| | | |
| | | /** |
| | | * ���캯�� |
| | | * |
| | | * @param request |
| | | * @param response |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public ResponseHandler(HttpServletRequest request, |
| | | HttpServletResponse response) { |
| | | this.request = request; |
| | | this.response = response; |
| | | |
| | | this.key = ""; |
| | | this.parameters = new TreeMap(); |
| | | this.debugInfo = ""; |
| | | |
| | | this.uriEncoding = ""; |
| | | |
| | | Map m = this.request.getParameterMap(); |
| | | Iterator it = m.keySet().iterator(); |
| | | while (it.hasNext()) { |
| | | String k = (String) it.next(); |
| | | String v = ((String[]) m.get(k))[0]; |
| | | this.setParameter(k, v); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ��Կ |
| | | */ |
| | | public String getKey() { |
| | | return key; |
| | | } |
| | | |
| | | /** |
| | | * ������Կ |
| | | */ |
| | | public void setKey(String key) { |
| | | this.key = key; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ����ֵ |
| | | * |
| | | * @param parameter |
| | | * ������� |
| | | * @return String |
| | | */ |
| | | public String getParameter(String parameter) { |
| | | String s = (String) this.parameters.get(parameter); |
| | | return (null == s) ? "" : s; |
| | | } |
| | | |
| | | /** |
| | | * ���ò���ֵ |
| | | * |
| | | * @param parameter |
| | | * ������� |
| | | * @param parameterValue |
| | | * ����ֵ |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public void setParameter(String parameter, String parameterValue) { |
| | | String v = ""; |
| | | if (null != parameterValue) { |
| | | v = parameterValue.trim(); |
| | | } |
| | | this.parameters.put(parameter, v); |
| | | } |
| | | |
| | | /** |
| | | * �������еIJ��� |
| | | * |
| | | * @return SortedMap |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public SortedMap getAllParameters() { |
| | | return this.parameters; |
| | | } |
| | | |
| | | /** |
| | | * �Ƿ�Ƹ�ͨǩ��,������:���������a-z����,������ֵ�IJ���μ�ǩ�� |
| | | * |
| | | * @return boolean |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public boolean isTenpaySign() { |
| | | StringBuffer sb = new StringBuffer(); |
| | | Set es = this.parameters.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while (it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry) it.next(); |
| | | String k = (String) entry.getKey(); |
| | | String v = (String) entry.getValue(); |
| | | if (!"sign".equals(k) && null != v && !"".equals(v)) { |
| | | sb.append(k + "=" + v + "&"); |
| | | } |
| | | } |
| | | |
| | | sb.append("key=" + this.getKey()); |
| | | |
| | | // ���ժҪ |
| | | String enc = TenpayUtil.getCharacterEncoding(this.request, |
| | | this.response); |
| | | String sign = MD5Util.MD5Encode(sb.toString(), enc).toLowerCase(); |
| | | |
| | | String tenpaySign = this.getParameter("sign").toLowerCase(); |
| | | |
| | | // debug��Ϣ |
| | | this.setDebugInfo(sb.toString() + " => sign:" + sign + " tenpaySign:" |
| | | + tenpaySign); |
| | | |
| | | return tenpaySign.equals(sign); |
| | | } |
| | | |
| | | /** |
| | | * ���ش������Ƹ�ͨ�������� |
| | | * |
| | | * @param msg |
| | | * : Success or fail�� |
| | | * @throws IOException |
| | | */ |
| | | public void sendToCFT(String msg) throws IOException { |
| | | String strHtml = msg; |
| | | PrintWriter out = this.getHttpServletResponse().getWriter(); |
| | | out.println(strHtml); |
| | | out.flush(); |
| | | out.close(); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ��ȡuri���� |
| | | * |
| | | * @return String |
| | | */ |
| | | public String getUriEncoding() { |
| | | return uriEncoding; |
| | | } |
| | | |
| | | /** |
| | | * ����uri���� |
| | | * |
| | | * @param uriEncoding |
| | | * @throws UnsupportedEncodingException |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public void setUriEncoding(String uriEncoding) |
| | | throws UnsupportedEncodingException { |
| | | if (!"".equals(uriEncoding.trim())) { |
| | | this.uriEncoding = uriEncoding; |
| | | |
| | | // ����ת�� |
| | | String enc = TenpayUtil.getCharacterEncoding(request, response); |
| | | Iterator it = this.parameters.keySet().iterator(); |
| | | while (it.hasNext()) { |
| | | String k = (String) it.next(); |
| | | String v = this.getParameter(k); |
| | | v = new String(v.getBytes(uriEncoding.trim()), enc); |
| | | this.setParameter(k, v); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ��ȡdebug��Ϣ |
| | | */ |
| | | public String getDebugInfo() { |
| | | return debugInfo; |
| | | } |
| | | |
| | | /** |
| | | * ����debug��Ϣ |
| | | */ |
| | | protected void setDebugInfo(String debugInfo) { |
| | | this.debugInfo = debugInfo; |
| | | } |
| | | |
| | | protected HttpServletRequest getHttpServletRequest() { |
| | | return this.request; |
| | | } |
| | | |
| | | protected HttpServletResponse getHttpServletResponse() { |
| | | return this.response; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import java.io.BufferedOutputStream; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.net.HttpURLConnection; |
| | | import java.security.KeyManagementException; |
| | | import java.security.KeyStoreException; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.security.UnrecoverableKeyException; |
| | | import java.security.cert.CertificateException; |
| | | import java.security.cert.X509Certificate; |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.SortedMap; |
| | | |
| | | import javax.net.ssl.HttpsURLConnection; |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.net.ssl.SSLSocketFactory; |
| | | |
| | | import org.dom4j.Document; |
| | | import org.dom4j.DocumentHelper; |
| | | import org.dom4j.Element; |
| | | |
| | | /** |
| | | * �Ƹ�ͨhttp����https����ͨ�ſͻ���<br/> |
| | | * ========================================================================<br/> |
| | | * api˵����<br/> |
| | | * setReqContent($reqContent),�����������ݣ�����post��get������get��ʽ�ṩ<br/> |
| | | * getResContent(), ��ȡӦ������<br/> |
| | | * setMethod(method),��������,post����get<br/> |
| | | * getErrInfo(),��ȡ������Ϣ<br/> |
| | | * setCertInfo(certFile, certPasswd),����֤�飬˫��httpsʱ��Ҫʹ��<br/> |
| | | * setCaInfo(caFile), ����CA����ʽδpem�����������<br/> |
| | | * setTimeOut(timeOut)�� ���ó�ʱʱ�䣬��λ��<br/> |
| | | * getResponseCode(), ȡ���ص�http״̬��<br/> |
| | | * call(),������ýӿ�<br/> |
| | | * getCharset()/setCharset(),�ַ����<br/> |
| | | * |
| | | * ========================================================================<br/> |
| | | * |
| | | */ |
| | | public class TenpayHttpClient { |
| | | |
| | | private static final String USER_AGENT_VALUE = |
| | | "Mozilla/4.0 (compatible; MSIE 6.0; Windows XP)"; |
| | | |
| | | private static final String JKS_CA_FILENAME = |
| | | "tenpay_cacert.jks"; |
| | | |
| | | private static final String JKS_CA_ALIAS = "tenpay"; |
| | | |
| | | private static final String JKS_CA_PASSWORD = ""; |
| | | |
| | | /** ca֤���ļ� */ |
| | | private File caFile; |
| | | |
| | | /** ֤���ļ� */ |
| | | private File certFile; |
| | | |
| | | /** ֤������ */ |
| | | private String certPasswd; |
| | | |
| | | /** �������ݣ�����post��get������get��ʽ�ṩ */ |
| | | private String reqContent; |
| | | |
| | | /** Ӧ������ */ |
| | | private String resContent; |
| | | |
| | | /** ���� */ |
| | | private String method; |
| | | |
| | | /** ������Ϣ */ |
| | | private String errInfo; |
| | | |
| | | /** ��ʱʱ��,����Ϊ��λ */ |
| | | private int timeOut; |
| | | |
| | | /** httpӦ����� */ |
| | | private int responseCode; |
| | | |
| | | /** �ַ���� */ |
| | | private String charset; |
| | | |
| | | private InputStream inputStream; |
| | | |
| | | private RequestHandler reqHandler;//方便取值所用(quan) |
| | | |
| | | /*public TenpayHttpClient() { |
| | | this.caFile = null; |
| | | this.certFile = null; |
| | | this.certPasswd = ""; |
| | | |
| | | this.reqContent = ""; |
| | | this.resContent = ""; |
| | | this.method = "POST"; |
| | | this.errInfo = ""; |
| | | this.timeOut = 30;//30�� |
| | | |
| | | this.responseCode = 0; |
| | | this.charset = "UTF-8"; |
| | | |
| | | this.inputStream = null; |
| | | }*/ |
| | | |
| | | public TenpayHttpClient() { |
| | | this.caFile = null; |
| | | this.certFile = null; |
| | | this.certPasswd = ""; |
| | | |
| | | this.reqContent = ""; |
| | | this.resContent = ""; |
| | | this.method = "POST"; |
| | | this.errInfo = ""; |
| | | this.timeOut = 30;//30�� |
| | | |
| | | this.responseCode = 0; |
| | | this.charset = "UTF-8"; |
| | | |
| | | this.inputStream = null; |
| | | } |
| | | |
| | | /** |
| | | * ����֤����Ϣ |
| | | * @param certFile ֤���ļ� |
| | | * @param certPasswd ֤������ |
| | | */ |
| | | public void setCertInfo(File certFile, String certPasswd) { |
| | | this.certFile = certFile; |
| | | this.certPasswd = certPasswd; |
| | | } |
| | | |
| | | /** |
| | | * ����ca |
| | | * @param caFile |
| | | */ |
| | | public void setCaInfo(File caFile) { |
| | | this.caFile = caFile; |
| | | } |
| | | |
| | | /** |
| | | * ������������ |
| | | * @param reqContent �������� |
| | | */ |
| | | public void setReqContent(String reqContent) { |
| | | this.reqContent = reqContent; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ������� |
| | | * @return String |
| | | * @throws IOException |
| | | */ |
| | | public String getResContent() { |
| | | try { |
| | | this.doResponse(); |
| | | } catch (IOException e) { |
| | | this.errInfo = e.getMessage(); |
| | | //return ""; |
| | | } |
| | | |
| | | return this.resContent; |
| | | } |
| | | |
| | | /** |
| | | * ��������post����get |
| | | * @param method ����post/get |
| | | */ |
| | | public void setMethod(String method) { |
| | | this.method = method; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ������Ϣ |
| | | * @return String |
| | | */ |
| | | public String getErrInfo() { |
| | | return this.errInfo; |
| | | } |
| | | |
| | | /** |
| | | * ���ó�ʱʱ��,����Ϊ��λ |
| | | * @param timeOut ��ʱʱ��,����Ϊ��λ |
| | | */ |
| | | public void setTimeOut(int timeOut) { |
| | | this.timeOut = timeOut; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡhttp״̬�� |
| | | * @return int |
| | | */ |
| | | public int getResponseCode() { |
| | | return this.responseCode; |
| | | } |
| | | |
| | | /** |
| | | * ִ��http���á�true:�ɹ� false:ʧ�� |
| | | * @return boolean |
| | | */ |
| | | /* public boolean call() { |
| | | |
| | | boolean isRet = false; |
| | | |
| | | |
| | | //http |
| | | if(null == this.caFile && null == this.certFile) { |
| | | System.out.println("没有CA"); |
| | | try { |
| | | this.callHttp(); |
| | | isRet = true; |
| | | } catch (IOException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } |
| | | return isRet; |
| | | } |
| | | |
| | | //https |
| | | try { |
| | | this.callHttps(); |
| | | isRet = true; |
| | | } catch (UnrecoverableKeyException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (KeyManagementException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (CertificateException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (KeyStoreException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (NoSuchAlgorithmException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (IOException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } |
| | | |
| | | return isRet; |
| | | |
| | | }*/ |
| | | |
| | | /** |
| | | * ִ��http���á�true:�ɹ� false:ʧ�� |
| | | * @return boolean |
| | | */ |
| | | public boolean call() { |
| | | |
| | | boolean isRet = false; |
| | | |
| | | |
| | | //http |
| | | if(null == this.caFile && null == this.certFile) { |
| | | System.out.println("没有CA"); |
| | | try { |
| | | this.callHttp(); |
| | | isRet = true; |
| | | } catch (IOException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } |
| | | return isRet; |
| | | } |
| | | |
| | | //https |
| | | try { |
| | | this.callHttps(); |
| | | isRet = true; |
| | | } catch (UnrecoverableKeyException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (KeyManagementException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (CertificateException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (KeyStoreException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (NoSuchAlgorithmException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } catch (IOException e) { |
| | | this.errInfo = e.getMessage(); |
| | | } |
| | | |
| | | return isRet; |
| | | |
| | | } |
| | | |
| | | protected void callHttp() throws IOException { |
| | | |
| | | if("POST".equals(this.method.toUpperCase())) { |
| | | String url = HttpClientUtil.getURL(this.reqContent); |
| | | System.out.println("tenpayHttpClient:url:"+url); |
| | | //String queryString = HttpClientUtil.getQueryString(this.reqContent); |
| | | //byte[] postData = queryString.getBytes(this.charset); |
| | | |
| | | String queryString = createXmlPosData(); |
| | | byte[] postData = queryString.getBytes(this.charset); |
| | | this.httpPostMethod(url, postData); |
| | | |
| | | return ; |
| | | } |
| | | |
| | | this.httpGetMethod(this.reqContent); |
| | | |
| | | } |
| | | |
| | | protected void callHttps() throws IOException, CertificateException, |
| | | KeyStoreException, NoSuchAlgorithmException, |
| | | UnrecoverableKeyException, KeyManagementException { |
| | | // caĿ¼ |
| | | String caPath = this.caFile.getParent(); |
| | | |
| | | System.out.println("caPath:"+caPath); |
| | | File jksCAFile = new File(caPath + "/" |
| | | + TenpayHttpClient.JKS_CA_FILENAME); |
| | | if (!jksCAFile.isFile()) { |
| | | X509Certificate cert = (X509Certificate) HttpClientUtil |
| | | .getCertificate(this.caFile); |
| | | |
| | | FileOutputStream out = new FileOutputStream(jksCAFile); |
| | | |
| | | // store jks file |
| | | HttpClientUtil.storeCACert(cert, TenpayHttpClient.JKS_CA_ALIAS, |
| | | TenpayHttpClient.JKS_CA_PASSWORD, out); |
| | | |
| | | out.close(); |
| | | |
| | | } |
| | | |
| | | FileInputStream trustStream = new FileInputStream(jksCAFile); |
| | | FileInputStream keyStream = new FileInputStream(this.certFile); |
| | | |
| | | SSLContext sslContext = HttpClientUtil.getSSLContext(trustStream, |
| | | TenpayHttpClient.JKS_CA_PASSWORD, keyStream, this.certPasswd); |
| | | |
| | | //�ر��� |
| | | keyStream.close(); |
| | | trustStream.close(); |
| | | |
| | | if("POST".equals(this.method.toUpperCase())) { |
| | | String url = HttpClientUtil.getURL(this.reqContent); |
| | | |
| | | //原本是直接参数转为字节数组的,现在组拼xml |
| | | //String queryString = HttpClientUtil.getQueryString(this.reqContent);//获取链接下面的内容 |
| | | //byte[] postData = queryString.getBytes(this.charset);//把参数转为字节数组 |
| | | |
| | | //先获取参数 |
| | | String queryString = createXmlPosData(); |
| | | |
| | | byte[] postData = queryString.getBytes(this.charset);//把参数转为字节数组 |
| | | |
| | | this.httpsPostMethod(url, postData, sslContext); |
| | | |
| | | return ; |
| | | } |
| | | |
| | | this.httpsGetMethod(this.reqContent, sslContext); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ��http post��ʽͨ�� |
| | | * @param url |
| | | * @param postData |
| | | * @throws IOException |
| | | */ |
| | | protected void httpPostMethod(String url, byte[] postData) |
| | | throws IOException { |
| | | |
| | | HttpURLConnection conn = HttpClientUtil.getHttpURLConnection(url); |
| | | |
| | | this.doPost(conn, postData); |
| | | } |
| | | |
| | | /** |
| | | * ��http get��ʽͨ�� |
| | | * |
| | | * @param url |
| | | * @throws IOException |
| | | */ |
| | | protected void httpGetMethod(String url) throws IOException { |
| | | |
| | | HttpURLConnection httpConnection = |
| | | HttpClientUtil.getHttpURLConnection(url); |
| | | |
| | | this.setHttpRequest(httpConnection); |
| | | |
| | | httpConnection.setRequestMethod("GET"); |
| | | |
| | | this.responseCode = httpConnection.getResponseCode(); |
| | | |
| | | this.inputStream = httpConnection.getInputStream(); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ��https get��ʽͨ�� |
| | | * @param url |
| | | * @param sslContext |
| | | * @throws IOException |
| | | */ |
| | | protected void httpsGetMethod(String url, SSLContext sslContext) |
| | | throws IOException { |
| | | |
| | | SSLSocketFactory sf = sslContext.getSocketFactory(); |
| | | |
| | | HttpsURLConnection conn = HttpClientUtil.getHttpsURLConnection(url); |
| | | |
| | | conn.setSSLSocketFactory(sf); |
| | | |
| | | this.doGet(conn); |
| | | |
| | | } |
| | | |
| | | //提交https post 数据 s |
| | | protected void httpsPostMethod(String url, byte[] postData, |
| | | SSLContext sslContext) throws IOException { |
| | | |
| | | SSLSocketFactory sf = sslContext.getSocketFactory(); |
| | | |
| | | HttpsURLConnection conn = HttpClientUtil.getHttpsURLConnection(url); |
| | | |
| | | conn.setSSLSocketFactory(sf); |
| | | |
| | | this.doPost(conn, postData); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ����http����Ĭ������ |
| | | * @param httpConnection |
| | | */ |
| | | protected void setHttpRequest(HttpURLConnection httpConnection) { |
| | | |
| | | //�������ӳ�ʱʱ�� |
| | | httpConnection.setConnectTimeout(this.timeOut * 1000); |
| | | |
| | | //User-Agent |
| | | httpConnection.setRequestProperty("User-Agent", |
| | | TenpayHttpClient.USER_AGENT_VALUE); |
| | | |
| | | //��ʹ�û��� |
| | | httpConnection.setUseCaches(false); |
| | | |
| | | //����������� |
| | | httpConnection.setDoInput(true); |
| | | httpConnection.setDoOutput(true); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * ����Ӧ�� |
| | | * @throws IOException |
| | | */ |
| | | protected void doResponse() throws IOException { |
| | | |
| | | if(null == this.inputStream) { |
| | | return; |
| | | } |
| | | |
| | | //��ȡӦ������ |
| | | this.resContent=HttpClientUtil.InputStreamTOString(this.inputStream,this.charset); |
| | | |
| | | // System.out.println("tenpayHttpClinet:385:"+resContent); |
| | | //�ر������� |
| | | this.inputStream.close(); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * post��ʽ���� |
| | | * @param conn |
| | | * @param postData |
| | | * @throws IOException |
| | | */ |
| | | protected void doPost(HttpURLConnection conn, byte[] postData) |
| | | throws IOException { |
| | | |
| | | // ��post��ʽͨ�� |
| | | conn.setRequestMethod("POST"); |
| | | |
| | | // ��������Ĭ������ |
| | | this.setHttpRequest(conn); |
| | | |
| | | // Content-Type |
| | | conn.setRequestProperty("Content-Type", |
| | | "application/x-www-form-urlencoded"); |
| | | |
| | | BufferedOutputStream out = new BufferedOutputStream(conn |
| | | .getOutputStream()); |
| | | |
| | | final int len = 1024; // 1KB |
| | | HttpClientUtil.doOutput(out, postData, len); |
| | | |
| | | // �ر��� |
| | | out.close(); |
| | | |
| | | // ��ȡ��Ӧ����״̬�� |
| | | this.responseCode = conn.getResponseCode(); |
| | | |
| | | // ��ȡӦ�������� |
| | | this.inputStream = conn.getInputStream(); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * get��ʽ���� |
| | | * @param conn |
| | | * @throws IOException |
| | | */ |
| | | protected void doGet(HttpURLConnection conn) throws IOException { |
| | | |
| | | //��GET��ʽͨ�� |
| | | conn.setRequestMethod("GET"); |
| | | |
| | | //��������Ĭ������ |
| | | this.setHttpRequest(conn); |
| | | |
| | | //��ȡ��Ӧ����״̬�� |
| | | this.responseCode = conn.getResponseCode(); |
| | | |
| | | //��ȡӦ�������� |
| | | this.inputStream = conn.getInputStream(); |
| | | } |
| | | |
| | | public void setRequestHandler(RequestHandler reqHandler) { |
| | | this.reqHandler = reqHandler; |
| | | } |
| | | |
| | | |
| | | //组建xml格式传递参数 |
| | | @SuppressWarnings({ "rawtypes", "unused" }) |
| | | public String createXmlPosData(){ |
| | | //先获取参数 |
| | | Document document = DocumentHelper.createDocument(); |
| | | Element root = document.addElement("xml"); |
| | | |
| | | if(reqHandler==null)throw new RuntimeException("请先设入reqHandler"); |
| | | |
| | | SortedMap parameters = reqHandler.getAllParameters(); |
| | | Set es = reqHandler.getAllParameters().entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while(it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry)it.next(); |
| | | String k = (String)entry.getKey(); |
| | | String v = (String)entry.getValue(); |
| | | |
| | | Element ToUserName = root.addElement(k); |
| | | ToUserName.addText(v); |
| | | } |
| | | |
| | | String queryString = document.asXML();//转为String |
| | | |
| | | queryString = queryString.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "").trim(); |
| | | |
| | | System.out.println("xml:"+queryString); |
| | | return queryString; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | |
| | | public class TenpayUtil { |
| | | |
| | | /** |
| | | * �Ѷ���ת�����ַ� |
| | | * @param obj |
| | | * @return String ת�����ַ�,������Ϊnull,�ؿ��ַ�. |
| | | */ |
| | | public static String toString(Object obj) { |
| | | if(obj == null) |
| | | return ""; |
| | | |
| | | return obj.toString(); |
| | | } |
| | | |
| | | /** |
| | | * �Ѷ���ת��Ϊint��ֵ. |
| | | * |
| | | * @param obj |
| | | * �����ֵĶ���. |
| | | * @return int ת�������ֵ,�Բ���ת���Ķ���0�� |
| | | */ |
| | | public static int toInt(Object obj) { |
| | | int a = 0; |
| | | try { |
| | | if (obj != null) |
| | | a = Integer.parseInt(obj.toString()); |
| | | } catch (Exception e) { |
| | | |
| | | } |
| | | return a; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ��ǰʱ�� yyyyMMddHHmmss |
| | | * @return String |
| | | */ |
| | | public static String getCurrTime() { |
| | | Date now = new Date(); |
| | | SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss"); |
| | | String s = outFormat.format(now); |
| | | return s; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ��ǰ���� yyyyMMdd |
| | | * @param date |
| | | * @return String |
| | | */ |
| | | public static String formatDate(Date date) { |
| | | SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); |
| | | String strDate = formatter.format(date); |
| | | return strDate; |
| | | } |
| | | |
| | | /** |
| | | * ȡ��һ��ָ�����ȴ�С�����������. |
| | | * |
| | | * @param length |
| | | * int �趨��ȡ�������ij��ȡ�lengthС��11 |
| | | * @return int ������ɵ������ |
| | | */ |
| | | public static int buildRandom(int length) { |
| | | int num = 1; |
| | | double random = Math.random(); |
| | | if (random < 0.1) { |
| | | random = random + 0.1; |
| | | } |
| | | for (int i = 0; i < length; i++) { |
| | | num = num * 10; |
| | | } |
| | | return (int) ((random * num)); |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ�����ַ� |
| | | * @param request |
| | | * @param response |
| | | * @return String |
| | | */ |
| | | public static String getCharacterEncoding(HttpServletRequest request, |
| | | HttpServletResponse response) { |
| | | |
| | | if(null == request || null == response) { |
| | | return "utf-8"; |
| | | } |
| | | |
| | | String enc = request.getCharacterEncoding(); |
| | | if(null == enc || "".equals(enc)) { |
| | | enc = response.getCharacterEncoding(); |
| | | } |
| | | |
| | | if(null == enc || "".equals(enc)) { |
| | | enc = "utf-8"; |
| | | } |
| | | |
| | | return enc; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡunixʱ�䣬��1970-01-01 00:00:00��ʼ������ |
| | | * @param date |
| | | * @return long |
| | | */ |
| | | public static long getUnixTime(Date date) { |
| | | if( null == date ) { |
| | | return 0; |
| | | } |
| | | |
| | | return date.getTime()/1000; |
| | | } |
| | | |
| | | /** |
| | | * ʱ��ת�����ַ� |
| | | * @param date ʱ�� |
| | | * @param formatType ��ʽ������ |
| | | * @return String |
| | | */ |
| | | public static String date2String(Date date, String formatType) { |
| | | SimpleDateFormat sdf = new SimpleDateFormat(formatType); |
| | | return sdf.format(date); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.hx.exception.ServiceException; |
| | | import com.hx.util.SimpleTool; |
| | | import com.hx.util.StringUtils; |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.apache.http.HttpEntity; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpPost; |
| | | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
| | | import org.apache.http.entity.StringEntity; |
| | | import org.apache.http.impl.client.CloseableHttpClient; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | import org.apache.http.ssl.SSLContexts; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.dom4j.Document; |
| | | import org.dom4j.Element; |
| | | import org.dom4j.io.SAXReader; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.security.KeyStore; |
| | | import java.util.*; |
| | | |
| | | |
| | | /** 微信支付/退款 |
| | | * @author ChenJiaHe |
| | | */ |
| | | public class WXPayUtil { |
| | | |
| | | // 退款接口连接 |
| | | private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund"; |
| | | /**查询订单链接*/ |
| | | @SuppressWarnings("unused") |
| | | private static final String QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; |
| | | |
| | | /**同意下单链接*/ |
| | | private static final String FIRST_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; |
| | | |
| | | // 企业付款 |
| | | private static final String CORP_PAY_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; |
| | | |
| | | |
| | | /** 企业付款*/ |
| | | public static JSONObject qdCorpPay(String appId, String orderNo, String certPath, String mchid, String mchKey, String openId, String payFee, String desc) |
| | | throws Exception { |
| | | |
| | | SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); |
| | | parameters.put("mch_appid", appId); |
| | | parameters.put("mchid", mchid); |
| | | parameters.put("partner_trade_no", orderNo); |
| | | parameters.put("nonce_str", UUID.randomUUID().toString().substring(0, 30)); |
| | | parameters.put("openid", openId); |
| | | parameters.put("check_name", "NO_CHECK"); |
| | | parameters.put("amount", payFee); |
| | | parameters.put("spbill_create_ip", "8.8.8.8"); |
| | | parameters.put("desc", desc); |
| | | |
| | | String sign = WXSignUtils.createSign("UTF-8", parameters, mchKey); |
| | | |
| | | parameters.put("sign", sign); |
| | | String xmlInfo = HttpXmlUtils.transferXml(parameters); |
| | | |
| | | JSONObject returnObj = new JSONObject(); |
| | | |
| | | try { |
| | | CloseableHttpResponse response = HttpUtil.Post(CORP_PAY_URL, xmlInfo, true, certPath, mchid); |
| | | String transfersXml = EntityUtils.toString(response.getEntity(), "utf-8"); |
| | | // System.out.println("渠道端企业付款:" + transfersXml); |
| | | Map<String, String> transferMap = HttpXmlUtils.parseRefundXml(transfersXml); |
| | | boolean bl = false; |
| | | if (transferMap.size() > 0) { |
| | | if (transferMap.get("return_code").equals("SUCCESS")) { |
| | | // 通讯成功 |
| | | if (transferMap.get("result_code").equals("SUCCESS")) { |
| | | // 成功需要进行的逻辑操作 |
| | | returnObj.put("status", "suc"); |
| | | } else { |
| | | bl = true; |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", transferMap.get("err_code") + "|" + transferMap.get("err_code_des")); |
| | | } |
| | | } else { |
| | | bl = true; |
| | | // 通讯不成功 |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", transferMap.get("return_msg")); |
| | | } |
| | | } else { |
| | | bl = true; |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", "返回为空"); |
| | | } |
| | | if (bl) { |
| | | System.out.println("企业付款失败:" + transfersXml); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", e.getMessage()); |
| | | } |
| | | |
| | | return returnObj; |
| | | } |
| | | |
| | | /**统一支付 |
| | | * @param request 方法获取 |
| | | * @param appId 小程序号 |
| | | * @param partner 商户号 |
| | | * @param key 秘钥 |
| | | * @param notifyUrl 回调链接 |
| | | * @param out_trade_no 订单号 |
| | | * @param body 商品描述 |
| | | * @param total_fee 支付金额 |
| | | * @param openid 用户openId |
| | | * @param attach 附带数据包 |
| | | * @param notifyUrl 回调通知地址 |
| | | * @param trade_type 交易类型 |
| | | * @return JSON status = "SUC"为成功 |
| | | */ |
| | | public static JSONObject unifiedPay(HttpServletRequest request,String appId,String partner,String key,String notifyUrl,String out_trade_no, String body, String total_fee, String openid, |
| | | String attach,String trade_type) throws Exception { |
| | | |
| | | if (!SimpleTool.checkNotNull(notifyUrl)) { |
| | | throw new ServiceException("支付功能故障!"); |
| | | } |
| | | |
| | | // 创建查询请求对象 |
| | | RequestHandler reqHandler = new RequestHandler(null, null); |
| | | // 通信对象 |
| | | TenpayHttpClient httpClient = new TenpayHttpClient(); |
| | | // 应答对象 |
| | | ClientResponseHandler resHandler = new ClientResponseHandler(); |
| | | |
| | | // ----------------------------- |
| | | // 设置请求参数 |
| | | // ----------------------------- |
| | | // reqHandler.init(); |
| | | reqHandler.setKey(key); |
| | | reqHandler.setGateUrl(FIRST_ORDER_URL);// 请求URL |
| | | |
| | | // ----------------------------- |
| | | // 设置接口参数(sign后台自动生成) |
| | | // ----------------------------- |
| | | reqHandler.setParameter("appid", appId); // 公众号/小程序 |
| | | reqHandler.setParameter("mch_id", partner); // 商户号 |
| | | reqHandler.setParameter("nonce_str", SimpleTool.getUUIDName().substring(0, 30));// 随机乱码 |
| | | reqHandler.setParameter("body", body);// 商品描述 |
| | | reqHandler.setParameter("out_trade_no", out_trade_no);// 商户订单号 |
| | | reqHandler.setParameter("total_fee", total_fee);// 总金额 |
| | | reqHandler.setParameter("spbill_create_ip", "8.8.8.8");// 终端IP |
| | | reqHandler.setParameter("notify_url",notifyUrl);// 通知地址 |
| | | reqHandler.setParameter("trade_type", trade_type);// 交易类型 |
| | | // JSAPI,NATIVE,APP |
| | | reqHandler.setParameter("openid", openid);// openId |
| | | reqHandler.setParameter("attach", attach);// 附带数据包 |
| | | |
| | | // ----------------------------- |
| | | // 设置通信参数 |
| | | // ----------------------------- |
| | | // 设置请求返回的等待时间 |
| | | httpClient.setTimeOut(5); |
| | | |
| | | // 设置ca证书 |
| | | // httpClient.setCaInfo(new File(CA_PATH)); |
| | | |
| | | // 设置个人(商户)证书 |
| | | // httpClient.setCertInfo(new File(CERT_PATH), CERT_PWD); |
| | | |
| | | // 设置发送类型POST |
| | | httpClient.setMethod("POST"); |
| | | |
| | | // 设置请求内容(生成sign) |
| | | String requestUrl = reqHandler.getRequestURL();// 组拼https://www.baidu.com?a=x&b=xx |
| | | |
| | | httpClient.setReqContent(requestUrl);// https://www.baidu.com?a=x&b=xx |
| | | String rescontent = "null"; |
| | | |
| | | httpClient.setRequestHandler(reqHandler);// 把处理对象,像是参数各种东西都设置进去方便获取(quan) |
| | | |
| | | // 返回出去的对象(状态,错误原因,该操作相关信息(参数,返回值)) |
| | | JSONObject returnObj = new JSONObject(); |
| | | |
| | | // 后台调用 |
| | | if (httpClient.call()) { |
| | | System.out.println("统一下单,成功cll了::"); |
| | | |
| | | // 设置结果参数 |
| | | rescontent = httpClient.getResContent(); |
| | | System.out.println("统一下单返回结果:" + rescontent); |
| | | resHandler.setContent(rescontent);// 解析xml |
| | | resHandler.setKey(key); |
| | | |
| | | // 获取返回参数 |
| | | String return_code = resHandler.getParameter("return_code"); |
| | | String return_msg = resHandler.getParameter("return_msg"); |
| | | |
| | | // 判断签名及结果 |
| | | if (resHandler.isTenpaySign() && "SUCCESS".equals(return_code)) { |
| | | String prepay_id = resHandler.getParameter("prepay_id");// 预支付交易会话标识 |
| | | String code_url = resHandler.getParameter("code_url");// 二维码链接 |
| | | |
| | | String result_code = resHandler.getParameter("result_code");// 业务结果 |
| | | String appid = resHandler.getParameter("appid");// 公众账号ID |
| | | String mch_id = resHandler.getParameter("mch_id");// 商户号 |
| | | String nonce_str = resHandler.getParameter("nonce_str");// 随机码 |
| | | String sign = resHandler.getParameter("sign");// 签名 |
| | | |
| | | if (result_code.equals("SUCCESS")) { |
| | | returnObj.put("status", "suc"); |
| | | returnObj.put("sign", sign); |
| | | returnObj.put("nonce_str", nonce_str); |
| | | returnObj.put("mch_id", mch_id); |
| | | returnObj.put("appid", appid); |
| | | returnObj.put("prepay_id", prepay_id); |
| | | returnObj.put("code_url", code_url); |
| | | returnObj.put("out_trade_no", out_trade_no); |
| | | } else { |
| | | String errMsg = "[ERROR]result_code:" + resHandler.getParameter("result_code") + " err_code:" |
| | | + resHandler.getParameter("err_code") + "err_code_des:" |
| | | + resHandler.getParameter("err_code_des"); |
| | | |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-C"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | String errMsg = "return_code:" + return_code + "err_code:" + resHandler.getParameter("err_code") |
| | | + " return_msg:" + return_msg; |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-B"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | // 有可能因为网络原因,请求已经处理,但未收到应答。 |
| | | returnObj.put("status", "ERROR-A"); |
| | | returnObj.put("errMsg", httpClient.getResponseCode() + ":" + httpClient.getErrInfo()); |
| | | } |
| | | |
| | | // 获取debug信息,建议把请求、应答内容、debug信息,通信返回码写入日志,方便定位问题 |
| | | String detail = "http res:" + httpClient.getResponseCode() + "," + httpClient.getErrInfo() + ";" + "req url:" |
| | | + requestUrl + ";" + ";" + "req debug:" + reqHandler.getDebugInfo() + ";" + "res content:" + rescontent |
| | | + ";" + "res debug:" + resHandler.getDebugInfo() + ";"; |
| | | |
| | | returnObj.put("detail", detail); |
| | | |
| | | |
| | | return returnObj; |
| | | } |
| | | |
| | | /**统一支付(分账) |
| | | * @param request 方法获取 |
| | | * @param appId 小程序号 |
| | | * @param partner 商户号 |
| | | * @param key 秘钥 |
| | | * @param notifyUrl 回调链接 |
| | | * @param out_trade_no 订单号 |
| | | * @param body 商品描述 |
| | | * @param total_fee 支付金额 |
| | | * @param openid 用户openId |
| | | * @param attach 附带数据包 |
| | | * @param notifyUrl 回调通知地址 |
| | | * @param trade_type 交易类型 |
| | | * @param profit_sharing 是否分账:N不,Y是 |
| | | * @return JSON status = "SUC"为成功 |
| | | */ |
| | | public static JSONObject unifiedPay(HttpServletRequest request,String appId,String partner,String key,String notifyUrl,String out_trade_no, String body, String total_fee, String openid, |
| | | String attach,String trade_type,String profit_sharing) throws Exception { |
| | | |
| | | if (!SimpleTool.checkNotNull(notifyUrl)) { |
| | | throw new ServiceException("支付功能故障!"); |
| | | } |
| | | |
| | | // 创建查询请求对象 |
| | | RequestHandler reqHandler = new RequestHandler(null, null); |
| | | // 通信对象 |
| | | TenpayHttpClient httpClient = new TenpayHttpClient(); |
| | | // 应答对象 |
| | | ClientResponseHandler resHandler = new ClientResponseHandler(); |
| | | |
| | | // ----------------------------- |
| | | // 设置请求参数 |
| | | // ----------------------------- |
| | | // reqHandler.init(); |
| | | reqHandler.setKey(key); |
| | | reqHandler.setGateUrl(FIRST_ORDER_URL);// 请求URL |
| | | |
| | | // ----------------------------- |
| | | // 设置接口参数(sign后台自动生成) |
| | | // ----------------------------- |
| | | |
| | | reqHandler.setParameter("appid", appId); // 公众号/小程序 |
| | | reqHandler.setParameter("mch_id", partner); // 商户号 |
| | | reqHandler.setParameter("nonce_str", SimpleTool.getUUIDName().substring(0, 30));// 随机乱码 |
| | | reqHandler.setParameter("body", body);// 商品描述 |
| | | reqHandler.setParameter("out_trade_no", out_trade_no);// 商户订单号 |
| | | reqHandler.setParameter("total_fee", total_fee);// 总金额 |
| | | reqHandler.setParameter("spbill_create_ip", "8.8.8.8");// 终端IP |
| | | reqHandler.setParameter("notify_url",notifyUrl);// 通知地址 |
| | | reqHandler.setParameter("trade_type", trade_type);// 交易类型 |
| | | //JSAPI,NATIVE,APP |
| | | reqHandler.setParameter("openid", openid);// openId |
| | | reqHandler.setParameter("attach", attach);// 附带数据包 |
| | | reqHandler.setParameter("profit_sharing", profit_sharing);// 附带数据包 |
| | | |
| | | // ----------------------------- |
| | | // 设置通信参数 |
| | | // ----------------------------- |
| | | // 设置请求返回的等待时间 |
| | | httpClient.setTimeOut(5); |
| | | |
| | | // 设置ca证书 |
| | | // httpClient.setCaInfo(new File(CA_PATH)); |
| | | |
| | | // 设置个人(商户)证书 |
| | | // httpClient.setCertInfo(new File(CERT_PATH), CERT_PWD); |
| | | |
| | | // 设置发送类型POST |
| | | httpClient.setMethod("POST"); |
| | | |
| | | // 设置请求内容(生成sign) |
| | | String requestUrl = reqHandler.getRequestURL();// 组拼https://www.baidu.com?a=x&b=xx |
| | | |
| | | httpClient.setReqContent(requestUrl);// https://www.baidu.com?a=x&b=xx |
| | | String rescontent = "null"; |
| | | |
| | | httpClient.setRequestHandler(reqHandler);// 把处理对象,像是参数各种东西都设置进去方便获取(quan) |
| | | |
| | | // 返回出去的对象(状态,错误原因,该操作相关信息(参数,返回值)) |
| | | JSONObject returnObj = new JSONObject(); |
| | | |
| | | // 后台调用 |
| | | if (httpClient.call()) { |
| | | System.out.println("统一下单,成功cll了::"); |
| | | |
| | | // 设置结果参数 |
| | | rescontent = httpClient.getResContent(); |
| | | System.out.println("统一下单返回结果:" + rescontent); |
| | | resHandler.setContent(rescontent);// 解析xml |
| | | resHandler.setKey(key); |
| | | |
| | | // 获取返回参数 |
| | | String return_code = resHandler.getParameter("return_code"); |
| | | String return_msg = resHandler.getParameter("return_msg"); |
| | | |
| | | // 判断签名及结果 |
| | | if (resHandler.isTenpaySign() && "SUCCESS".equals(return_code)) { |
| | | String prepay_id = resHandler.getParameter("prepay_id");// 预支付交易会话标识 |
| | | String code_url = resHandler.getParameter("code_url");// 二维码链接 |
| | | |
| | | String result_code = resHandler.getParameter("result_code");// 业务结果 |
| | | String appid = resHandler.getParameter("appid");// 公众账号ID |
| | | String mch_id = resHandler.getParameter("mch_id");// 商户号 |
| | | String nonce_str = resHandler.getParameter("nonce_str");// 随机码 |
| | | String sign = resHandler.getParameter("sign");// 签名 |
| | | |
| | | if (result_code.equals("SUCCESS")) { |
| | | returnObj.put("status", "suc"); |
| | | returnObj.put("sign", sign); |
| | | returnObj.put("nonce_str", nonce_str); |
| | | returnObj.put("mch_id", mch_id); |
| | | returnObj.put("appid", appid); |
| | | returnObj.put("prepay_id", prepay_id); |
| | | returnObj.put("code_url", code_url); |
| | | returnObj.put("out_trade_no", out_trade_no); |
| | | } else { |
| | | String errMsg = "[ERROR]result_code:" + resHandler.getParameter("result_code") + " err_code:" |
| | | + resHandler.getParameter("err_code") + "err_code_des:" |
| | | + resHandler.getParameter("err_code_des"); |
| | | |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-C"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | String errMsg = "return_code:" + return_code + "err_code:" + resHandler.getParameter("err_code") |
| | | + " return_msg:" + return_msg; |
| | | // 错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | returnObj.put("status", "ERROR-B"); |
| | | returnObj.put("errMsg", errMsg); |
| | | } |
| | | } else { |
| | | // 有可能因为网络原因,请求已经处理,但未收到应答。 |
| | | returnObj.put("status", "ERROR-A"); |
| | | returnObj.put("errMsg", httpClient.getResponseCode() + ":" + httpClient.getErrInfo()); |
| | | } |
| | | |
| | | // 获取debug信息,建议把请求、应答内容、debug信息,通信返回码写入日志,方便定位问题 |
| | | String detail = "http res:" + httpClient.getResponseCode() + "," + httpClient.getErrInfo() + ";" + "req url:" |
| | | + requestUrl + ";" + ";" + "req debug:" + reqHandler.getDebugInfo() + ";" + "res content:" + rescontent |
| | | + ";" + "res debug:" + resHandler.getDebugInfo() + ";"; |
| | | |
| | | returnObj.put("detail", detail); |
| | | |
| | | |
| | | return returnObj; |
| | | } |
| | | |
| | | /**处理信息 |
| | | */ |
| | | public static JSONObject paymentData(JSONObject payObj,String key){ |
| | | JSONObject wxObj = new JSONObject(); |
| | | /**统一下单*/ |
| | | String payStatus = payObj.getString("status"); |
| | | if (payStatus.equals("suc")) { |
| | | // JSONObject payObj = po.getJSONObject("inf"); |
| | | String appId = payObj.getString("appid"); |
| | | String nonceStr = payObj.getString("nonce_str"); |
| | | String prepay_id = payObj.getString("prepay_id"); |
| | | // JSAPI调用支付返回的数据 |
| | | String timeStamp = SimpleTool.getTenTime(new Date()).toString(); |
| | | String signType = "MD5"; |
| | | String packagef = "prepay_id=" + prepay_id; |
| | | RequestHandler reqHandler = new RequestHandler(null, null); |
| | | reqHandler.setParameter("appId", appId); |
| | | reqHandler.setParameter("nonceStr", nonceStr); |
| | | reqHandler.setParameter("timeStamp", timeStamp); |
| | | reqHandler.setParameter("package", packagef); |
| | | reqHandler.setParameter("signType", signType); |
| | | reqHandler.setKey(key); |
| | | String paySign = reqHandler.createSign();// 生成签名 |
| | | wxObj.put("orderNo", payObj.getString("out_trade_no")); |
| | | wxObj.put("paySign", paySign); |
| | | wxObj.put("appId", appId); |
| | | wxObj.put("nonceStr", nonceStr); |
| | | wxObj.put("package", packagef); |
| | | wxObj.put("timeStamp", timeStamp); |
| | | } else { |
| | | throw new RuntimeException(payObj.toString()); |
| | | } |
| | | return wxObj; |
| | | } |
| | | |
| | | /** |
| | | * 退款 |
| | | * @param appId 小程序/公众号 appId |
| | | * @param partner 商户号 |
| | | * @param key 商户号秘钥 |
| | | * @param certPath 个人商户证书 |
| | | * @param out_trade_no 商户订单号 |
| | | * @param transaction_id 财付通订单号(微信订单号) |
| | | * @param out_refund_no 商户退单号 |
| | | * @param total_fee 订单总额(单位:分) |
| | | * @param refund_fee 退款金额(单位:分) |
| | | * @return JSON status="SUCCESS"(成功) (状态,错误原因,该操作相关信息(参数,返回值)) |
| | | */ |
| | | public static JSONObject refund(String appId,String partner,String key,String certPath,String out_trade_no, String transaction_id, String out_refund_no, String total_fee, |
| | | String refund_fee) { |
| | | try{ |
| | | KeyStore keyStore = KeyStore.getInstance("PKCS12"); |
| | | FileInputStream instream = new FileInputStream(new File(certPath)); |
| | | try { |
| | | keyStore.load(instream,partner.toCharArray()); |
| | | }finally { |
| | | instream.close(); |
| | | } |
| | | // Trust own CA and all self-signed certs |
| | | SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,partner.toCharArray()).build(); |
| | | // Allow TLSv1 protocol only |
| | | SSLConnectionSocketFactory sslsf; |
| | | sslsf = new SSLConnectionSocketFactory( |
| | | sslcontext, new String[] { "TLSv1" }, null, |
| | | SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); |
| | | CloseableHttpClient httpclient = HttpClients.custom() |
| | | .setSSLSocketFactory(sslsf).build(); |
| | | HttpPost httppost = new HttpPost(REFUND_URL); |
| | | String xml = wxPayRefundData(appId, partner, key, out_trade_no, transaction_id, out_refund_no, total_fee, refund_fee); |
| | | try { |
| | | StringEntity se = new StringEntity(xml); |
| | | httppost.setEntity(se); |
| | | |
| | | CloseableHttpResponse responseEntry = httpclient.execute(httppost); |
| | | try { |
| | | HttpEntity entity = responseEntry.getEntity(); |
| | | if (entity != null) { |
| | | |
| | | SAXReader saxReader = new SAXReader(); |
| | | Document document = saxReader.read(entity.getContent()); |
| | | Element rootElt = document.getRootElement(); |
| | | String returnCode = rootElt.elementText("return_code"); |
| | | JSONObject result = new JSONObject(); |
| | | |
| | | if(returnCode.equals("SUCCESS")){ |
| | | String resultCode = rootElt.elementText("result_code"); |
| | | if(resultCode.equals("SUCCESS")) { |
| | | result.put("weixinPayUrl", rootElt.elementText("code_url")); |
| | | result.put("prepayId", rootElt.elementText("prepay_id")); |
| | | result.put("msg", "success"); |
| | | |
| | | String refund_id = rootElt.elementText("refund_id");//微信退款单号 |
| | | String r_out_refund_no = rootElt.elementText("out_refund_no"); |
| | | String errMsg = "商户号" + r_out_refund_no + "的退款流水号是:" + refund_id; |
| | | result.put("status", "SUCCESS"); |
| | | result.put("errMsg", errMsg); |
| | | result.put("refund_id", refund_id); |
| | | }else{ |
| | | String errMsg = "[ERROR]result_code:" + rootElt.elementText("result_code")+ |
| | | " err_code:" + rootElt.elementText("err_code"); |
| | | |
| | | //错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | result.put("errMsg", errMsg); |
| | | result.put("status","false"); |
| | | result.put("msg",rootElt.elementText("err_code_des")); |
| | | } |
| | | }else{ |
| | | String errMsg = "[ERROR]return_code:" + rootElt.elementText("return_code"); |
| | | |
| | | //错误时,返回结果未签名,记录retcode、retmsg看失败详情。 |
| | | result.put("errMsg", errMsg); |
| | | result.put("status","false"); |
| | | result.put("msg",rootElt.elementText("return_msg")); |
| | | } |
| | | return result; |
| | | } |
| | | EntityUtils.consume(entity); |
| | | } |
| | | finally { |
| | | responseEntry.close(); |
| | | } |
| | | } |
| | | finally { |
| | | httpclient.close(); |
| | | } |
| | | return null; |
| | | }catch(Exception e){ |
| | | e.printStackTrace(); |
| | | JSONObject result = new JSONObject(); |
| | | result.put("status","error"); |
| | | result.put("msg",e.getMessage()); |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | /** 封装参数数据 |
| | | * @param appId 小程序/公众号 appId |
| | | * @param partner 商户号 |
| | | * @param key 商户号秘钥 |
| | | * @param out_trade_no 商户订单号 |
| | | * @param transaction_id 财付通订单号(微信订单号) |
| | | * @param out_refund_no 商户退单号 |
| | | * @param total_fee 订单总额(单位:分) |
| | | * @param refund_fee 退款金额(单位:分) |
| | | * @return |
| | | */ |
| | | public static String wxPayRefundData(String appId,String partner,String key,String out_trade_no, String transaction_id,String out_refund_no,String total_fee,String refund_fee) { |
| | | StringBuffer xml = new StringBuffer(); |
| | | String data = null; |
| | | try { |
| | | String nonceStr = SimpleTool.getUUIDName().substring(0,30); |
| | | xml.append("</xml>"); |
| | | SortedMap<String,String> parameters = new TreeMap<String,String>(); |
| | | parameters.put("appid",appId); |
| | | parameters.put("mch_id",partner); |
| | | parameters.put("nonce_str", nonceStr); |
| | | if(!StringUtils.isEmpty(out_trade_no)) { |
| | | parameters.put("out_trade_no", out_trade_no); |
| | | } |
| | | if(!StringUtils.isEmpty(transaction_id)) { |
| | | parameters.put("transaction_id", transaction_id); |
| | | } |
| | | parameters.put("out_refund_no", out_refund_no); |
| | | parameters.put("fee_type", "CNY"); |
| | | parameters.put("total_fee", total_fee);//总金额 |
| | | parameters.put("refund_fee", refund_fee);//退款金额 |
| | | parameters.put("op_user_id",partner); |
| | | parameters.put("sign", createSign(parameters,key)); |
| | | |
| | | data =SortedMaptoXml(parameters); |
| | | } catch (Exception e) { |
| | | System.err.println(e.getMessage()); |
| | | return null; |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | /** |
| | | * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 |
| | | */ |
| | | public static String createSign(SortedMap<String, String> packageParams, String AppKey) { |
| | | StringBuffer sb; |
| | | sb = new StringBuffer(); |
| | | Set es = packageParams.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | while (it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry) it.next(); |
| | | String k = (String) entry.getKey(); |
| | | String v = (String) entry.getValue(); |
| | | if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { |
| | | sb.append(k + "=" + v + "&"); |
| | | } |
| | | } |
| | | sb.append("key=" + AppKey); |
| | | String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); |
| | | return sign; |
| | | } |
| | | |
| | | /** |
| | | * @Author: HONGLINCHEN |
| | | * @Description:请求值转换为xml格式 SortedMap转xml |
| | | * @param params |
| | | * @Date: 2017-9-7 17:18 |
| | | */ |
| | | private static String SortedMaptoXml(SortedMap<String,String> params) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | Set es = params.entrySet(); |
| | | Iterator it = es.iterator(); |
| | | sb.append("<xml>\n"); |
| | | while(it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry)it.next(); |
| | | String k = (String)entry.getKey(); |
| | | Object v = entry.getValue(); |
| | | sb.append("<"+k+">"); |
| | | sb.append(v); |
| | | sb.append("</"+k+">\n"); |
| | | } |
| | | sb.append("</xml>"); |
| | | return sb.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.SortedMap; |
| | | |
| | | public class WXSignUtils { |
| | | /** |
| | | * 微信支付签名算法sign |
| | | * @param characterEncoding |
| | | * @param parameters |
| | | * @return |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public static String createSign(String characterEncoding, SortedMap<Object,Object> parameters, String key){ |
| | | StringBuffer sb = new StringBuffer(); |
| | | Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序) |
| | | Iterator it = es.iterator(); |
| | | while(it.hasNext()) { |
| | | Map.Entry entry = (Map.Entry)it.next(); |
| | | String k = (String)entry.getKey(); |
| | | Object v = entry.getValue(); |
| | | if(null != v && !"".equals(v) |
| | | && !"sign".equals(k) && !"key".equals(k)) { |
| | | sb.append(k + "=" + v + "&"); |
| | | } |
| | | } |
| | | sb.append("key=" + key); |
| | | String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); |
| | | return sign; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; |
| | | import net.sf.json.JSONObject; |
| | | import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.security.AlgorithmParameters; |
| | | import java.security.InvalidAlgorithmParameterException; |
| | | import java.security.InvalidKeyException; |
| | | import java.security.Key; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.security.NoSuchProviderException; |
| | | import java.security.Security; |
| | | |
| | | import javax.crypto.BadPaddingException; |
| | | import javax.crypto.Cipher; |
| | | import javax.crypto.IllegalBlockSizeException; |
| | | import javax.crypto.NoSuchPaddingException; |
| | | import javax.crypto.spec.IvParameterSpec; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | |
| | | |
| | | public class WechatUtil { |
| | | public static boolean initialized = false; |
| | | |
| | | //log4j日志 |
| | | private static Logger logger = LoggerFactory.getLogger(WechatUtil.class.getName()); |
| | | |
| | | public static JSONObject encryptedData(String encryptedData, String session_key, String iv) throws Exception { |
| | | JSONObject encrypted_obj = null; |
| | | byte[] resultByte =decrypt(Base64.decode(encryptedData), |
| | | Base64.decode(session_key), |
| | | Base64.decode(iv)); |
| | | if(null != resultByte && resultByte.length > 0){ |
| | | String userInfo = new String(resultByte, "UTF-8"); |
| | | encrypted_obj = JSONObject.fromObject(userInfo); |
| | | }else{ |
| | | logger.error("获取unionid解密失败:encryptedData="+encryptedData+";session_key="+session_key+";iv="+iv); |
| | | } |
| | | return encrypted_obj; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * AES解密 |
| | | * @param content 密文 |
| | | * @return |
| | | * @throws InvalidAlgorithmParameterException |
| | | * @throws NoSuchProviderException |
| | | */ |
| | | public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws Exception { |
| | | initialize(); |
| | | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); |
| | | Key sKeySpec = new SecretKeySpec(keyByte, "AES"); |
| | | |
| | | cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化 |
| | | byte[] result = cipher.doFinal(content); |
| | | return result; |
| | | } |
| | | |
| | | public static void initialize(){ |
| | | if (initialized) return; |
| | | Security.addProvider(new BouncyCastleProvider()); |
| | | initialized = true; |
| | | } |
| | | //生成iv |
| | | public static AlgorithmParameters generateIV(byte[] iv) throws Exception{ |
| | | AlgorithmParameters params = AlgorithmParameters.getInstance("AES"); |
| | | params.init(new IvParameterSpec(iv)); |
| | | return params; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import net.sf.json.JSONObject; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.util.EntityUtils; |
| | | |
| | | import java.util.Map; |
| | | import java.util.SortedMap; |
| | | import java.util.TreeMap; |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * 微信小程序支付相关工具类 |
| | | */ |
| | | public class WxMpPayUtil { |
| | | |
| | | /**小程序红包发送链接*/ |
| | | private static final String URL_SEND_RED_PACK = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendminiprogramhb"; |
| | | |
| | | /** |
| | | * 发送小程序红包 |
| | | * @param orderNo 订单号 |
| | | * @param mchId 商户号 |
| | | * @param mchKey 商户密钥 |
| | | * @param appId 小程序appId |
| | | * @param sendName 发送者名称 |
| | | * @param openId 接收者openId |
| | | * @param payFee 红包金额,以分为单位 |
| | | * @param wishing 祝福语 |
| | | * @param actName 活动名称 |
| | | * @param remark 备注 |
| | | * @param certPath 支付证书路径 |
| | | * @return |
| | | */ |
| | | public static JSONObject sendMiniProgramReadPack(String orderNo, String mchId, String mchKey, String appId, String sendName, String openId, |
| | | int payFee, String wishing, String actName, String remark, String certPath) |
| | | { |
| | | SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); |
| | | parameters.put("nonce_str", UUID.randomUUID().toString().substring(0, 30)); |
| | | parameters.put("mch_billno", orderNo);//商户订单号 |
| | | parameters.put("mchid", mchId);//商户号 |
| | | parameters.put("wxappid", appId);//公众账号appId |
| | | parameters.put("send_name", sendName);//红包发送者名称 |
| | | parameters.put("re_openid", openId);//用户openId |
| | | parameters.put("total_amount", payFee);//红包总金额,以分为单位 |
| | | parameters.put("total_num", 1);//红包数量,固定为1 |
| | | parameters.put("wishing", wishing);//红包祝福语,128字符 |
| | | parameters.put("act_name", actName);//活动名称 |
| | | parameters.put("remark", remark);//备注 |
| | | parameters.put("notify_way", "MINI_PROGRAM_JSAPI");//通知用户形式,固定 |
| | | |
| | | String sign = WXSignUtils.createSign("UTF-8", parameters, mchKey); |
| | | |
| | | parameters.put("sign", sign); |
| | | String xmlInfo = HttpXmlUtils.transferXml(parameters); |
| | | |
| | | JSONObject returnObj = new JSONObject(); |
| | | |
| | | try { |
| | | CloseableHttpResponse response = HttpUtil.Post(URL_SEND_RED_PACK, xmlInfo, true, certPath, mchId); |
| | | String transfersXml = EntityUtils.toString(response.getEntity(), "utf-8"); |
| | | Map<String, String> transferMap = HttpXmlUtils.parseRefundXml(transfersXml); |
| | | boolean bl = false; |
| | | if (transferMap.size() > 0) { |
| | | if (transferMap.get("return_code").equals("SUCCESS")) { |
| | | // 通讯成功 |
| | | if (transferMap.get("result_code").equals("SUCCESS")) { |
| | | // 成功需要进行的逻辑操作 |
| | | returnObj.put("status", "suc"); |
| | | } else { |
| | | bl = true; |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", transferMap.get("err_code") + "|" + transferMap.get("err_code_des")); |
| | | } |
| | | } else { |
| | | bl = true; |
| | | // 通讯不成功 |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", transferMap.get("return_msg")); |
| | | } |
| | | } else { |
| | | bl = true; |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", "返回为空"); |
| | | } |
| | | if (bl) { |
| | | System.out.println("企业付款失败:" + transfersXml); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | returnObj.put("status", "fail"); |
| | | returnObj.put("errMsg", e.getMessage()); |
| | | } |
| | | |
| | | return returnObj; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mp.util; |
| | | |
| | | import org.jdom.Document; |
| | | import org.jdom.Element; |
| | | import org.jdom.JDOMException; |
| | | import org.jdom.input.SAXBuilder; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * xml������ |
| | | *JX |
| | | *linhan |
| | | */ |
| | | public class XMLUtil { |
| | | |
| | | /** |
| | | * ����xml,���ص�һ��Ԫ�ؼ�ֵ�ԡ�����һ��Ԫ�����ӽڵ㣬��˽ڵ��ֵ���ӽڵ��xml��ݡ� |
| | | * @param strxml |
| | | * @return |
| | | * @throws JDOMException |
| | | * @throws IOException |
| | | */ |
| | | @SuppressWarnings({ "rawtypes", "unchecked" }) |
| | | public static Map doXMLParse(String strxml) throws JDOMException, IOException { |
| | | strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\""); |
| | | |
| | | if(null == strxml || "".equals(strxml)) { |
| | | return null; |
| | | } |
| | | |
| | | Map m = new HashMap(); |
| | | |
| | | InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8")); |
| | | SAXBuilder builder = new SAXBuilder(); |
| | | Document doc = builder.build(in); |
| | | Element root = doc.getRootElement(); |
| | | List list = root.getChildren(); |
| | | Iterator it = list.iterator(); |
| | | while(it.hasNext()) { |
| | | Element e = (Element) it.next(); |
| | | String k = e.getName(); |
| | | String v = ""; |
| | | List children = e.getChildren(); |
| | | if(children.isEmpty()) { |
| | | v = e.getTextNormalize(); |
| | | } else { |
| | | v = XMLUtil.getChildrenText(children); |
| | | } |
| | | |
| | | m.put(k, v); |
| | | } |
| | | |
| | | //�ر��� |
| | | in.close(); |
| | | |
| | | return m; |
| | | } |
| | | |
| | | /** |
| | | * ��ȡ�ӽ���xml |
| | | * @param children |
| | | * @return String |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public static String getChildrenText(List children) { |
| | | StringBuffer sb = new StringBuffer(); |
| | | if(!children.isEmpty()) { |
| | | Iterator it = children.iterator(); |
| | | while(it.hasNext()) { |
| | | Element e = (Element) it.next(); |
| | | String name = e.getName(); |
| | | String value = e.getTextNormalize(); |
| | | List list = e.getChildren(); |
| | | sb.append("<" + name + ">"); |
| | | if(!list.isEmpty()) { |
| | | sb.append(XMLUtil.getChildrenText(list)); |
| | | } |
| | | sb.append(value); |
| | | sb.append("</" + name + ">"); |
| | | } |
| | | } |
| | | |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * ��ȡxml�����ַ� |
| | | * @param strxml |
| | | * @return |
| | | * @throws IOException |
| | | * @throws JDOMException |
| | | */ |
| | | public static String getXMLEncoding(String strxml) throws JDOMException, IOException { |
| | | InputStream in = HttpClientUtil.String2Inputstream(strxml); |
| | | SAXBuilder builder = new SAXBuilder(); |
| | | Document doc = builder.build(in); |
| | | in.close(); |
| | | return (String)doc.getProperty("encoding"); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.aes.handler; |
| | | |
| | | import com.hx.mybatis.aes.springbean.VariableAesKey; |
| | | import com.hx.util.mysql.aes.MysqlHexAesTool; |
| | | import org.apache.ibatis.type.BaseTypeHandler; |
| | | import org.apache.ibatis.type.JdbcType; |
| | | import org.apache.ibatis.type.MappedJdbcTypes; |
| | | import org.apache.ibatis.type.MappedTypes; |
| | | |
| | | import java.sql.CallableStatement; |
| | | import java.sql.PreparedStatement; |
| | | import java.sql.ResultSet; |
| | | import java.sql.SQLException; |
| | | |
| | | /** |
| | | * @author CJH |
| | | * @Date 2021-01-02 |
| | | * // @MappedTypes注解中的类代表此转换器可以自动转换为的java对象,@MappedJdbcTypes注解中设置的是对应的jdbctype,mysql的json对象对应的jdbctype为VARCHAR。 |
| | | */ |
| | | @MappedTypes(value = {String.class}) |
| | | @MappedJdbcTypes(value = {JdbcType.VARCHAR}, includeNullJdbcType = true) |
| | | public class GenericStringHandler extends BaseTypeHandler<String> { |
| | | |
| | | public GenericStringHandler() { |
| | | } |
| | | |
| | | @Override |
| | | public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { |
| | | ps.setString(i, parameter); |
| | | } |
| | | |
| | | @Override |
| | | public String getNullableResult(ResultSet rs, String columnName) throws SQLException { |
| | | String data = rs.getString(columnName); |
| | | if(data != null && data.length()%32==0 && MysqlHexAesTool.isHexStrValid(data)){ |
| | | try{ |
| | | data = MysqlHexAesTool.decryptData(data, VariableAesKey.getAesKey(columnName),null); |
| | | }catch (Exception e){ |
| | | //e.printStackTrace(); |
| | | } |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | @Override |
| | | public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { |
| | | String data = rs.getString(columnIndex); |
| | | if(data != null && data.length()%32==0 && MysqlHexAesTool.isHexStrValid(data)){ |
| | | try{ |
| | | data = MysqlHexAesTool.decryptData(data, VariableAesKey.getAesKey(null),null); |
| | | }catch (Exception e){ |
| | | //e.printStackTrace(); |
| | | } |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | @Override |
| | | public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { |
| | | String data = cs.getString(columnIndex); |
| | | if(data != null && data.length() < 129 && data.length()%32==0 && MysqlHexAesTool.isHexStrValid(data)){ |
| | | try{ |
| | | data = MysqlHexAesTool.decryptData(data, VariableAesKey.getAesKey(null),null); |
| | | }catch (Exception e){ |
| | | //e.printStackTrace(); |
| | | } |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | } |
| | | |
New file |
| | |
| | | package com.hx.mybatis.aes.springbean; |
| | | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 通用常量集中营 |
| | | * @author CJH |
| | | */ |
| | | @Component |
| | | public class ConstantBean { |
| | | |
| | | /**获取AES秘钥的配置(从什么包获取到)*/ |
| | | @Value("${mysql.hxe.aes.find.packs:}") |
| | | private String packPath; |
| | | /**固定AES的秘钥*/ |
| | | @Value("${mysql.hxe.aes.fixd.key:}") |
| | | private String fixedAesKey; |
| | | /**数据库初始化加密字段版本号*/ |
| | | @Value("${mysql.hxe.aes.init.version:}") |
| | | private String initVersion; |
| | | |
| | | public String getPackPath() { |
| | | return packPath; |
| | | } |
| | | |
| | | public void setPackPath(String packPath) { |
| | | this.packPath = packPath; |
| | | } |
| | | |
| | | public String getFixedAesKey() { |
| | | return fixedAesKey; |
| | | } |
| | | |
| | | public void setFixedAesKey(String fixedAesKey) { |
| | | this.fixedAesKey = fixedAesKey; |
| | | } |
| | | |
| | | public String getInitVersion() { |
| | | return initVersion; |
| | | } |
| | | |
| | | public void setInitVersion(String initVersion) { |
| | | this.initVersion = initVersion; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.aes.springbean; |
| | | |
| | | import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; |
| | | import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * ExportTableAliasVisitor |
| | | * @author Mwg |
| | | * @date 2020/09/08 23:47 |
| | | */ |
| | | public class ExportTableAliasVisitor extends SQLASTVisitorAdapter { |
| | | |
| | | private Map<String,String> tableMap = new HashMap<>(); |
| | | |
| | | public Map<String, String> getTableMap() { |
| | | return tableMap; |
| | | } |
| | | |
| | | public void setTableMap(Map<String, String> tableMap) { |
| | | this.tableMap = tableMap; |
| | | } |
| | | |
| | | @Override |
| | | public boolean visit(SQLExprTableSource x) { |
| | | |
| | | //别名,如果有别名,别名保持不变 |
| | | //System.out.println("alias:"+x.getAlias());//别名 |
| | | //System.out.println("expr:"+x.getExpr());//表名 |
| | | tableMap.put(x.getExpr().toString(),x.getAlias()); |
| | | |
| | | |
| | | //String s = StringUtils.isEmpty(x.getAlias()) ? x.getExpr().toString() : x.getAlias(); |
| | | |
| | | // 修改表名,不包含点才加 select id from c left join d on c.id = d.id 中的c 和 d |
| | | |
| | | /*if(!x.getExpr().toString().contains(".")) { |
| | | |
| | | x.setExpr("`" + dbName.get() + "`." + x.getExpr()); |
| | | |
| | | }*/ |
| | | //x.setExpr("mymymytable");//修改表名 |
| | | //x.setAlias("aa");//修改别名 |
| | | //x.setAlias(s); |
| | | return true; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.aes.springbean; |
| | | |
| | | import java.util.Set; |
| | | |
| | | public class FieldData { |
| | | |
| | | //主键 |
| | | private String id; |
| | | //数据库表明 |
| | | private String tableName; |
| | | //需要加密得表字段 |
| | | private Set<String> encrypFields; |
| | | |
| | | public FieldData() { |
| | | } |
| | | |
| | | public String getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(String id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getTableName() { |
| | | return tableName; |
| | | } |
| | | |
| | | public void setTableName(String tableName) { |
| | | this.tableName = tableName; |
| | | } |
| | | |
| | | public Set<String> getEncrypFields() { |
| | | return encrypFields; |
| | | } |
| | | |
| | | public void setEncrypFields(Set<String> encrypFields) { |
| | | this.encrypFields = encrypFields; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.aes.springbean; |
| | | |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Column; |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Table; |
| | | import com.hx.common.annotations.MysqlHexAes; |
| | | import com.hx.common.dao.mapper.CommonMapper; |
| | | import com.hx.common.service.CommonService; |
| | | import com.hx.exception.ServiceException; |
| | | import com.hx.mybatisTool.SqlSentence; |
| | | import com.hx.util.StringUtils; |
| | | import com.hx.util.mysql.aes.MysqlHexAesTool; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.util.*; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.Executors; |
| | | |
| | | public class InitMysqlData { |
| | | |
| | | /** |
| | | * 项目启动就执行后就执行该方法 |
| | | */ |
| | | //@PostConstruct 2022-06-17屏掉,暂时用不上 |
| | | public static void initData(String packPath, CommonService commonService){ |
| | | |
| | | //项目启动的时候填入 |
| | | if(!StringUtils.isEmpty(packPath)){ |
| | | Set<Class<?>> classes = VariableAesKey.classData(packPath); |
| | | |
| | | SqlSentence sqlSentence = new SqlSentence(); |
| | | Map<String,Object> values = new HashMap<>(); |
| | | |
| | | //解析表数据 |
| | | List<FieldData> fieldDatas = entityhandle(classes); |
| | | |
| | | int pageSize = 500; |
| | | //创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 |
| | | ExecutorService fixedThreadPool = Executors.newFixedThreadPool(20); |
| | | try{ |
| | | for(FieldData fieldData:fieldDatas){ |
| | | //获取条数 |
| | | sqlSentence.sqlSentence("SELECT COUNT(0) FROM "+fieldData.getTableName(),values); |
| | | int total = commonService.selectCountSql(sqlSentence); |
| | | if(total ==0 ){ |
| | | continue; |
| | | } |
| | | int pageTotal = total/pageSize+1; |
| | | for(int i= 0;i<pageTotal;i++){ |
| | | int finalI = i; |
| | | fixedThreadPool.execute(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | //更新数据 |
| | | updateData(fieldData,commonService, finalI,pageSize); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | }finally { |
| | | fixedThreadPool.shutdown(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /**更新数据*/ |
| | | public static void updateData(FieldData fieldData,CommonService commonService,int pageNum,int pageSize){ |
| | | SqlSentence sqlSentence = new SqlSentence(); |
| | | Map<String,Object> values = new HashMap<>(); |
| | | |
| | | //查询数据 |
| | | StringBuilder selectField = new StringBuilder(); |
| | | selectField.append(fieldData.getId()); |
| | | for(String fieldName:fieldData.getEncrypFields()){ |
| | | selectField.append(","+fieldName); |
| | | } |
| | | pageNum = pageNum*pageSize; |
| | | |
| | | sqlSentence.sqlSentence("SELECT "+selectField.toString()+" FROM "+fieldData.getTableName()+" LIMIT "+pageNum+","+pageSize,values); |
| | | List<Map<String,Object>> list = commonService.selectListMap(CommonMapper.class,sqlSentence); |
| | | |
| | | boolean isUpdate = false; |
| | | for (Map<String,Object> map:list){ |
| | | isUpdate = false; |
| | | StringBuilder setField = new StringBuilder(); |
| | | for (Map.Entry<String, Object> entry : map.entrySet()) { |
| | | String mapKey = entry.getKey(); |
| | | String mapValue = (String) entry.getValue(); |
| | | if(StringUtils.isEmpty(mapValue)){ |
| | | continue; |
| | | } |
| | | if(mapValue.length()%32==0 && MysqlHexAesTool.isHexStrValid(mapValue)){ |
| | | continue; |
| | | } |
| | | if(fieldData.getId().equals(mapKey)){ |
| | | continue; |
| | | } |
| | | if(setField.length()>0){ |
| | | setField.append(","); |
| | | } |
| | | setField.append(mapKey+" = #{m."+mapKey+"}"); |
| | | isUpdate = true; |
| | | } |
| | | |
| | | if(isUpdate){ |
| | | values = map; |
| | | sqlSentence.sqlSentence("UPDATE "+fieldData.getTableName()+" SET "+setField.toString()+" WHERE "+fieldData.getId()+" = #{m."+fieldData.getId()+"}",values); |
| | | |
| | | if(commonService.updateSentence(sqlSentence)!=1){ |
| | | throw new ServiceException("更新超过1条,更新失败!"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /**获取到表的数据*/ |
| | | public static List<FieldData> entityhandle(Set<Class<?>> classes){ |
| | | |
| | | List<FieldData> fildDatas = new ArrayList<>(); |
| | | //存储单表字段信息 |
| | | FieldData fildData; |
| | | //存储需要加密的字段 |
| | | Set<String> encrypFields; |
| | | |
| | | String fildName; |
| | | |
| | | for(Class<?> cl:classes){ |
| | | fildData = new FieldData(); |
| | | encrypFields = new HashSet<>(); |
| | | |
| | | //表名称 |
| | | if(!cl.isAnnotationPresent(Table.class)){ |
| | | continue; |
| | | } |
| | | Table table = cl.getAnnotation(Table.class); |
| | | fildData.setTableName(table.name()); |
| | | |
| | | // 取得本类的全部属性 |
| | | Field[] fields = cl.getDeclaredFields(); |
| | | fields = VariableAesKey.getPatentFields(fields,cl); |
| | | for (Field field:fields) { |
| | | |
| | | fildName = null; |
| | | if(field.isAnnotationPresent(Column.class)){ |
| | | Column column = field.getAnnotation(Column.class); |
| | | fildName = column.name(); |
| | | if(StringUtils.isEmpty(fildName)){ |
| | | fildName = field.getName(); |
| | | } |
| | | if(column.isKey()){ |
| | | fildData.setId(fildName); |
| | | } |
| | | }else{ |
| | | fildName = field.getName(); |
| | | } |
| | | |
| | | // 判断方法中是否有指定注解类型的注解 |
| | | if (!field.isAnnotationPresent(MysqlHexAes.class)) { |
| | | continue; |
| | | } |
| | | // 根据注解类型返回方法的指定类型注解 |
| | | MysqlHexAes mysqlHexAes = field.getAnnotation(MysqlHexAes.class); |
| | | //判断版本号是不是一样的 |
| | | if(!StringUtils.isEmpty(VariableAesKey.INIT_VERSION)){ |
| | | if(!VariableAesKey.INIT_VERSION.equals(mysqlHexAes.initVersion())){ |
| | | continue; |
| | | } |
| | | }else{ |
| | | if(!StringUtils.isEmpty(mysqlHexAes.initVersion())){ |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | String aesKey = mysqlHexAes.aesKey(); |
| | | if(StringUtils.isEmpty(aesKey)){ |
| | | aesKey = VariableAesKey.AES_KEY; |
| | | if(StringUtils.isEmpty(aesKey)){ |
| | | throw new RuntimeException("mysql的AES秘钥不能为空:"+field.getName()); |
| | | } |
| | | } |
| | | |
| | | encrypFields.add(fildName); |
| | | } |
| | | //是否有需要加密得字段 |
| | | if(encrypFields.size()<=0){ |
| | | continue; |
| | | } |
| | | fildData.setEncrypFields(encrypFields); |
| | | fildDatas.add(fildData); |
| | | } |
| | | return fildDatas; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.aes.springbean; |
| | | |
| | | import org.apache.ibatis.executor.statement.StatementHandler; |
| | | import org.apache.ibatis.mapping.BoundSql; |
| | | import org.apache.ibatis.mapping.MappedStatement; |
| | | import org.apache.ibatis.mapping.ParameterMapping; |
| | | import org.apache.ibatis.mapping.SqlCommandType; |
| | | import org.apache.ibatis.plugin.*; |
| | | import org.apache.ibatis.reflection.DefaultReflectorFactory; |
| | | import org.apache.ibatis.reflection.MetaObject; |
| | | import org.apache.ibatis.reflection.SystemMetaObject; |
| | | import org.apache.ibatis.session.Configuration; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.sql.Connection; |
| | | import java.util.List; |
| | | import java.util.Properties; |
| | | |
| | | |
| | | @Component |
| | | @Intercepts({ |
| | | @Signature( |
| | | type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class |
| | | }) |
| | | }) |
| | | public class MySqlInterceptor implements Interceptor { |
| | | |
| | | private static Logger logger = LoggerFactory.getLogger(MySqlInterceptor.class.getName()); |
| | | @Override |
| | | public Object intercept(Invocation invocation) throws Throwable { |
| | | |
| | | // 方法一 |
| | | StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); |
| | | MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory()); |
| | | //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement |
| | | MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); |
| | | //id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser |
| | | //String id = mappedStatement.getId(); |
| | | //sql语句类型 select、delete、insert、update |
| | | SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); |
| | | BoundSql boundSql = statementHandler.getBoundSql(); |
| | | |
| | | // 获取节点的配置 |
| | | Configuration configuration = mappedStatement.getConfiguration(); |
| | | // 获取参数 |
| | | Object parameterObject = boundSql.getParameterObject(); |
| | | // MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作 |
| | | // MetaObject metaObject1 = configuration.newMetaObject(parameterObject); |
| | | //获取sql中问号的基本信息 |
| | | List<ParameterMapping> parameterMappings = boundSql |
| | | .getParameterMappings(); |
| | | |
| | | /*for (ParameterMapping parameterMapping : parameterMappings) { |
| | | String propertyName = parameterMapping.getProperty(); |
| | | System.out.println("propertyName:"+ propertyName); |
| | | System.out.println("parameterObject:"+ parameterObject); |
| | | }*/ |
| | | |
| | | //这里可以进行sql修改 |
| | | //获取到原始sql语句 |
| | | String sql = boundSql.getSql(); |
| | | //新增 |
| | | if(sqlCommandType == SqlCommandType.INSERT){ |
| | | sql = SqlUtils.insertSql(sql, VariableAesKey.aesKeysTable); |
| | | }else if(sqlCommandType == SqlCommandType.UPDATE){ |
| | | sql = SqlUtils.updateSql(sql, VariableAesKey.aesKeysTable); |
| | | }else if(sqlCommandType == SqlCommandType.SELECT){ |
| | | if(VariableAesKey.isRun == 1){ |
| | | sql = SqlUtils.selectSql(sql, VariableAesKey.aesKeysTable); |
| | | } |
| | | }else if(sqlCommandType == SqlCommandType.DELETE){ |
| | | sql = SqlUtils.deleteSql(sql, VariableAesKey.aesKeysTable); |
| | | } |
| | | |
| | | //通过反射修改sql语句 |
| | | Field field = boundSql.getClass().getDeclaredField("sql"); |
| | | field.setAccessible(true); |
| | | field.set(boundSql, sql); |
| | | |
| | | return invocation.proceed(); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public Object plugin(Object target) { |
| | | if (target instanceof StatementHandler) { |
| | | return Plugin.wrap(target, this); |
| | | } else { |
| | | return target; |
| | | } |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void setProperties(Properties properties) { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.aes.springbean; |
| | | |
| | | import com.alibaba.druid.sql.SQLUtils; |
| | | import com.alibaba.druid.sql.ast.SQLExpr; |
| | | import com.alibaba.druid.sql.ast.SQLStatement; |
| | | import com.alibaba.druid.sql.ast.statement.*; |
| | | import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement; |
| | | import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; |
| | | import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; |
| | | import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; |
| | | import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; |
| | | import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; |
| | | import com.alibaba.druid.stat.TableStat; |
| | | import com.alibaba.druid.util.JdbcConstants; |
| | | import com.alibaba.druid.util.JdbcUtils; |
| | | import com.hx.util.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * sql语句处理工具 |
| | | * @author CJH 2022-01-12 |
| | | */ |
| | | public class SqlUtils { |
| | | //log4j日志 |
| | | private static Logger logger = LoggerFactory.getLogger(SqlUtils.class.getName()); |
| | | |
| | | |
| | | /**查询加密数据处理,只对查询做处理 |
| | | * @param sql sql语句 |
| | | * @param aesKeysTable aes秘钥 |
| | | * @return |
| | | */ |
| | | public static String selectSql(String sql,Map<String,Map<String,String>> aesKeysTable){ |
| | | |
| | | MySqlStatementParser parser = new MySqlStatementParser(sql); |
| | | SQLSelectStatement sqlStatement = (SQLSelectStatement) parser.parseSelect(); |
| | | |
| | | SQLSelect sqlSelect = sqlStatement.getSelect(); |
| | | if (sqlSelect.getQuery() instanceof SQLSelectQueryBlock) { |
| | | // 非union的查询语句 |
| | | return selectSqlRoutine( sqlStatement,aesKeysTable); |
| | | } else if (sqlSelect.getQuery() instanceof SQLUnionQuery) { |
| | | // union的查询语句 |
| | | return selectSqlUnion( sql, sqlStatement, aesKeysTable); |
| | | }else { |
| | | return selectSqlRoutine( sqlStatement,aesKeysTable); |
| | | } |
| | | } |
| | | |
| | | /**查询加密数据处理,只对查询做处理,select返回不做处理(Union特殊语句) |
| | | * @param sql sql语句 |
| | | * @param aesKeysTable aes秘钥 |
| | | * @return |
| | | */ |
| | | public static String selectSqlUnion(String sql,SQLSelectStatement sqlStatement,Map<String,Map<String,String>> aesKeysTable){ |
| | | |
| | | //获取表和别名 |
| | | ExportTableAliasVisitor visitorTable = new ExportTableAliasVisitor(); |
| | | sqlStatement.accept(visitorTable); |
| | | Map<String,String> tableMaps = visitorTable.getTableMap(); |
| | | |
| | | //获取所有的字段 |
| | | MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); |
| | | sqlStatement.accept(visitor); |
| | | //遍历所有字段 |
| | | Collection<TableStat.Column> columns= visitor.getColumns(); |
| | | |
| | | //处理需要加密得字段 |
| | | |
| | | if(!StringUtils.isEmpty(sql)){ |
| | | Map<String,String> aesKeys = null; |
| | | String aeskey = null; |
| | | //把剩下的拼接上来 |
| | | String tableAl = null; |
| | | for(TableStat.Column column:columns){ |
| | | aesKeys= aesKeysTable.get(column.getTable()); |
| | | if(aesKeys == null){ |
| | | continue; |
| | | } |
| | | aeskey = aesKeys.getOrDefault(column.getName(),null); |
| | | if(StringUtils.isEmpty(aeskey)){ |
| | | continue; |
| | | } |
| | | tableAl = tableMaps.get(column.getTable()); |
| | | if(!StringUtils.isEmpty(tableAl)){ |
| | | tableAl = tableAl+"."+column.getName(); |
| | | }else{ |
| | | tableAl = column.getName(); |
| | | } |
| | | sql = sql.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')"); |
| | | } |
| | | } |
| | | return sql; |
| | | } |
| | | |
| | | |
| | | /**查询加密数据处理,只对查询做处理,select返回不做处理(常规语句) |
| | | * @param sqlStatement sql语句 |
| | | * @param aesKeysTable aes秘钥 |
| | | * @return |
| | | */ |
| | | public static String selectSqlRoutine(SQLSelectStatement sqlStatement,Map<String,Map<String,String>> aesKeysTable){ |
| | | |
| | | //解析select查询 |
| | | //SQLSelect sqlSelect = sqlStatement.getSelect() |
| | | //获取sql查询块 |
| | | SQLSelectQueryBlock sqlSelectQuery = null; |
| | | boolean b = true; |
| | | try{ |
| | | sqlSelectQuery = (SQLSelectQueryBlock)sqlStatement.getSelect().getQuery() ; |
| | | }catch (Exception e){ |
| | | b = false; |
| | | logger.error("解析sql报错:"+e.getMessage()); |
| | | } |
| | | if(!b){ |
| | | return "err"; |
| | | } |
| | | |
| | | StringBuffer out = new StringBuffer() ; |
| | | //创建sql解析的标准化输出 |
| | | SQLASTOutputVisitor sqlastOutputVisitor = SQLUtils.createFormatOutputVisitor(out , null , JdbcUtils.MYSQL) ; |
| | | |
| | | //获取表和别名 |
| | | ExportTableAliasVisitor visitorTable = new ExportTableAliasVisitor(); |
| | | sqlStatement.accept(visitorTable); |
| | | Map<String,String> tableMaps = visitorTable.getTableMap(); |
| | | |
| | | //获取所有的字段 |
| | | MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); |
| | | sqlStatement.accept(visitor); |
| | | //遍历所有字段 |
| | | Collection<TableStat.Column> columns= visitor.getColumns(); |
| | | |
| | | StringBuilder sqlWhere = new StringBuilder(); |
| | | |
| | | StringBuilder sqlSelect = new StringBuilder(); |
| | | String expr = null; |
| | | sqlSelect.append("SELECT "); |
| | | //解析select返回的数据字段项 |
| | | for (SQLSelectItem sqlSelectItem : sqlSelectQuery.getSelectList()) { |
| | | if(sqlSelect.length() > 7){ |
| | | sqlSelect.append(","); |
| | | } |
| | | |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectItem.accept(sqlastOutputVisitor) ; |
| | | expr = out.toString(); |
| | | sqlSelect.append(expr); |
| | | |
| | | /* if(expr.indexOf("SELECT") == -1){ |
| | | sqlSelect.append(expr); |
| | | }else{ |
| | | //sqlSelect.append("("); |
| | | sqlSelect.append(expr); |
| | | //sqlSelect.append(")"); |
| | | *//* if(!StringUtils.isEmpty(sqlSelectItem.getAlias())){ |
| | | sqlSelect.append(" AS "+sqlSelectItem.getAlias()); |
| | | }*//* |
| | | }*/ |
| | | } |
| | | |
| | | //解析from |
| | | if(sqlSelectQuery.getFrom() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getFrom().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" FROM "+out); |
| | | } |
| | | |
| | | //解析where |
| | | if(sqlSelectQuery.getWhere() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getWhere().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" WHERE "+out+" "); |
| | | } |
| | | |
| | | if(sqlSelectQuery.getGroupBy() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getGroupBy().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" "+out); |
| | | } |
| | | if(sqlSelectQuery.getOrderBy() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getOrderBy().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" "+out); |
| | | } |
| | | if(sqlSelectQuery.getLimit() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getLimit().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" "+out); |
| | | } |
| | | |
| | | //处理where需要加密得字段 |
| | | String sql = sqlWhere.toString(); |
| | | if(!StringUtils.isEmpty(sql)){ |
| | | Map<String,String> aesKeys = null; |
| | | String aeskey = null; |
| | | //把剩下的拼接上来 |
| | | String tableAl = null; |
| | | for(TableStat.Column column:columns){ |
| | | aesKeys= aesKeysTable.get(column.getTable()); |
| | | if(aesKeys == null){ |
| | | continue; |
| | | } |
| | | aeskey = aesKeys.getOrDefault(column.getName(),null); |
| | | if(StringUtils.isEmpty(aeskey)){ |
| | | continue; |
| | | } |
| | | tableAl = tableMaps.get(column.getTable()); |
| | | if(!StringUtils.isEmpty(tableAl)){ |
| | | tableAl = tableAl+"."+column.getName(); |
| | | }else{ |
| | | tableAl = column.getName(); |
| | | } |
| | | sql = sql.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')"); |
| | | } |
| | | } |
| | | return sqlSelect.toString()+sql; |
| | | } |
| | | |
| | | /** |
| | | * 处理select返回字段的参数 |
| | | * @param sql |
| | | * @param aesKeysTable |
| | | * @param tableMaps |
| | | * @param columns |
| | | * @return |
| | | */ |
| | | public static String selectSqlHandle(String sql,Map<String,Map<String,String>> aesKeysTable |
| | | ,Map<String,String> tableMaps,Collection<TableStat.Column> columns){ |
| | | |
| | | |
| | | MySqlStatementParser parser = new MySqlStatementParser(sql); |
| | | SQLSelectStatement sqlStatement = (SQLSelectStatement) parser.parseSelect(); |
| | | //获取格式化的slq语句 |
| | | sql = sqlStatement.toString(); |
| | | |
| | | //解析select查询 |
| | | //SQLSelect sqlSelect = sqlStatement.getSelect() ; |
| | | //获取sql查询块 |
| | | SQLSelectQueryBlock sqlSelectQuery = (SQLSelectQueryBlock)sqlStatement.getSelect().getQuery() ; |
| | | StringBuffer out = new StringBuffer() ; |
| | | //创建sql解析的标准化输出 |
| | | SQLASTOutputVisitor sqlastOutputVisitor = SQLUtils.createFormatOutputVisitor(out , null , JdbcUtils.MYSQL) ; |
| | | |
| | | StringBuilder sqlWhere = new StringBuilder(); |
| | | |
| | | StringBuilder sqlSelect = new StringBuilder(); |
| | | String expr = null; |
| | | sqlSelect.append("SELECT "); |
| | | //解析select返回的数据字段项 |
| | | for (SQLSelectItem sqlSelectItem : sqlSelectQuery.getSelectList()) { |
| | | if(sqlSelect.length() > 7){ |
| | | sqlSelect.append(","); |
| | | } |
| | | expr = sqlSelectItem.getExpr().toString(); |
| | | if(expr.indexOf("SELECT") == -1){ |
| | | sqlSelect.append(expr); |
| | | if(!StringUtils.isEmpty(sqlSelectItem.getAlias())){ |
| | | sqlSelect.append(" AS "+sqlSelectItem.getAlias()); |
| | | } |
| | | }else{ |
| | | sqlSelect.append("("); |
| | | selectSqlHandle(expr,aesKeysTable,tableMaps,columns); |
| | | sqlSelect.append(")"); |
| | | if(!StringUtils.isEmpty(sqlSelectItem.getAlias())){ |
| | | sqlSelect.append(" AS "+sqlSelectItem.getAlias()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //解析from |
| | | if(sqlSelectQuery.getFrom() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getFrom().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" FROM "+out); |
| | | } |
| | | |
| | | //解析where |
| | | if(sqlSelectQuery.getWhere() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getWhere().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" WHERE "+out+" "); |
| | | } |
| | | |
| | | if(sqlSelectQuery.getGroupBy() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getGroupBy().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" "+out); |
| | | } |
| | | if(sqlSelectQuery.getOrderBy() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getOrderBy().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" "+out); |
| | | } |
| | | if(sqlSelectQuery.getLimit() != null){ |
| | | out.delete(0, out.length()) ; |
| | | sqlSelectQuery.getLimit().accept(sqlastOutputVisitor) ; |
| | | sqlWhere.append(" "+out); |
| | | } |
| | | |
| | | sql = sqlWhere.toString(); |
| | | if(!StringUtils.isEmpty(sql)){ |
| | | Map<String,String> aesKeys = null; |
| | | String aeskey = null; |
| | | //把剩下的拼接上来 |
| | | String tableAl = null; |
| | | |
| | | for(TableStat.Column column:columns){ |
| | | aesKeys= aesKeysTable.get(column.getTable()); |
| | | if(aesKeys == null){ |
| | | continue; |
| | | } |
| | | aeskey = aesKeys.getOrDefault(column.getName(),null); |
| | | if(StringUtils.isEmpty(aeskey)){ |
| | | continue; |
| | | } |
| | | tableAl = tableMaps.get(column.getTable()); |
| | | if(!StringUtils.isEmpty(tableAl)){ |
| | | tableAl = tableAl+"."+column.getName(); |
| | | }else{ |
| | | tableAl = column.getName(); |
| | | } |
| | | sql = sql.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')"); |
| | | } |
| | | } |
| | | return sqlSelect.toString()+sql; |
| | | } |
| | | |
| | | /**新增加密数据处理 |
| | | * @param sql sql语句 |
| | | * @param aesKeysTable aes秘钥 |
| | | * @return |
| | | */ |
| | | public static String insertSql(String sql,Map<String,Map<String,String>> aesKeysTable){ |
| | | //装载重写的sql语句 |
| | | StringBuilder splicingSql = new StringBuilder(); |
| | | |
| | | sql = SQLUtils.format(sql, JdbcConstants.MYSQL); |
| | | String[] datas = sql.split("VALUES",2); |
| | | |
| | | splicingSql.append(datas[0]+"VALUES "); |
| | | |
| | | //重新拼接SQL语句 |
| | | |
| | | //解析sql语句 |
| | | MySqlStatementParser parser = new MySqlStatementParser(sql); |
| | | SQLStatement statement = parser.parseStatement(); |
| | | MySqlInsertStatement insert = (MySqlInsertStatement)statement; |
| | | |
| | | String insertName = insert.getTableName().getSimpleName(); |
| | | |
| | | //根据表名称获取到AES秘钥 |
| | | Map<String,String> aesKeys= aesKeysTable.get(insertName); |
| | | if(aesKeys == null){ |
| | | return sql; |
| | | } |
| | | |
| | | //获取所有的字段 |
| | | List<SQLExpr> columns = insert.getColumns(); |
| | | |
| | | String fildValue = null; |
| | | String aeskey = null; |
| | | //遍历值 |
| | | List<SQLInsertStatement.ValuesClause> vcl = insert.getValuesList(); |
| | | for(int j = 0; j<vcl.size(); j++){ |
| | | if( j != 0){ |
| | | splicingSql.append(","); |
| | | } |
| | | for(int i = 0;i < columns.size();i++){ |
| | | //查询改字段是否需要加密 |
| | | aeskey = aesKeys.getOrDefault(columns.get(i).toString(),null); |
| | | fildValue = vcl.get(j).getValues().get(i).toString(); |
| | | if(i == 0){ |
| | | splicingSql.append("("); |
| | | if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){ |
| | | splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))"); |
| | | }else{ |
| | | splicingSql.append(fildValue); |
| | | } |
| | | }else if(i == columns.size()-1){ |
| | | splicingSql.append(","); |
| | | if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){ |
| | | splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))"); |
| | | }else{ |
| | | splicingSql.append(fildValue); |
| | | } |
| | | splicingSql.append(")"); |
| | | }else{ |
| | | splicingSql.append(","); |
| | | if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){ |
| | | splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))"); |
| | | }else{ |
| | | splicingSql.append(fildValue); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return splicingSql.toString(); |
| | | } |
| | | |
| | | /**更新加密数据处理 |
| | | * @param sql sql语句 |
| | | * @param aesKeysTable aes秘钥 |
| | | * @return |
| | | */ |
| | | public static String updateSql(String sql,Map<String,Map<String,String>> aesKeysTable){ |
| | | |
| | | //装载重写的sql语句 |
| | | StringBuilder splicingSql = new StringBuilder(); |
| | | |
| | | //sql = SQLUtils.format(sql, JdbcConstants.MYSQL); |
| | | MySqlStatementParser parser = new MySqlStatementParser(sql); |
| | | SQLStatement sqlStatement = parser.parseStatement(); |
| | | //获取格式化的slq语句 |
| | | sql = sqlStatement.toString(); |
| | | |
| | | MySqlUpdateStatement updateStatement = (MySqlUpdateStatement)sqlStatement; |
| | | |
| | | String insertName = updateStatement.getTableName().getSimpleName(); |
| | | |
| | | String[] datas = sql.split("WHERE",2); |
| | | |
| | | Map<String,String> aesKeys = aesKeysTable.get(insertName); |
| | | if(aesKeys == null){ |
| | | return sql; |
| | | } |
| | | |
| | | splicingSql.append("UPDATE "+insertName+" SET "); |
| | | String aeskey = null; |
| | | String fildValue = null; |
| | | List<SQLUpdateSetItem> items = updateStatement.getItems(); |
| | | for(int i = 0;i<items.size();i++){ |
| | | if(i != 0){ |
| | | splicingSql.append(","); |
| | | } |
| | | SQLUpdateSetItem item = items.get(i); |
| | | //查询改字段是否需要加密 |
| | | aeskey = aesKeys.getOrDefault(item.getColumn().toString(),null); |
| | | |
| | | fildValue = item.getValue().toString(); |
| | | if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){ |
| | | splicingSql.append(item.getColumn()+" = HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))"); |
| | | }else{ |
| | | splicingSql.append(item.getColumn()+" = "+fildValue); |
| | | } |
| | | } |
| | | String sqlWhere = " WHERE"; |
| | | //把剩下的拼接上来 |
| | | if(datas.length > 1){ |
| | | for(int i =1;i<datas.length;i++){ |
| | | sqlWhere = sqlWhere+datas[i]; |
| | | } |
| | | |
| | | parser = new MySqlStatementParser("SELECT * FROM "+insertName+" "+sqlWhere); |
| | | sqlStatement = parser.parseStatement(); |
| | | |
| | | ExportTableAliasVisitor visitorTable = new ExportTableAliasVisitor(); |
| | | sqlStatement.accept(visitorTable); |
| | | |
| | | //获取表和别名 |
| | | Map<String,String> tableMaps = visitorTable.getTableMap(); |
| | | tableMaps.put(insertName,null); |
| | | |
| | | //获取所有的字段 |
| | | MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); |
| | | sqlStatement.accept(visitor); |
| | | |
| | | String tableAl = null; |
| | | //遍历所有字段 |
| | | Collection<TableStat.Column> columns= visitor.getColumns(); |
| | | for(TableStat.Column column:columns){ |
| | | |
| | | aesKeys= aesKeysTable.get(column.getTable()); |
| | | if(aesKeys == null){ |
| | | continue; |
| | | } |
| | | aeskey = aesKeys.getOrDefault(column.getName(),null); |
| | | if(StringUtils.isEmpty(aeskey)){ |
| | | continue; |
| | | } |
| | | tableAl = tableMaps.get(column.getTable()); |
| | | if(!StringUtils.isEmpty(tableAl)){ |
| | | tableAl = tableAl+"."+column.getName(); |
| | | }else{ |
| | | tableAl = column.getName(); |
| | | } |
| | | sqlWhere = sqlWhere.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')"); |
| | | } |
| | | |
| | | } |
| | | splicingSql.append(sqlWhere); |
| | | return splicingSql.toString(); |
| | | } |
| | | |
| | | /**删除加密数据处理 |
| | | * @param sql sql语句 |
| | | * @param aesKeysTable aes秘钥 |
| | | * @return |
| | | */ |
| | | public static String deleteSql(String sql,Map<String,Map<String,String>> aesKeysTable){ |
| | | //装载重写的sql语句 |
| | | StringBuilder splicingSql = new StringBuilder(); |
| | | |
| | | //sql = SQLUtils.format(sql, JdbcConstants.MYSQL); |
| | | MySqlStatementParser parser = new MySqlStatementParser(sql); |
| | | SQLStatement sqlStatement = parser.parseStatement(); |
| | | //获取格式化的slq语句 |
| | | sql = sqlStatement.toString(); |
| | | |
| | | MySqlDeleteStatement deleteStatement = (MySqlDeleteStatement)sqlStatement; |
| | | |
| | | String insertName = deleteStatement.getTableName().getSimpleName(); |
| | | |
| | | String[] datas = sql.split("WHERE",2); |
| | | |
| | | Map<String,String> aesKeys = aesKeysTable.get(insertName); |
| | | if(aesKeys == null){ |
| | | return sql; |
| | | } |
| | | |
| | | splicingSql.append("DELETE FROM "+insertName); |
| | | |
| | | String aeskey = null; |
| | | |
| | | String sqlWhere = " WHERE"; |
| | | //把剩下的拼接上来 |
| | | if(datas.length > 1){ |
| | | for(int i =1;i<datas.length;i++){ |
| | | sqlWhere = sqlWhere+datas[i]; |
| | | } |
| | | |
| | | parser = new MySqlStatementParser("SELECT * FROM "+insertName+" "+sqlWhere); |
| | | sqlStatement = parser.parseStatement(); |
| | | |
| | | ExportTableAliasVisitor visitorTable = new ExportTableAliasVisitor(); |
| | | sqlStatement.accept(visitorTable); |
| | | |
| | | //获取表和别名 |
| | | Map<String,String> tableMaps = visitorTable.getTableMap(); |
| | | tableMaps.put(insertName,null); |
| | | |
| | | //获取所有的字段 |
| | | MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); |
| | | sqlStatement.accept(visitor); |
| | | |
| | | String tableAl = null; |
| | | //遍历所有字段 |
| | | Collection<TableStat.Column> columns= visitor.getColumns(); |
| | | for(TableStat.Column column:columns){ |
| | | |
| | | aesKeys= aesKeysTable.get(column.getTable()); |
| | | if(aesKeys == null){ |
| | | continue; |
| | | } |
| | | aeskey = aesKeys.getOrDefault(column.getName(),null); |
| | | if(StringUtils.isEmpty(aeskey)){ |
| | | continue; |
| | | } |
| | | tableAl = tableMaps.get(column.getTable()); |
| | | if(!StringUtils.isEmpty(tableAl)){ |
| | | tableAl = tableAl+"."+column.getName(); |
| | | }else{ |
| | | tableAl = column.getName(); |
| | | } |
| | | sqlWhere = sqlWhere.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')"); |
| | | } |
| | | |
| | | } |
| | | splicingSql.append(sqlWhere); |
| | | return splicingSql.toString(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.aes.springbean; |
| | | |
| | | import com.gitee.sunchenbin.mybatis.actable.annotation.Table; |
| | | import com.hx.common.annotations.MysqlHexAes; |
| | | import com.hx.util.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.PostConstruct; |
| | | import javax.annotation.Resource; |
| | | import java.io.File; |
| | | import java.io.FileFilter; |
| | | import java.io.IOException; |
| | | import java.lang.reflect.Field; |
| | | import java.net.JarURLConnection; |
| | | import java.net.URL; |
| | | import java.net.URLDecoder; |
| | | import java.util.*; |
| | | import java.util.jar.JarEntry; |
| | | import java.util.jar.JarFile; |
| | | |
| | | /** |
| | | * 获取指定包里面的AES秘钥 |
| | | */ |
| | | @Component |
| | | public class VariableAesKey { |
| | | |
| | | //log4j日志 |
| | | private static Logger logger = LoggerFactory.getLogger(VariableAesKey.class.getName()); |
| | | |
| | | @Resource |
| | | private ConstantBean constantBean; |
| | | |
| | | /**是否已经启动完*/ |
| | | public static int isRun = 0; |
| | | |
| | | /**存储所有AES的秘钥*/ |
| | | public static Map<String,String> aesKeys = new HashMap<>(); |
| | | /**根据表明来存储AES秘钥*/ |
| | | public static Map<String,Map<String,String>> aesKeysTable = new HashMap<>(); |
| | | |
| | | /**固定的aes秘钥*/ |
| | | public static String AES_KEY = null; |
| | | /**数据库加密字段初始化版本号*/ |
| | | public static String INIT_VERSION = null; |
| | | |
| | | |
| | | |
| | | /**存储AES秘钥*/ |
| | | public static void setAesKey(String aesKeyFild,String aesKey){ |
| | | aesKeys.put(aesKeyFild,aesKey); |
| | | } |
| | | /**获取AES秘钥*/ |
| | | public static String getAesKey(String aesKeyFild){ |
| | | if(aesKeyFild == null){ |
| | | return AES_KEY; |
| | | } |
| | | if(StringUtils.isEmpty(aesKeys.get(aesKeyFild))){ |
| | | return AES_KEY; |
| | | }else { |
| | | return aesKeys.get(aesKeyFild); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 项目启动就执行后就执行该方法 |
| | | */ |
| | | @PostConstruct |
| | | public void VariableAesKey(){ |
| | | System.out.println("加载AES"); |
| | | isRun = 1; |
| | | //项目启动的时候填入 |
| | | logger.info("扫描获取AES的包:" + constantBean.getPackPath()); |
| | | AES_KEY = constantBean.getFixedAesKey(); |
| | | INIT_VERSION = constantBean.getInitVersion(); |
| | | if(!StringUtils.isEmpty(constantBean.getPackPath())){ |
| | | Set<Class<?>> classes = classData(constantBean.getPackPath()); |
| | | logger.info("扫描获取AES的包classes:" + classes.size()); |
| | | Map<String,String> aesKeysFild = new HashMap<>(); |
| | | boolean isAes = false; |
| | | String tableName = null; |
| | | |
| | | for(Class<?> cl:classes){ |
| | | //表名称 |
| | | boolean hasAnnotation = cl.isAnnotationPresent(Table.class); |
| | | if(!hasAnnotation){ |
| | | continue; |
| | | } |
| | | Table table = cl.getAnnotation(Table.class); |
| | | tableName = table.name(); |
| | | |
| | | aesKeysFild = new HashMap<>(); |
| | | isAes = false; |
| | | |
| | | // 取得本类的全部属性 |
| | | Field[] fields = cl.getDeclaredFields(); |
| | | fields = getPatentFields(fields,cl); |
| | | for (Field field:fields) { |
| | | // 判断方法中是否有指定注解类型的注解 |
| | | hasAnnotation = field.isAnnotationPresent(MysqlHexAes.class); |
| | | if (hasAnnotation) { |
| | | // 根据注解类型返回方法的指定类型注解 |
| | | MysqlHexAes mysqlHexAes = field.getAnnotation(MysqlHexAes.class); |
| | | |
| | | //String aesKeyField = mysqlHexAes.aesKeyField(); |
| | | String aesKey = mysqlHexAes.aesKey(); |
| | | |
| | | if(StringUtils.isEmpty(aesKey)){ |
| | | aesKey = constantBean.getFixedAesKey(); |
| | | if(StringUtils.isEmpty(aesKey)){ |
| | | throw new RuntimeException("mysql的AES秘钥不能为空:"+field.getName()); |
| | | } |
| | | } |
| | | String key = aesKeys.get(field.getName()); |
| | | if(StringUtils.isEmpty(key)){ |
| | | aesKeys.put(field.getName(),aesKey); |
| | | aesKeysFild.put(field.getName(),aesKey); |
| | | isAes = true; |
| | | }else{ |
| | | isAes = true; |
| | | aesKeysFild.put(field.getName(),aesKey); |
| | | if(!aesKey.equals(key)){ |
| | | throw new RuntimeException("字段/定义的AES秘钥字段【"+field.getName()+"】多个一样,但是AES秘钥不一样"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if(isAes){ |
| | | aesKeysTable.put(tableName,aesKeysFild); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /**获取包下面的所有文件*/ |
| | | public static Set<Class<?>> classData(String packPath){ |
| | | Set<Class<?>> classes = new LinkedHashSet(); |
| | | String[] split = packPath.split(",|;"); |
| | | String[] var3 = split; |
| | | int var4 = split.length; |
| | | |
| | | label82: |
| | | for(int var5 = 0; var5 < var4; ++var5) { |
| | | String pack = var3[var5]; |
| | | boolean recursive = true; |
| | | String packageName = pack; |
| | | String packageDirName = pack.replace('.', '/'); |
| | | |
| | | try { |
| | | Enumeration dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName); |
| | | |
| | | while(true) { |
| | | label75: |
| | | while(true) { |
| | | if (!dirs.hasMoreElements()) { |
| | | continue label82; |
| | | } |
| | | |
| | | URL url = (URL)dirs.nextElement(); |
| | | String protocol = url.getProtocol(); |
| | | if ("file".equals(protocol)) { |
| | | System.err.println("file类型的扫描:" + pack); |
| | | String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); |
| | | findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes); |
| | | } else if ("jar".equals(protocol)) { |
| | | System.err.println("jar类型的扫描"); |
| | | |
| | | try { |
| | | JarFile jar = ((JarURLConnection)url.openConnection()).getJarFile(); |
| | | Enumeration entries = jar.entries(); |
| | | |
| | | while(true) { |
| | | JarEntry entry; |
| | | String name; |
| | | int idx; |
| | | do { |
| | | do { |
| | | if (!entries.hasMoreElements()) { |
| | | continue label75; |
| | | } |
| | | |
| | | entry = (JarEntry)entries.nextElement(); |
| | | name = entry.getName(); |
| | | if (name.charAt(0) == '/') { |
| | | name = name.substring(1); |
| | | } |
| | | } while(!name.startsWith(packageDirName)); |
| | | |
| | | idx = name.lastIndexOf(47); |
| | | if (idx != -1) { |
| | | packageName = name.substring(0, idx).replace('/', '.'); |
| | | } |
| | | } while(idx == -1 && !recursive); |
| | | |
| | | if (name.endsWith(".class") && !entry.isDirectory()) { |
| | | String className = name.substring(packageName.length() + 1, name.length() - 6); |
| | | |
| | | try { |
| | | classes.add(Class.forName(packageName + '.' + className)); |
| | | } catch (ClassNotFoundException var20) { |
| | | var20.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } catch (IOException var21) { |
| | | var21.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } catch (IOException var22) { |
| | | var22.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | return classes; |
| | | } |
| | | |
| | | /** |
| | | * 以文件的形式来获取包下的所有Class |
| | | * |
| | | * @param packageName |
| | | * @param packagePath |
| | | * @param recursive |
| | | * @param classes |
| | | */ |
| | | public static void findAndAddClassesInPackageByFile( |
| | | String packageName, |
| | | String packagePath, |
| | | final boolean recursive, |
| | | Set<Class<?>> classes){ |
| | | // 获取此包的目录 建立一个File |
| | | File dir = new File(packagePath); |
| | | // 如果不存在或者 也不是目录就直接返回 |
| | | if (!dir.exists() || !dir.isDirectory()) { |
| | | // log.warn("用户定义包名 " + packageName + " 下没有任何文件"); |
| | | return; |
| | | } |
| | | // 如果存在 就获取包下的所有文件 包括目录 |
| | | File[] dirfiles = dir.listFiles(new FileFilter(){ |
| | | // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件) |
| | | @Override |
| | | public boolean accept(File file){ |
| | | return (recursive && file.isDirectory()) || (file.getName().endsWith(".class")); |
| | | } |
| | | }); |
| | | // 循环所有文件 |
| | | for (File file : dirfiles){ |
| | | // 如果是目录 则继续扫描 |
| | | if (file.isDirectory()) { |
| | | findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes); |
| | | }else{ |
| | | // 如果是java类文件 去掉后面的.class 只留下类名 |
| | | String className = file.getName().substring(0, file.getName().length() - 6); |
| | | try{ |
| | | // 添加到集合中去 |
| | | // classes.add(Class.forName(packageName + '.' + |
| | | // className)); |
| | | // 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净 |
| | | classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className)); |
| | | }catch (ClassNotFoundException e){ |
| | | // log.error("添加用户自定义视图类错误 找不到此类的.class文件"); |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取父类的字段 |
| | | * @param fields |
| | | * @param clas |
| | | * @return |
| | | */ |
| | | public static Field[] getPatentFields(Field[] fields,Class<?> clas){ |
| | | if (clas.getSuperclass() != null) { |
| | | Class clsSup = clas.getSuperclass(); |
| | | List<Field> fieldList = new ArrayList<Field>(); |
| | | fieldList.addAll(Arrays.asList(fields)); |
| | | fieldList.addAll(Arrays.asList(clsSup.getDeclaredFields())); |
| | | fields = new Field[fieldList.size()]; |
| | | int i = 0; |
| | | for (Object field : fieldList.toArray()) { |
| | | fields[i] = (Field) field; |
| | | i++; |
| | | } |
| | | fields = getPatentFields(fields,clsSup); |
| | | } |
| | | return fields; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.mybatis.date.handler; |
| | | |
| | | import org.apache.ibatis.type.BaseTypeHandler; |
| | | import org.apache.ibatis.type.JdbcType; |
| | | import org.apache.ibatis.type.MappedJdbcTypes; |
| | | import org.apache.ibatis.type.MappedTypes; |
| | | |
| | | import java.sql.*; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * @author CJH |
| | | * @Date 2021-01-02 |
| | | * // @MappedTypes注解中的类代表此转换器可以自动转换为的java对象,@MappedJdbcTypes注解中设置的是对应的jdbctype,mysql的json对象对应的jdbctype为VARCHAR。 |
| | | */ |
| | | @MappedTypes(value = {LocalDateTime.class}) |
| | | @MappedJdbcTypes(value = {JdbcType.TIMESTAMP}, includeNullJdbcType = true) |
| | | public class GenericDateHandler extends BaseTypeHandler<Timestamp> { |
| | | |
| | | public GenericDateHandler() { |
| | | } |
| | | |
| | | public void setNonNullParameter(PreparedStatement ps, int i, Timestamp parameter, JdbcType jdbcType) throws SQLException { |
| | | ps.setTimestamp(i, parameter); |
| | | } |
| | | |
| | | public Timestamp getNullableResult(ResultSet rs, String columnName) throws SQLException { |
| | | return rs.getTimestamp(columnName); |
| | | } |
| | | |
| | | public Timestamp getNullableResult(ResultSet rs, int columnIndex) throws SQLException { |
| | | return rs.getTimestamp(columnIndex); |
| | | } |
| | | |
| | | public Timestamp getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { |
| | | return cs.getTimestamp(columnIndex); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.mybatisTool; |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import com.hx.util.SimpleTool; |
| | | import com.hx.util.StringUtils; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * mybatis 自定义处理sql语句 |
| | | * @author chenjiahe |
| | | * @Data: 2020-06-08 |
| | | */ |
| | | public class SqlSentence { |
| | | |
| | | /**执行语句*/ |
| | | private String sqlSentence; |
| | | |
| | | /**新增存在查询判断*/ |
| | | private String whereExist; |
| | | |
| | | private Map<String,Object> m; |
| | | /**排序*/ |
| | | private String orderBy; |
| | | /**开始页数*/ |
| | | private Integer startPage = 0; |
| | | /**每页数量*/ |
| | | private Integer pageNum = 0; |
| | | /**条数(当前类使用)*/ |
| | | private Integer pageSize; |
| | | |
| | | ////////////////////////////////////////////////////////////// |
| | | |
| | | /********************mother****************************/ |
| | | |
| | | public SqlSentence() |
| | | { |
| | | |
| | | } |
| | | |
| | | public SqlSentence(Class c, String where, Map<String, Object> values) |
| | | { |
| | | if(StringUtils.isEmpty(where)) |
| | | { |
| | | throw new TipsException("sql is null"); |
| | | } |
| | | |
| | | if(values == null) |
| | | { |
| | | throw new TipsException("values is null"); |
| | | } |
| | | |
| | | sqlSentence = "select * from " + c.getSimpleName()+ " where " + where; |
| | | m = values; |
| | | } |
| | | |
| | | public SqlSentence(String where, Map<String, Object> values) |
| | | { |
| | | if(StringUtils.isEmpty(where)) |
| | | { |
| | | throw new TipsException("sql is null"); |
| | | } |
| | | |
| | | if(values == null) |
| | | { |
| | | throw new TipsException("values is null"); |
| | | } |
| | | |
| | | sqlSentence = where; |
| | | m = values; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * sql整条语句 |
| | | * @param sql 如:select * from user Where name = #{m.userName} order by age desc |
| | | * @param values 存放的值如:values.put("userName","ChenJiaHe") |
| | | */ |
| | | public void sqlSentence(String sql,Map<String,Object> values) { |
| | | if(StringUtils.isEmpty(sql)) |
| | | { |
| | | throw new TipsException("sql is null"); |
| | | } |
| | | |
| | | if(values == null) |
| | | { |
| | | throw new TipsException("values is null"); |
| | | } |
| | | |
| | | sqlSentence = sql; |
| | | m = values; |
| | | } |
| | | |
| | | /** |
| | | * sql整条语句-分页 |
| | | * @param sql 如:select * from user Where name = #{m.userName} order by age desc |
| | | * @param values 存放的值如:values.put("userName","ChenJiaHe") |
| | | * @param pageNum 当前页数 |
| | | * @param pageSize 当前条数 |
| | | */ |
| | | public void sqlSentencePage(String sql,Map<String,Object> values,int pageNum,int pageSize) { |
| | | if(StringUtils.isEmpty(sql)) { |
| | | throw new TipsException("sql is null"); |
| | | } |
| | | |
| | | if(values == null) { |
| | | throw new TipsException("values is null"); |
| | | } |
| | | if(pageNum < 1){ |
| | | pageNum = 1; |
| | | } |
| | | if(pageSize < 1){ |
| | | pageSize = 1; |
| | | } |
| | | this.pageNum = pageNum; |
| | | this.pageSize = pageSize; |
| | | |
| | | //算起点 |
| | | int pageStart = (pageNum-1)*pageSize; |
| | | sql = sql+" LIMIT "+pageStart+","+pageSize; |
| | | sqlSentence = sql; |
| | | m = values; |
| | | } |
| | | |
| | | /**分页组装信息 |
| | | * @param data 装载信息 |
| | | * @param totalNum 总页数 |
| | | * @return 装载信息 |
| | | */ |
| | | public Map<String,Object> pageAssembleData(Map<String,Object> data,int totalNum){ |
| | | data.put("pageNum",pageNum); |
| | | data.put("pageSize",pageSize); |
| | | data.put("total",totalNum); |
| | | int pages; |
| | | if(pageSize > 0){ |
| | | if(totalNum%pageSize > 0){ |
| | | pages = totalNum/pageSize+1; |
| | | }else{ |
| | | pages = totalNum/pageSize; |
| | | } |
| | | }else{ |
| | | pages = 0; |
| | | } |
| | | data.put("pages",pages); |
| | | if(pages <= pageNum){ |
| | | data.put("isLastPage",true); |
| | | }else{ |
| | | data.put("isLastPage",false); |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询的语句 |
| | | * @param sql 如:id = #{m.userId} order by age DESC |
| | | * @param values 存放的值如:values.put("userId","123456") |
| | | */ |
| | | public void sqlWhere(String sql,Map<String,Object> values) { |
| | | if(!SimpleTool.checkNotNull(values)){ |
| | | throw new TipsException("values is null"); |
| | | } |
| | | if(!SimpleTool.checkNotNull(sql)) { |
| | | sql = "1=1"; |
| | | } |
| | | sqlSentence = sql; |
| | | m = values; |
| | | } |
| | | |
| | | /** |
| | | * 更新语句的语句 |
| | | * @param sql 如:name = #{m.name},age = ? WHERE id = #{m.id} |
| | | * @param values 存放的值 |
| | | */ |
| | | public void sqlUpdate(String sql,Map<String,Object> values) { |
| | | if(!SimpleTool.checkNotNull(values)){ |
| | | throw new TipsException("values is null"); |
| | | } |
| | | m = values; |
| | | sqlSentence = sql; |
| | | } |
| | | |
| | | |
| | | /************************************************************************/ |
| | | |
| | | public Map<String, Object> getM() { |
| | | return m; |
| | | } |
| | | |
| | | public void setM(Map<String, Object> m) { |
| | | this.m = m; |
| | | } |
| | | |
| | | public String getSqlSentence() { |
| | | return sqlSentence; |
| | | } |
| | | |
| | | public void setSqlSentence(String sqlSentence) { |
| | | this.sqlSentence = sqlSentence; |
| | | } |
| | | |
| | | public String getOrderBy() { |
| | | return orderBy; |
| | | } |
| | | |
| | | public void setOrderBy(String orderBy) { |
| | | this.orderBy = orderBy; |
| | | } |
| | | |
| | | public Integer getStartPage() { |
| | | return startPage; |
| | | } |
| | | |
| | | public void setStartPage(Integer startPage) { |
| | | this.startPage = startPage; |
| | | } |
| | | |
| | | public Integer getPageNum() { |
| | | return pageNum; |
| | | } |
| | | |
| | | public void setPageNum(Integer pageNum) { |
| | | this.pageNum = pageNum; |
| | | } |
| | | |
| | | public Integer getStartIndex() |
| | | { |
| | | return (startPage - 1) * pageNum; |
| | | } |
| | | |
| | | public String getWhereExist() { |
| | | return whereExist; |
| | | } |
| | | |
| | | public void setWhereExist(String whereExist) { |
| | | if(StringUtils.isNull(whereExist)){ |
| | | whereExist = null; |
| | | } |
| | | this.whereExist = whereExist; |
| | | } |
| | | |
| | | public Integer getPageSize() { |
| | | return pageSize; |
| | | } |
| | | |
| | | public void setPageSize(Integer pageSize) { |
| | | this.pageSize = pageSize; |
| | | } |
| | | } |
| | | |
| | | |
New file |
| | |
| | | package com.hx.mybatisTool; |
| | | |
| | | import com.hx.util.StringUtils; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Sql工具类 |
| | | * @author fwq |
| | | */ |
| | | public class SqlStringTool { |
| | | |
| | | /**基础key*/ |
| | | private static final String BASE_KEY = "k"; |
| | | /**AND符号*/ |
| | | private static final String AND_STR = " AND "; |
| | | /**左边括号拼接*/ |
| | | private static final String LEFT_STR = "#{m."; |
| | | /**右边括号拼接*/ |
| | | private static final String RIGHT_STR = "}"; |
| | | /**逗号分隔*/ |
| | | private static final String SIGN_STR = ","; |
| | | /**IN左符号*/ |
| | | private static final String IN_LEFT = " IN ( "; |
| | | /**IN右符号*/ |
| | | private static final String IN_RIGHT = " ) "; |
| | | |
| | | /** |
| | | * 递归key,直到不重复,这个递归是针对同一个sqlMap,防止同方法多个查询时存在key覆盖问题。 |
| | | * PS:建议查询完上一次,清理sqlMap后再传递进来,减少递归的操作 |
| | | */ |
| | | private static String getKey(String key, Map<String, Object> sqlMap) { |
| | | if (sqlMap.get(key) != null) { |
| | | getKey(BASE_KEY + key, sqlMap); |
| | | } |
| | | return key; |
| | | } |
| | | |
| | | /** |
| | | * 拼接sql语句 |
| | | * @param sql StringBuilder的sql语句 |
| | | * @param tableColumn 含别名表字段,例如:user AS u 根据id查询时传递u.id |
| | | * @param dataList 要循环的数值,List集合 |
| | | * @param sqlMap sql语句对应的参数Map |
| | | */ |
| | | public static void handleList(StringBuilder sql, String tableColumn, List<String> dataList, Map<String, Object> sqlMap) { |
| | | if (sql == null || StringUtils.isEmpty(tableColumn) || dataList == null || dataList.size() < 1) { |
| | | return; |
| | | } |
| | | String key = null; |
| | | sql.append(AND_STR).append(tableColumn).append(IN_LEFT); |
| | | for (int i = 0; i < dataList.size(); i++) { |
| | | key = getKey(BASE_KEY + i, sqlMap); |
| | | sql.append(LEFT_STR).append(key).append(RIGHT_STR).append(SIGN_STR); |
| | | sqlMap.put(key, dataList.get(i)); |
| | | } |
| | | sql.deleteCharAt(sql.length() - 1).append(IN_RIGHT); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 拼接sql语句 |
| | | * @param sql StringBuffer的sql语句 |
| | | * @param tableColumn 含别名表字段,例如:user AS u 根据id查询时传递u.id |
| | | * @param dataList 要循环的数值,List集合 |
| | | * @param sqlMap sql语句对应的参数Map |
| | | */ |
| | | public static void handleList(StringBuffer sql, String tableColumn, List<String> dataList, Map<String, Object> sqlMap) { |
| | | if (sql == null || StringUtils.isEmpty(tableColumn) || dataList == null || dataList.size() < 1) { |
| | | return; |
| | | } |
| | | String key = null; |
| | | sql.append(AND_STR).append(tableColumn).append(IN_LEFT); |
| | | for (int i = 0; i < dataList.size(); i++) { |
| | | key = getKey(BASE_KEY + i, sqlMap); |
| | | sql.append(LEFT_STR).append(key).append(RIGHT_STR).append(SIGN_STR); |
| | | sqlMap.put(key, dataList.get(i)); |
| | | } |
| | | sql.deleteCharAt(sql.length() - 1).append(IN_RIGHT); |
| | | } |
| | | |
| | | /** |
| | | * 拼接sql语句 |
| | | * @param sql StringBuilder的sql语句 |
| | | * @param tableColumn 含别名表字段,例如:user AS u 根据id查询时传递u.id |
| | | * @param dataList 要循环的数值,String数组 |
| | | * @param sqlMap sql语句对应的参数Map |
| | | */ |
| | | public static void handleList(StringBuilder sql, String tableColumn, String[] dataList, Map<String, Object> sqlMap) { |
| | | if (sql == null || StringUtils.isEmpty(tableColumn) || dataList == null || dataList.length < 1) { |
| | | return; |
| | | } |
| | | String key = null; |
| | | sql.append(AND_STR).append(tableColumn).append(IN_LEFT); |
| | | for (int i = 0; i < dataList.length; i++) { |
| | | key = getKey(BASE_KEY + i, sqlMap); |
| | | sql.append(LEFT_STR).append(key).append(RIGHT_STR).append(SIGN_STR); |
| | | sqlMap.put(key, dataList[i]); |
| | | } |
| | | sql.deleteCharAt(sql.length() - 1).append(IN_RIGHT); |
| | | } |
| | | |
| | | /** |
| | | * 拼接sql语句 |
| | | * @param sql StringBuffer的sql语句 |
| | | * @param tableColumn 含别名表字段,例如:user AS u 根据id查询时传递u.id |
| | | * @param dataList 要循环的数值,String数组 |
| | | * @param sqlMap sql语句对应的参数Map |
| | | */ |
| | | public static void handleList(StringBuffer sql, String tableColumn, String[] dataList, Map<String, Object> sqlMap) { |
| | | if (sql == null || StringUtils.isEmpty(tableColumn) || dataList == null || dataList.length < 1) { |
| | | return; |
| | | } |
| | | String key = null; |
| | | sql.append(AND_STR).append(tableColumn).append(IN_LEFT); |
| | | for (int i = 0; i < dataList.length; i++) { |
| | | key = getKey(BASE_KEY + i, sqlMap); |
| | | sql.append(LEFT_STR).append(key).append(RIGHT_STR).append(SIGN_STR); |
| | | sqlMap.put(key, dataList[i]); |
| | | } |
| | | sql.deleteCharAt(sql.length() - 1).append(IN_RIGHT); |
| | | } |
| | | |
| | | /** |
| | | * 拼接sql语句 |
| | | * @param sql StringBuilder的sql语句 |
| | | * @param tableColumn 含别名表字段,例如:user AS u 根据id查询时传递u.id |
| | | * @param dataList 要循环的数值,Map数组对象 |
| | | * @param dataListKey Map数组对象中要循环值对应的key |
| | | * @param sqlMap sql语句对应的参数Map |
| | | */ |
| | | public static void handleList(StringBuilder sql, String tableColumn, List<Map<String, Object>> dataList, String dataListKey, Map<String, Object> sqlMap) { |
| | | if (sql == null || StringUtils.isEmpty(tableColumn) || dataList == null || dataList.size() < 1) { |
| | | return; |
| | | } |
| | | String key = null; |
| | | sql.append(AND_STR).append(tableColumn).append(IN_LEFT); |
| | | for (int i = 0; i < dataList.size(); i++) { |
| | | key = getKey(BASE_KEY + i, sqlMap); |
| | | sql.append(LEFT_STR).append(key).append(RIGHT_STR).append(SIGN_STR); |
| | | sqlMap.put(key, dataList.get(i).get(dataListKey)); |
| | | } |
| | | sql.deleteCharAt(sql.length() - 1).append(IN_RIGHT); |
| | | } |
| | | |
| | | /** |
| | | * 拼接sql语句 |
| | | * @param sql StringBuffer的sql语句 |
| | | * @param tableColumn 含别名表字段,例如:user AS u 根据id查询时传递u.id |
| | | * @param dataList 要循环的数值,Map数组对象 |
| | | * @param dataListKey Map数组对象中要循环值对应的key |
| | | * @param sqlMap sql语句对应的参数Map |
| | | */ |
| | | public static void handleList(StringBuffer sql, String tableColumn, List<Map<String, Object>> dataList, String dataListKey, Map<String, Object> sqlMap) { |
| | | if (sql == null || StringUtils.isEmpty(tableColumn) || dataList == null || dataList.size() < 1) { |
| | | return; |
| | | } |
| | | String key = null; |
| | | sql.append(AND_STR).append(tableColumn).append(IN_LEFT); |
| | | for (int i = 0; i < dataList.size(); i++) { |
| | | key = getKey(BASE_KEY + i, sqlMap); |
| | | sql.append(LEFT_STR).append(key).append(RIGHT_STR).append(SIGN_STR); |
| | | sqlMap.put(key, dataList.get(i).get(dataListKey)); |
| | | } |
| | | sql.deleteCharAt(sql.length() - 1).append(IN_RIGHT); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
New file |
| | |
| | | package com.hx.redis; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonAutoDetect; |
| | | import com.fasterxml.jackson.annotation.PropertyAccessor; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.data.redis.connection.RedisConnectionFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; |
| | | import org.springframework.data.redis.serializer.StringRedisSerializer; |
| | | |
| | | @Configuration |
| | | @EnableCaching |
| | | public class RedisConfig { |
| | | @Bean |
| | | public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { |
| | | RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); |
| | | template.setConnectionFactory(factory); |
| | | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); |
| | | ObjectMapper om = new ObjectMapper(); |
| | | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); |
| | | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); |
| | | jackson2JsonRedisSerializer.setObjectMapper(om); |
| | | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); |
| | | template.setKeySerializer(stringRedisSerializer); |
| | | template.setHashKeySerializer(stringRedisSerializer); |
| | | template.setValueSerializer(jackson2JsonRedisSerializer); |
| | | template.setHashValueSerializer(jackson2JsonRedisSerializer); |
| | | template.afterPropertiesSet(); |
| | | return template; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.redis; |
| | | |
| | | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | |
| | | /** |
| | | * 文件处理工具 |
| | | * |
| | | * @author wangrenhuang |
| | | * @Date 2021-10-19 |
| | | */ |
| | | @Component |
| | | public class RedisUtil { |
| | | /** |
| | | * [redis] |
| | | */ |
| | | @Resource |
| | | private RedisTemplate<String, Object> redisTemplate; |
| | | |
| | | /** |
| | | * 切换数据库 |
| | | * @param dataNumber 数据库编号 |
| | | */ |
| | | public void setDataBase(int dataNumber) { |
| | | LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory(); |
| | | if (connectionFactory != null && dataNumber != connectionFactory.getDatabase()) { |
| | | connectionFactory.setDatabase(dataNumber); |
| | | this.redisTemplate.setConnectionFactory(connectionFactory); |
| | | connectionFactory.resetConnection(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * [判断key是否存在] |
| | | * |
| | | * @param key 键 |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean hasKey(String key) { |
| | | try { |
| | | return redisTemplate.hasKey(key); |
| | | } catch (Exception e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * [普通缓存获取] |
| | | * |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | public Object get(String key) { |
| | | return key == null ? null : redisTemplate.opsForValue().get(key); |
| | | } |
| | | |
| | | /** |
| | | * [普通缓存删除] |
| | | * |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | public boolean delete(String key) { |
| | | try { |
| | | Boolean aBoolean = redisTemplate.hasKey(key); |
| | | return aBoolean == false ? true : redisTemplate.delete(key); |
| | | } catch (Exception e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * [普通缓存放入] |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return true成功 false失败 |
| | | */ |
| | | public boolean set(String key, Object value) { |
| | | try { |
| | | redisTemplate.opsForValue().set(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 普通缓存放入并设置时间 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public boolean set(String key, Object value, long time) { |
| | | try { |
| | | if (time > 0) { |
| | | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); |
| | | } else { |
| | | set(key, value); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 26 |
| | | * 指定缓存失效时间 |
| | | * 27 |
| | | * |
| | | * @param key 键 |
| | | * 28 |
| | | * @param time 时间(秒) |
| | | * 29 |
| | | * @return 30 |
| | | */ |
| | | |
| | | public boolean expire(String key, long time) { |
| | | try { |
| | | if (time > 0) { |
| | | redisTemplate.expire(key, time, TimeUnit.SECONDS); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 设置到期时间 |
| | | * @param key 对应键 |
| | | * @param time 时长 |
| | | * @param timeUnit 时间单位 |
| | | * @return |
| | | */ |
| | | public boolean expire(String key, long time, TimeUnit timeUnit) { |
| | | try { |
| | | if (time > 0) { |
| | | return redisTemplate.expire(key, time, timeUnit); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * hash 删除操作 |
| | | * |
| | | * @param key 键 |
| | | * @param valueKey 值 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public boolean hashDel(String key, Object... valueKey) { |
| | | try { |
| | | redisTemplate.opsForHash().delete(key,valueKey); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * hash 设置hashMapt操作 |
| | | * |
| | | * @param key 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public boolean hashSetMap(String key, Map<String,Object> map) { |
| | | try { |
| | | redisTemplate.opsForHash().putAll(key, map); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * hash 设置单个hashMap操作 |
| | | * |
| | | * @param key 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public boolean hashSet(String hashKey, String key, Object value) { |
| | | try { |
| | | redisTemplate.opsForHash().put(hashKey,key,value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * hash 获取整个hashKey数据 |
| | | * |
| | | * @param hashKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Map<Object, Object> hashGetAll(String hashKey) { |
| | | try { |
| | | return redisTemplate.opsForHash().entries(hashKey); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * hash 获取单个hashKey |
| | | * |
| | | * @param hashKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object hashGet(String hashKey,Object key) { |
| | | try { |
| | | return redisTemplate.opsForHash().get(hashKey,key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 新增-左插入 |
| | | * |
| | | * @param listKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object leftPush(String listKey,Object value) { |
| | | try { |
| | | return redisTemplate.opsForList().leftPush(listKey,value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 新增-左插入(存在才插入) |
| | | * |
| | | * @param listKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object leftPushIfPresent(String listKey,Object value) { |
| | | try { |
| | | return redisTemplate.opsForList().leftPushIfPresent(listKey,value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 新增-右插入(存在才插入) |
| | | * |
| | | * @param listKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object rightPushIfPresent(String listKey,Object value) { |
| | | try { |
| | | return redisTemplate.opsForList().rightPushIfPresent(listKey,value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 新增-右插入 |
| | | * |
| | | * @param listKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object rightPush(String listKey,Object value) { |
| | | try { |
| | | return redisTemplate.opsForList().rightPush(listKey,value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 弹出-左 |
| | | * |
| | | * @param listKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object leftPop(String listKey) { |
| | | try { |
| | | return redisTemplate.opsForList().leftPop(listKey); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 弹出-右 |
| | | * |
| | | * @param listKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object rightPop(String listKey) { |
| | | try { |
| | | return redisTemplate.opsForList().rightPop(listKey); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 获取索引下的值 |
| | | * |
| | | * @param key 键 |
| | | * @param index 索引 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object listGet(String key, long index) { |
| | | try { |
| | | return redisTemplate.opsForList().index(key,index); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 获取索引下的值 |
| | | * |
| | | * @param key 键 |
| | | * @param start 开始位置 0是开始位置 |
| | | * @param end 结束位置,-1返回所有 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public List<Object> listGetRange(String key, long start , long end) { |
| | | try { |
| | | return redisTemplate.opsForList().range(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 获取长度 |
| | | * |
| | | * @param listKey 键 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object listSize(String listKey) { |
| | | try { |
| | | return redisTemplate.opsForList().size(listKey); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * list 删除 |
| | | * |
| | | * @param listKey 键 |
| | | * @param index index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素; index<0, 从尾部开始删除第一个值等于value的元素 |
| | | * @param value 删除的值 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public Object listRemove(String listKey,long index,Object value) { |
| | | try { |
| | | return redisTemplate.opsForList().remove(listKey, index, value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param timeOut 时间 |
| | | * @param unit 时间单位 |
| | | */ |
| | | public Boolean setIfAbsent(String key, Object value, long timeOut, TimeUnit unit) { |
| | | try { |
| | | return redisTemplate.opsForValue().setIfAbsent(key, value, timeOut, unit); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.repeat.check; |
| | | |
| | | import com.hx.common.annotations.repeat.RequestRepeat; |
| | | import com.hx.exception.TipsException; |
| | | import com.hx.redis.RedisUtil; |
| | | import com.hx.util.DateUtil; |
| | | import com.hx.util.IPUtils; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.lang.reflect.Method; |
| | | import java.util.Date; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * URL防重复提交 |
| | | * @author CJH |
| | | */ |
| | | public class RequestRepeatUtil { |
| | | |
| | | /**请求重复校验 |
| | | * 目前区分重复是IP地址和请求方法,如果想要更精准,传code |
| | | * @param code 前缀标识,用于区分不同请求来源,长度最好12位之内,可空 |
| | | * @param request HttpServletRequest |
| | | * @param redisUtil redis |
| | | * @param millisecond 间隔时间,毫秒(默认500毫秒) |
| | | * @param annotateCheck 是否注解校验,如果是,将以注解来做校验,否则就全部做校验 |
| | | * @param method 请求方法,方法或者类上面有校验注解,注解跳过或者拦截 |
| | | */ |
| | | public static void checkRequest(String code,HttpServletRequest request, RedisUtil redisUtil, Long millisecond |
| | | , boolean annotateCheck, Method method){ |
| | | //优先校验注解,优先方法再到类 |
| | | RequestRepeat requestRepeat = method.getAnnotation(RequestRepeat.class); |
| | | if(requestRepeat != null){ |
| | | if(requestRepeat.isRepeat()){ |
| | | check(code,request,redisUtil,requestRepeat.millisecond()); |
| | | }else{ |
| | | return; |
| | | } |
| | | }else{ |
| | | requestRepeat = method.getClass().getAnnotation(RequestRepeat.class); |
| | | if(requestRepeat != null){ |
| | | if(requestRepeat.isRepeat()){ |
| | | check(code,request,redisUtil,requestRepeat.millisecond()); |
| | | }else{ |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | //通过注解校验,不需要全部 |
| | | if(!annotateCheck){ |
| | | check(code,request,redisUtil,millisecond); |
| | | } |
| | | } |
| | | |
| | | public static void check(String code,HttpServletRequest request,RedisUtil redisUtil,Long millisecond){ |
| | | //没有设置,默认0.5秒 |
| | | if(millisecond == null){ |
| | | millisecond = 500L; |
| | | } |
| | | //获取请求的IP地址 |
| | | String ip = IPUtils.getIpAddr(request); |
| | | //获取URL |
| | | String method = request.getServletPath(); |
| | | if(code != null){ |
| | | code = code+"-"+ip+"-"+method; |
| | | }else{ |
| | | code = ip+"-"+method; |
| | | } |
| | | if(!redisUtil.setIfAbsent(code, DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"),millisecond, TimeUnit.MILLISECONDS)){ |
| | | throw new TipsException("请勿频繁操作!"); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.resultTool; |
| | | |
| | | /** |
| | | * 统一状态码 |
| | | * @author chenjiahe |
| | | * @Data: 2020-06-20 |
| | | */ |
| | | public final class ResponseCode { |
| | | |
| | | /*成功*/ |
| | | public static final String SUCCESS = "100"; |
| | | /*错误提示,前端根据这个码弹出提示*/ |
| | | public static final String ERROR_TIPS="200"; |
| | | /*参数验证错误*/ |
| | | public static final String ERROR_PARAMS_VALIDATOR="205"; |
| | | /*业务验证错误*/ |
| | | public static final String ERROR_SERVICE_VALIDATOR="300"; |
| | | /*系统数据错误*/ |
| | | public static final String ERROR_DATA_VALIDATOR="400"; |
| | | /*登录有误*/ |
| | | public static final String ERROR_LOGIN="603"; |
| | | /*系统异常*/ |
| | | public static final String ERROR_SYSTEM = "999"; |
| | | /*签名错误*/ |
| | | public static final String ERROR_SIGN = "203"; |
| | | |
| | | |
| | | |
| | | } |
| | | |
New file |
| | |
| | | package com.hx.resultTool; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.hx.exception.TipsException; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 统一返回格式 |
| | | * @author chenjiahe |
| | | * @Data: 2020-06-20 |
| | | */ |
| | | public class Result implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -3948389268046368059L; |
| | | |
| | | private String code; |
| | | |
| | | private String msg; |
| | | |
| | | private Object data; |
| | | |
| | | public Result() {} |
| | | |
| | | public Result(String code, String msg) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | } |
| | | |
| | | public static Result success() { |
| | | Result Result = new Result(); |
| | | Result.setCode(ResponseCode.SUCCESS); |
| | | Result.setMsg("SUCCESS"); |
| | | return Result; |
| | | } |
| | | |
| | | public static Result success(Object data) { |
| | | Result Result = new Result(); |
| | | Result.setCode(ResponseCode.SUCCESS); |
| | | Result.setData(data); |
| | | Result.setMsg("SUCCESS"); |
| | | return Result; |
| | | } |
| | | |
| | | public static Result failure(String code, String msg) { |
| | | Result Result = new Result(); |
| | | Result.setCode(code); |
| | | Result.setMsg(msg); |
| | | return Result; |
| | | } |
| | | |
| | | public static Result failure(String code, String msg, Object data) { |
| | | Result Result = new Result(); |
| | | Result.setCode(code); |
| | | Result.setMsg(msg); |
| | | Result.setData(data); |
| | | return Result; |
| | | } |
| | | |
| | | /**校验返回码*/ |
| | | public Boolean checkCode(){ |
| | | if(ResponseCode.SUCCESS.equals(code)){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /**校验返回码,进行错误提示*/ |
| | | public void checkTips(){ |
| | | if(!ResponseCode.SUCCESS.equals(code)){ |
| | | throw new TipsException("请求失败:"+this.code+","+this.msg); |
| | | } |
| | | } |
| | | |
| | | /**返回数据转JSONObject*/ |
| | | public JSONObject getJsonObject(Object data){ |
| | | return JSONObject.parseObject(JSON.toJSONString(data)); |
| | | } |
| | | |
| | | /**返回数据转JSONArray*/ |
| | | public JSONArray getJsonArray(Object data){ |
| | | return JSONArray.parseArray(JSON.toJSONString(data)); |
| | | } |
| | | |
| | | /**返回数据转对象*/ |
| | | public <T> T getObject(Object data, Class<T> clazz) { |
| | | return JSONObject.parseObject(JSON.toJSONString(data), clazz); |
| | | } |
| | | |
| | | /**返回数据转列表*/ |
| | | public <T> List<T> getArray(Object data, Class<T> clazz) { |
| | | return JSONArray.parseArray(JSON.toJSONString(data), clazz); |
| | | } |
| | | |
| | | /*******************************************************************************/ |
| | | |
| | | public String getCode() { |
| | | return this.code; |
| | | } |
| | | |
| | | public void setCode(final String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getMsg() { |
| | | return this.msg; |
| | | } |
| | | |
| | | public void setMsg(final String msg) { |
| | | this.msg = msg; |
| | | } |
| | | |
| | | public Object getData() { |
| | | return this.data; |
| | | } |
| | | |
| | | public void setData(final Object data) { |
| | | this.data = data; |
| | | } |
| | | |
| | | } |
| | | |
New file |
| | |
| | | package com.hx.security.request; |
| | | |
| | | import org.apache.tomcat.util.descriptor.web.SecurityCollection; |
| | | import org.apache.tomcat.util.descriptor.web.SecurityConstraint; |
| | | import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; |
| | | import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /**设置限制请求*/ |
| | | @Configuration |
| | | public class RequestRestriction { |
| | | |
| | | @Bean |
| | | public ConfigurableServletWebServerFactory configurableServletWebServerFactory() { |
| | | TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); |
| | | factory.addContextCustomizers(context -> { |
| | | SecurityConstraint securityConstraint = new SecurityConstraint(); |
| | | securityConstraint.setUserConstraint("CONFIDENTIAL"); |
| | | SecurityCollection collection = new SecurityCollection(); |
| | | //设置不安全请求不能通过 |
| | | collection.addPattern("/*"); |
| | | collection.addMethod("HEAD"); |
| | | collection.addMethod("PUT"); |
| | | collection.addMethod("DELETE"); |
| | | collection.addMethod("OPTIONS"); |
| | | collection.addMethod("TRACE"); |
| | | collection.addMethod("COPY"); |
| | | collection.addMethod("SEARCH"); |
| | | collection.addMethod("PROPFIND"); |
| | | //collection.addMethod("PATCH"); |
| | | securityConstraint.addCollection(collection); |
| | | context.addConstraint(securityConstraint); |
| | | }); |
| | | return factory; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import org.apache.commons.codec.binary.Base64; |
| | | |
| | | import javax.crypto.Cipher; |
| | | import javax.crypto.SecretKey; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | import java.io.UnsupportedEncodingException; |
| | | |
| | | /** |
| | | * AES加密工具类 |
| | | */ |
| | | public class Aes { |
| | | |
| | | /** |
| | | * 将二进制转换成16进制 |
| | | * |
| | | * @param buf 字节数组 |
| | | * @return |
| | | */ |
| | | public static String parseByte2HexStr(byte buf[]) { |
| | | StringBuffer sb = new StringBuffer(); |
| | | for (int i = 0; i < buf.length; i++) { |
| | | String hex = Integer.toHexString(buf[i] & 0xFF); |
| | | if (hex.length() == 1) { |
| | | hex = '0' + hex; |
| | | } |
| | | sb.append(hex.toUpperCase()); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 将16进制转换为二进制 |
| | | * |
| | | * @param hexStr 16进制字符 |
| | | * @return |
| | | */ |
| | | public static byte[] parseHexStr2Byte(String hexStr) { |
| | | if (hexStr.length() < 1) |
| | | return null; |
| | | byte[] result = new byte[hexStr.length() / 2]; |
| | | for (int i = 0; i < hexStr.length() / 2; i++) { |
| | | int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); |
| | | int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); |
| | | result[i] = (byte) (high * 16 + low); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 加密 |
| | | * @param str 待加密字符串 |
| | | * @param secret 密钥 |
| | | * @return |
| | | */ |
| | | public static byte[] encrypt(String str, String secret) { |
| | | if (null != str) { |
| | | byte[] bytes = null; |
| | | |
| | | try { |
| | | Base64 base64 = new Base64(); |
| | | String ALGORITHM = "AES"; |
| | | SecretKey desKey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥 |
| | | Cipher c; |
| | | c = Cipher.getInstance(ALGORITHM); |
| | | c.init(Cipher.ENCRYPT_MODE, desKey); |
| | | bytes = c.doFinal(str.getBytes("UTF-8")); |
| | | return bytes; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 解密 |
| | | * @param str 待解密字符串 |
| | | * @param secret 密钥 |
| | | * @return |
| | | */ |
| | | public static byte[] decrypt(byte[] str, String secret) { |
| | | try { |
| | | String ALGORITHM = "AES"; |
| | | SecretKey desKey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥 |
| | | Cipher c = Cipher.getInstance(ALGORITHM); |
| | | c.init(Cipher.DECRYPT_MODE, desKey); |
| | | return c.doFinal(str); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static void main(String[] args) throws UnsupportedEncodingException { |
| | | |
| | | String content = "apiKey=phitabfaceapi&userId=o5W1it6Pvqn6vPX6E1BGERH8J1lw"; |
| | | String password = "phitabfacesecret"; |
| | | |
| | | byte[] encode = encrypt(content, password); |
| | | String code = parseByte2HexStr(encode); |
| | | System.out.println("密文字符串:" + code); |
| | | |
| | | //16进制字符串转成字节数组 |
| | | byte[] decode = parseHexStr2Byte(code); |
| | | // 解密 |
| | | byte[] decryptResult = decrypt(decode, password); |
| | | System.out.println("解密后:" + new String(decryptResult, "UTF-8")); //不转码会乱码 |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import javax.crypto.Cipher; |
| | | import javax.crypto.SecretKey; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | |
| | | import org.apache.commons.codec.binary.Base64; |
| | | |
| | | /** |
| | | * AES加解密工具 |
| | | * 使用该类,需要行替换local_policy.jar及us_export_policy.jar |
| | | * @author ChenJiaHe |
| | | * |
| | | */ |
| | | public class AesUtil { |
| | | |
| | | /**16位加密秘钥*/ |
| | | public static final String SECRET = "huoXiong16816888"; |
| | | |
| | | /** |
| | | * AES加密 |
| | | * |
| | | * @param str |
| | | * 需要加密的明文 |
| | | * @param secret |
| | | * 秘钥 |
| | | * @return 加密后的密文(base64编码字符串) |
| | | */ |
| | | public static String aesEncryp(String str, String secret) { |
| | | if (null != str) { |
| | | byte[] bytes = null; |
| | | |
| | | try { |
| | | Base64 base64 = new Base64(); |
| | | String ALGORITHM = "AES"; |
| | | SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥 |
| | | Cipher c; |
| | | c = Cipher.getInstance(ALGORITHM); |
| | | c.init(Cipher.ENCRYPT_MODE, deskey); |
| | | bytes = c.doFinal(str.getBytes("UTF-8")); |
| | | if (bytes != null) { |
| | | return new String(base64.encode(bytes)); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * AES解密 |
| | | * |
| | | * @param str |
| | | * 需要解密的秘文 |
| | | * @param secret |
| | | * 秘钥 |
| | | * @return 解密后的明文 |
| | | */ |
| | | public static String aesDecryp(String str, String secret) { |
| | | try { |
| | | Base64 base64 = new Base64(); |
| | | String ALGORITHM = "AES"; |
| | | SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥 |
| | | Cipher c = Cipher.getInstance(ALGORITHM); |
| | | c.init(Cipher.DECRYPT_MODE, deskey); |
| | | return new String(c.doFinal(base64.decode(str.getBytes("UTF-8"))), "UTF-8"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * AES加密(固定秘钥) |
| | | * |
| | | * @param str 需要加密的明文 |
| | | * @return 加密后的密文(base64编码字符串) |
| | | */ |
| | | public static String aesEncryp(String str) { |
| | | String secret = SECRET; |
| | | if (null != str) { |
| | | byte[] bytes = null; |
| | | |
| | | try { |
| | | Base64 base64 = new Base64(); |
| | | String ALGORITHM = "AES"; |
| | | SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥 |
| | | Cipher c; |
| | | c = Cipher.getInstance(ALGORITHM); |
| | | c.init(Cipher.ENCRYPT_MODE, deskey); |
| | | bytes = c.doFinal(str.getBytes("UTF-8")); |
| | | if (bytes != null) { |
| | | return new String(base64.encode(bytes)); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * AES解密(固定秘钥) |
| | | * |
| | | * @param str 需要解密的秘文 |
| | | * @return 解密后的明文 |
| | | */ |
| | | public static String aesDecryp(String str) { |
| | | String secret = SECRET; |
| | | try { |
| | | Base64 base64 = new Base64(); |
| | | String ALGORITHM = "AES"; |
| | | SecretKey deskey = new SecretKeySpec(secret.getBytes("UTF-8"), ALGORITHM);// 生成密钥 |
| | | Cipher c = Cipher.getInstance(ALGORITHM); |
| | | c.init(Cipher.DECRYPT_MODE, deskey); |
| | | return new String(c.doFinal(base64.decode(str.getBytes("UTF-8"))), "UTF-8"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import com.google.zxing.BarcodeFormat; |
| | | import com.google.zxing.MultiFormatWriter; |
| | | import com.google.zxing.client.j2se.MatrixToImageWriter; |
| | | import com.google.zxing.common.BitMatrix; |
| | | import sun.misc.BASE64Encoder; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.ByteArrayOutputStream; |
| | | |
| | | public class BarCodeUtil { |
| | | |
| | | /** |
| | | * 给前端产生一个条形码 |
| | | * |
| | | * @param number 编码 |
| | | * @param width 宽度 |
| | | * @param height 高度 |
| | | */ |
| | | public static String getCode(String number, Integer width, Integer height) { |
| | | // 生成条形码 |
| | | BufferedImage image = getBarCode(number, width, height); |
| | | // 使用流的方式 |
| | | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| | | try { |
| | | ImageIO.write(image, "png", out); |
| | | } catch (Exception e) { |
| | | // log.error("generate code error! error message:{}", "出现问题!"); |
| | | e.printStackTrace(); |
| | | } |
| | | // 将流转成数组 |
| | | byte[] bytes = out.toByteArray(); |
| | | BASE64Encoder encoder = new BASE64Encoder(); |
| | | // 把生成的编码返回去 |
| | | return "data:image/png;base64," + encoder.encodeBuffer(bytes).trim(); |
| | | } |
| | | |
| | | /** |
| | | * 产生条形码的方法 |
| | | * |
| | | * @param number 编码 |
| | | * @param width 宽度 |
| | | * @param height 高度 |
| | | */ |
| | | public static BufferedImage getBarCode(String number, Integer width, Integer height) { |
| | | try { |
| | | BitMatrix bitMatrix = new MultiFormatWriter().encode(number, BarcodeFormat.CODE_128, width, height); |
| | | return MatrixToImageWriter.toBufferedImage(bitMatrix); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | /** |
| | | * Base64 工具类 |
| | | */ |
| | | public class Base64Util { |
| | | private static final char last2byte = (char) Integer.parseInt("00000011", 2); |
| | | private static final char last4byte = (char) Integer.parseInt("00001111", 2); |
| | | private static final char last6byte = (char) Integer.parseInt("00111111", 2); |
| | | private static final char lead6byte = (char) Integer.parseInt("11111100", 2); |
| | | private static final char lead4byte = (char) Integer.parseInt("11110000", 2); |
| | | private static final char lead2byte = (char) Integer.parseInt("11000000", 2); |
| | | private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; |
| | | |
| | | public Base64Util() { |
| | | } |
| | | |
| | | public static String encode(byte[] from) { |
| | | StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3); |
| | | int num = 0; |
| | | char currentByte = 0; |
| | | |
| | | int i; |
| | | for (i = 0; i < from.length; ++i) { |
| | | for (num %= 8; num < 8; num += 6) { |
| | | switch (num) { |
| | | case 0: |
| | | currentByte = (char) (from[i] & lead6byte); |
| | | currentByte = (char) (currentByte >>> 2); |
| | | case 1: |
| | | case 3: |
| | | case 5: |
| | | default: |
| | | break; |
| | | case 2: |
| | | currentByte = (char) (from[i] & last6byte); |
| | | break; |
| | | case 4: |
| | | currentByte = (char) (from[i] & last4byte); |
| | | currentByte = (char) (currentByte << 2); |
| | | if (i + 1 < from.length) { |
| | | currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6); |
| | | } |
| | | break; |
| | | case 6: |
| | | currentByte = (char) (from[i] & last2byte); |
| | | currentByte = (char) (currentByte << 4); |
| | | if (i + 1 < from.length) { |
| | | currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4); |
| | | } |
| | | } |
| | | |
| | | to.append(encodeTable[currentByte]); |
| | | } |
| | | } |
| | | |
| | | if (to.length() % 4 != 0) { |
| | | for (i = 4 - to.length() % 4; i > 0; --i) { |
| | | to.append("="); |
| | | } |
| | | } |
| | | |
| | | return to.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | public class BigDecimalUtil { |
| | | |
| | | /**保留两位小数 |
| | | * |
| | | * @param bigDecimal 小数值 |
| | | * @return |
| | | */ |
| | | public static BigDecimal retainDecimal(BigDecimal bigDecimal){ |
| | | bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP); |
| | | return bigDecimal; |
| | | } |
| | | |
| | | /**保留小微小数 |
| | | * |
| | | * @param bigDecimal 小数值 |
| | | * @param decimalNum 保留小数位数 |
| | | * @return |
| | | */ |
| | | public static BigDecimal retainDecimal(BigDecimal bigDecimal,int decimalNum){ |
| | | bigDecimal.setScale(decimalNum, BigDecimal.ROUND_HALF_UP); |
| | | return bigDecimal; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import org.apache.commons.lang.StringUtils; |
| | | |
| | | /** |
| | | * 数据脱敏工具类 |
| | | * |
| | | */ |
| | | public class BlurDataUtil { |
| | | |
| | | /** |
| | | * 手机号脱敏处理 |
| | | * 脱敏规则: 保留前三后四, 比如 18738291234 置换为 187****1234 |
| | | * @param phone |
| | | * @return |
| | | */ |
| | | public static final String blurPhone(String phone) { |
| | | if (StringUtils.isEmpty(phone) || (phone.length() != 11)) { |
| | | return phone; |
| | | } |
| | | return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"); |
| | | } |
| | | |
| | | /** |
| | | * 身份证号脱敏处理 |
| | | * 原身份证号:500222202110275699,脱敏后:132****99308084911 |
| | | * @param idCard |
| | | * @return |
| | | */ |
| | | public static String blurIdCard(String idCard) { |
| | | if (StringUtils.isEmpty(idCard)) { |
| | | return ""; |
| | | } |
| | | /* |
| | | * 参数1:证件号,参数2(OVERLAY):替换后的字符串, |
| | | * 参数3(START):替换的起始下标,参数4(END):替换的结束下标(不包含) |
| | | */ |
| | | return StringUtils.overlay(idCard, "****", 3, 7); |
| | | } |
| | | |
| | | /** |
| | | * 身份证号脱敏处理 |
| | | * 展示 前6位和后6位 |
| | | * @param idCard |
| | | * @return |
| | | */ |
| | | public static String hiddenIdCard(String idCard) {//身份证 |
| | | if (StringUtils.isBlank(idCard)) { |
| | | return ""; |
| | | } |
| | | return StringUtils.left(idCard, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(idCard, 4), StringUtils.length(idCard), "*"), "***")); |
| | | } |
| | | |
| | | /** |
| | | * 邮箱脱敏处理 |
| | | * 原邮箱:zhangsan@qq.com,脱敏后:zhang***@qq.com |
| | | * @param email |
| | | * @return |
| | | */ |
| | | public static String blurEmail(String email) { |
| | | if (StringUtils.isEmpty(email)) { |
| | | return email; |
| | | } |
| | | String encrypt = email.replaceAll("(\\w+)\\w{3}@(\\w+)", "$1***@$2"); |
| | | if(StringUtils.equalsIgnoreCase(email, encrypt)){ |
| | | encrypt = email.replaceAll("(\\w*)\\w{1}@(\\w+)", "$1*@$2"); |
| | | } |
| | | return encrypt; |
| | | } |
| | | |
| | | /** |
| | | * 护照脱敏处理 |
| | | * 脱敏规则:护照前2后3位脱敏,护照一般为8或9位 |
| | | * @param passport |
| | | * @return |
| | | */ |
| | | public static String blurPassport(String passport) { |
| | | if (StringUtils.isEmpty(passport) || (passport.length() < 8)) { |
| | | return passport; |
| | | } |
| | | return passport.substring(0, 2) + new String(new char[passport.length() - 5]).replace("\0", "*") + passport.substring(passport.length() - 3); |
| | | } |
| | | |
| | | /** |
| | | * 字段信息脱敏 |
| | | * 脱敏规则:如果字符长度大于3位,则隐藏最后三位,否则隐藏最后1位 |
| | | * @param field |
| | | * @return |
| | | */ |
| | | public static String blurField(String field) { |
| | | if (StringUtils.isEmpty(field)) { |
| | | return field; |
| | | } |
| | | String encrypt = field.replaceAll("(\\w+)\\w{3}", "$1***"); |
| | | if(StringUtils.equalsIgnoreCase(field, encrypt)){ |
| | | encrypt = field.replaceAll("(\\w*)\\w{1}", "$1*"); |
| | | } |
| | | return encrypt; |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | System.out.println(blurPhone("18738291234")); // 187****1234 |
| | | System.out.println(blurIdCard("500222202110275699")); // 500****99410275467 |
| | | System.out.println(blurEmail("zhangsan@qq.com")); // zhang***@qq.com |
| | | System.out.println(blurPassport("12345678")); // 12***678 |
| | | System.out.println(blurField("I feel so good")); // I f*** so g*** |
| | | } |
| | | |
| | | /* |
| | | * 备注: |
| | | * 1、String.replaceAll(第1个参数是脱敏筛选的正则,第2个参数是脱敏替换的正则) |
| | | * 2、需要引入commons-lang3,这个基本每个项目都用到 |
| | | * <dependency> |
| | | * <groupId>org.apache.commons</groupId> |
| | | * <artifactId>commons-lang3</artifactId> |
| | | * <version>3.7</version> |
| | | * </dependency> |
| | | */ |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import com.qcloud.cos.COSClient; |
| | | import com.qcloud.cos.ClientConfig; |
| | | import com.qcloud.cos.auth.BasicCOSCredentials; |
| | | import com.qcloud.cos.auth.COSCredentials; |
| | | import com.qcloud.cos.exception.CosClientException; |
| | | import com.qcloud.cos.exception.CosServiceException; |
| | | import com.qcloud.cos.http.HttpProtocol; |
| | | import com.qcloud.cos.model.GetObjectRequest; |
| | | import com.qcloud.cos.model.ObjectMetadata; |
| | | import com.qcloud.cos.model.PutObjectRequest; |
| | | import com.qcloud.cos.model.PutObjectResult; |
| | | import com.qcloud.cos.region.Region; |
| | | import com.qcloud.cos.transfer.Download; |
| | | import com.qcloud.cos.transfer.TransferManager; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.Executors; |
| | | |
| | | /**腾讯云 COS |
| | | * @author ChenJiaHe |
| | | * @date 2020-12-03 |
| | | */ |
| | | public class COSUtil { |
| | | |
| | | /** 后端调用上传图片 |
| | | * @param key 上传路径(包括图片名称和和后缀),指定要上传到 COS 上对象键 |
| | | * @param localFile |
| | | * @param secretId 用户id |
| | | * @param secretKey 用户秘钥 |
| | | * @param regionName 存在域,参考腾讯云 |
| | | * @param bucketName 指定要上传到的存储桶 |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static String uploadImg(String key,MultipartFile localFile,String secretId, String secretKey,String regionName,String bucketName) throws IOException { |
| | | |
| | | // 1 初始化用户身份信息(secretId, secretKey)。 |
| | | COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); |
| | | // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224 |
| | | // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。 |
| | | Region region = new Region(regionName); |
| | | ClientConfig clientConfig = new ClientConfig(region); |
| | | // 3 生成 cos 客户端。 |
| | | COSClient cosClient = new COSClient(cred, clientConfig); |
| | | |
| | | //开始上传 |
| | | ObjectMetadata objectMetadata = new ObjectMetadata(); |
| | | // 设置输入流长度为500 |
| | | objectMetadata.setContentLength(localFile.getSize()); |
| | | // 设置 Content type, 默认是 application/octet-stream,对于本地文件上传,默认根据本地文件的后缀进行映射 |
| | | // ,例如 jpg 文件映射 为image/jpeg对于流式上传 默认是 application/octet-stream |
| | | //objectMetadata.setContentType("application/pdf"); |
| | | PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key,localFile.getInputStream(),objectMetadata); |
| | | PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest); |
| | | |
| | | //拼接路径 |
| | | StringBuilder imgUrl = new StringBuilder(); |
| | | imgUrl.append("https://"+bucketName+".cos."+regionName+".myqcloud.com"); |
| | | if(key.startsWith("/")){ |
| | | imgUrl.append(key); |
| | | }else{ |
| | | imgUrl.append("/"+key); |
| | | } |
| | | cosClient.shutdown(); |
| | | return imgUrl.toString(); |
| | | |
| | | } |
| | | |
| | | |
| | | /** 后端调用上传图片 |
| | | * @param key 上传路径(包括图片名称和和后缀),指定要上传到 COS 上对象键 |
| | | * @param localFile |
| | | * @param secretId 用户id |
| | | * @param secretKey 用户秘钥 |
| | | * @param regionName 存在域,参考腾讯云 |
| | | * @param bucketName 指定要上传到的存储桶 |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static String uploadImg(String key,File localFile,String secretId, String secretKey,String regionName,String bucketName) throws IOException { |
| | | |
| | | // 1 初始化用户身份信息(secretId, secretKey)。 |
| | | COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); |
| | | // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224 |
| | | // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。 |
| | | Region region = new Region(regionName); |
| | | ClientConfig clientConfig = new ClientConfig(region); |
| | | // 3 生成 cos 客户端。 |
| | | COSClient cosClient = new COSClient(cred, clientConfig); |
| | | |
| | | // 设置 Content type, 默认是 application/octet-stream,对于本地文件上传,默认根据本地文件的后缀进行映射 |
| | | // ,例如 jpg 文件映射 为image/jpeg对于流式上传 默认是 application/octet-stream |
| | | //objectMetadata.setContentType("application/pdf"); |
| | | PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile); |
| | | PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest); |
| | | |
| | | //拼接路径 |
| | | StringBuilder imgUrl = new StringBuilder(); |
| | | imgUrl.append("https://"+bucketName+".cos."+regionName+".myqcloud.com"); |
| | | if(key.startsWith("/")){ |
| | | imgUrl.append(key); |
| | | }else{ |
| | | imgUrl.append("/"+key); |
| | | } |
| | | cosClient.shutdown(); |
| | | return imgUrl.toString(); |
| | | |
| | | } |
| | | |
| | | /**下载文件 |
| | | * @param key 上传路径(包括图片名称和和后缀),指定要上传到 COS 上对象键 |
| | | * @param secretId 用户id |
| | | * @param secretKey 用户秘钥 |
| | | * @param regionName 存在域,参考腾讯云 |
| | | * @param bucketName 指定要上传到的存储桶 |
| | | */ |
| | | public static File download(String key,String secretId, String secretKey,String regionName,String bucketName){ |
| | | |
| | | // 使用高级接口必须先保证本进程存在一个 TransferManager 实例,如果没有则创建 |
| | | // 详细代码参见本页:高级接口 -> 创建 TransferManager |
| | | TransferManager transferManager = createTransferManager( secretId, secretKey,regionName); |
| | | // 本地文件路径 |
| | | File downloadFile = null; |
| | | try { |
| | | GetObjectRequest getObjectRequest; |
| | | //截取文件名称 |
| | | String[] datas = key.split(regionName+".myqcloud.com/"); |
| | | if(datas.length ==1){ |
| | | getObjectRequest = new GetObjectRequest(bucketName, datas[0]); |
| | | }else if(datas.length ==2){ |
| | | getObjectRequest = new GetObjectRequest(bucketName, datas[1]); |
| | | }else{ |
| | | throw new TipsException("文件路径错误【key】"); |
| | | } |
| | | |
| | | ////生成临时文件 |
| | | //获取后缀名称 |
| | | String suffix = key.substring(key.lastIndexOf(".")); |
| | | downloadFile = File.createTempFile("temp", suffix); |
| | | |
| | | // 返回一个异步结果 Donload, 可同步的调用 waitForCompletion 等待下载结束, 成功返回 void, 失败抛出异常 |
| | | Download download = transferManager.download(getObjectRequest, downloadFile); |
| | | download.waitForCompletion(); |
| | | } catch (CosServiceException e) { |
| | | e.printStackTrace(); |
| | | } catch (CosClientException e) { |
| | | e.printStackTrace(); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | }catch (IOException e){ |
| | | e.printStackTrace(); |
| | | }finally { |
| | | // 确定本进程不再使用 transferManager 实例之后,关闭之 |
| | | // 详细代码参见本页:高级接口 -> 关闭 TransferManager |
| | | shutdownTransferManager(transferManager); |
| | | } |
| | | |
| | | return downloadFile; |
| | | } |
| | | |
| | | /** |
| | | * 创建 TransferManager 实例,这个实例用来后续调用高级接口 |
| | | * @param secretId |
| | | * @param secretKey |
| | | * @return |
| | | */ |
| | | public static TransferManager createTransferManager(String secretId, String secretKey,String regionName) { |
| | | // 创建一个 COSClient 实例,这是访问 COS 服务的基础实例。 |
| | | // 详细代码参见本页: 简单操作 -> 创建 COSClient |
| | | COSClient cosClient = createCOSClient( secretId, secretKey,regionName); |
| | | |
| | | // 自定义线程池大小,建议在客户端与 COS 网络充足(例如使用腾讯云的 CVM,同地域上传 COS)的情况下,设置成16或32即可,可较充分的利用网络资源 |
| | | // 对于使用公网传输且网络带宽质量不高的情况,建议减小该值,避免因网速过慢,造成请求超时。 |
| | | ExecutorService threadPool = Executors.newFixedThreadPool(32); |
| | | |
| | | // 传入一个 threadpool, 若不传入线程池,默认 TransferManager 中会生成一个单线程的线程池。 |
| | | TransferManager transferManager = new TransferManager(cosClient, threadPool); |
| | | |
| | | return transferManager; |
| | | } |
| | | |
| | | /** |
| | | * 关闭管理 |
| | | * @param transferManager |
| | | */ |
| | | public static void shutdownTransferManager(TransferManager transferManager) { |
| | | // 指定参数为 true, 则同时会关闭 transferManager 内部的 COSClient 实例。 |
| | | // 指定参数为 false, 则不会关闭 transferManager 内部的 COSClient 实例。 |
| | | transferManager.shutdownNow(true); |
| | | } |
| | | |
| | | /** |
| | | * 创建 COSClient 实例,这个实例用来后续调用请求 |
| | | * @param secretId |
| | | * @param secretKey |
| | | * @return |
| | | */ |
| | | public static COSClient createCOSClient(String secretId, String secretKey,String regionName) { |
| | | // 设置用户身份信息。 |
| | | // SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理 |
| | | COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); |
| | | |
| | | // ClientConfig 中包含了后续请求 COS 的客户端设置: |
| | | ClientConfig clientConfig = new ClientConfig(); |
| | | |
| | | // 设置 bucket 的地域 |
| | | // COS_REGION 请参照 https://cloud.tencent.com/document/product/436/6224 |
| | | clientConfig.setRegion(new Region(regionName)); |
| | | |
| | | // 设置请求协议, http 或者 https |
| | | // 5.6.53 及更低的版本,建议设置使用 https 协议 |
| | | // 5.6.54 及更高版本,默认使用了 https |
| | | clientConfig.setHttpProtocol(HttpProtocol.https); |
| | | |
| | | // 以下的设置,是可选的: |
| | | |
| | | // 设置 socket 读取超时,默认 30s |
| | | clientConfig.setSocketTimeout(300*1000); |
| | | // 设置建立连接超时,默认 30s |
| | | clientConfig.setConnectionTimeout(30*1000); |
| | | |
| | | // 如果需要的话,设置 http 代理,ip 以及 port |
| | | //clientConfig.setHttpProxyIp("httpProxyIp"); |
| | | //clientConfig.setHttpProxyPort(80); |
| | | |
| | | // 生成 cos 客户端。 |
| | | return new COSClient(cred, clientConfig); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import java.io.FileOutputStream; |
| | | import java.io.OutputStreamWriter; |
| | | import java.util.List; |
| | | |
| | | import org.apache.commons.csv.CSVFormat; |
| | | import org.apache.commons.csv.CSVPrinter; |
| | | |
| | | /** |
| | | * CVS工具类 |
| | | * |
| | | * @author mgchen |
| | | * |
| | | */ |
| | | public class CVSUtil { |
| | | |
| | | public void writeToCVS() throws Exception { |
| | | FileOutputStream fos = new FileOutputStream("E:/cjsworkspace/cjs-excel-demo/target/abc.csv"); |
| | | OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK"); |
| | | |
| | | CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader("姓名", "年龄", "家乡"); |
| | | // CSVFormat.DEFAULT.withHeader(header) |
| | | CSVPrinter csvPrinter = new CSVPrinter(osw, csvFormat); |
| | | |
| | | // csvPrinter = CSVFormat.DEFAULT.withHeader("姓名", "年龄", "家乡").print(osw); |
| | | |
| | | for (int i = 0; i < 10; i++) { |
| | | csvPrinter.printRecord("张三", 20, "湖北"); |
| | | } |
| | | |
| | | csvPrinter.flush(); |
| | | csvPrinter.close(); |
| | | |
| | | } |
| | | |
| | | public static void writeToCVS(String path, String[] headers, List<List<Object>> data) throws Exception { |
| | | FileOutputStream fos = new FileOutputStream(path); |
| | | byte[] uft8bom = { (byte) 0xef, (byte) 0xbb, (byte) 0xbf }; |
| | | fos.write(uft8bom); |
| | | OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8"); |
| | | |
| | | CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader(headers); |
| | | CSVPrinter csvPrinter = new CSVPrinter(osw, csvFormat); |
| | | |
| | | for (int i = 0; i < data.size(); i++) { |
| | | csvPrinter.printRecord(data.get(i)); |
| | | } |
| | | |
| | | csvPrinter.flush(); |
| | | csvPrinter.close(); |
| | | osw.close(); |
| | | fos.close(); |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import java.awt.Color; |
| | | import java.awt.Font; |
| | | import java.awt.Graphics; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | import java.util.Base64; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | |
| | | /** |
| | | * 验证码生成器 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-06-17 |
| | | */ |
| | | public class CheckCodeImageUtil { |
| | | |
| | | private final static int WIDTH = 60; |
| | | private final static int HEIGHT = 20; |
| | | |
| | | private static char[] generateCheckCode() { |
| | | // ������֤����ַ�� |
| | | String chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
| | | char[] rands = new char[4]; |
| | | for (int i = 0; i < 4; i++) { |
| | | int rand = (int) (Math.random() * 35); |
| | | rands[i] = chars.charAt(rand); |
| | | } |
| | | return rands; |
| | | } |
| | | |
| | | private static void drawRands(Graphics g, char[] rands) { |
| | | g.setColor(Color.BLACK); |
| | | g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18)); |
| | | // �ڲ�ͬ�ĸ߶��������֤���ÿ���ַ� |
| | | g.drawString("" + rands[0], 1, 17); |
| | | g.drawString("" + rands[1], 16, 15); |
| | | g.drawString("" + rands[2], 31, 18); |
| | | g.drawString("" + rands[3], 46, 16); |
| | | } |
| | | |
| | | private static void drawBackground(Graphics g) { |
| | | // ������ |
| | | g.setColor(new Color(0xDCDCDC)); |
| | | g.fillRect(0, 0, WIDTH, HEIGHT); |
| | | // ������120�����ŵ� |
| | | for (int i = 0; i < 120; i++) { |
| | | int x = (int) (Math.random() * WIDTH); |
| | | int y = (int) (Math.random() * HEIGHT); |
| | | int red = (int) (Math.random() * 255); |
| | | int green = (int) (Math.random() * 255); |
| | | int blue = (int) (Math.random() * 255); |
| | | g.setColor(new Color(red, green, blue)); |
| | | g.drawOval(x, y, 1, 0); |
| | | } |
| | | } |
| | | |
| | | public static String[] createImage(String id) |
| | | { |
| | | ByteArrayOutputStream bos = null; |
| | | String reStr = ""; |
| | | char[] rands = null; |
| | | try { |
| | | BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); |
| | | Graphics g = image.getGraphics(); |
| | | |
| | | rands = generateCheckCode(); |
| | | |
| | | drawBackground(g); |
| | | drawRands(g, rands); |
| | | |
| | | g.dispose(); |
| | | |
| | | bos = new ByteArrayOutputStream(); |
| | | ImageIO.write(image, "JPEG", bos); |
| | | byte[] buf = bos.toByteArray(); |
| | | reStr = Base64.getEncoder().encodeToString(buf); |
| | | |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | }finally { |
| | | if(bos != null) |
| | | { |
| | | try { |
| | | bos.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | bos = null; |
| | | } |
| | | } |
| | | return new String[] {new String(rands),reStr}; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import java.util.Random; |
| | | |
| | | public class CreateNoTool { |
| | | |
| | | /**获取随机秘钥(数字与大写字母组合) |
| | | * |
| | | * @param y |
| | | * 随机数位数 |
| | | * @return |
| | | */ |
| | | public static String randomKey(Integer y) { |
| | | String[] data = new String[] { |
| | | "0","1","2","3","4","5","6","7","8","9" |
| | | ,"A","B","C","D","E","F","G","H","I","J" |
| | | ,"K","L","M","N","O","P","Q","R","S","T" |
| | | ,"U","V","W","S","Y","Z" |
| | | }; |
| | | String no = ""; |
| | | Random r = new Random(); |
| | | for (int i = 0; i < y; i++) { |
| | | no += data[r.nextInt(data.length-1)]; |
| | | } |
| | | return no; |
| | | } |
| | | |
| | | /**获取随机秘钥(数字) |
| | | * |
| | | * @param y |
| | | * 随机数位数 |
| | | * @return |
| | | */ |
| | | public static String randomKeyNumber(Integer y) { |
| | | String[] data = new String[] { |
| | | "0","1","2","3","4","5","6","7","8","9" |
| | | }; |
| | | String no = ""; |
| | | Random r = new Random(); |
| | | for (int i = 0; i < y; i++) { |
| | | no += data[r.nextInt(data.length-1)]; |
| | | } |
| | | return no; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.Locale; |
| | | |
| | | public class DateUtil { |
| | | |
| | | private static SimpleDateFormat Format_1 = new SimpleDateFormat("yyyyMMdd"); |
| | | private static SimpleDateFormat Format_2 = new SimpleDateFormat("yyyyMMddHHmmss"); |
| | | private static SimpleDateFormat Format_3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | private static SimpleDateFormat Format_4 = new SimpleDateFormat("yyyy-MM-dd"); |
| | | private static SimpleDateFormat Format_5 = new SimpleDateFormat("HH:mm:ss"); |
| | | private static SimpleDateFormat Format_6 = new SimpleDateFormat("yyyyMM"); |
| | | private static SimpleDateFormat Format_7 = new SimpleDateFormat("MM月dd日 HH:mm"); |
| | | private static SimpleDateFormat Format_8 = new SimpleDateFormat("yyyy年MM月"); |
| | | private static SimpleDateFormat Format_9 = new SimpleDateFormat("MM-dd"); |
| | | private static SimpleDateFormat Format_10 = new SimpleDateFormat("yyyy年MM月dd日"); |
| | | private static SimpleDateFormat Format_11 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); |
| | | private static SimpleDateFormat Format_12 = new SimpleDateFormat("yyyyMMddHHmm"); |
| | | private static SimpleDateFormat Format_13 = new SimpleDateFormat("yyyy/MM/dd"); |
| | | private static SimpleDateFormat Format_14 = new SimpleDateFormat("yyyy-MM"); |
| | | private static SimpleDateFormat Format_15 = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
| | | private static SimpleDateFormat Format_16 = new SimpleDateFormat("yyyy/MM/dd HH:mm"); |
| | | private static SimpleDateFormat Format_17 = new SimpleDateFormat("HH:mm"); |
| | | |
| | | /**时间格式转化iso8601 |
| | | * @param date 时间 |
| | | * @return 返回的时间格式字符串 |
| | | */ |
| | | public static String dateFormatISO8601(Date date) { |
| | | if(!SimpleTool.checkNotNull(date)){ |
| | | return ""; |
| | | } |
| | | SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");//设置日期格式 |
| | | return df.format(date); |
| | | } |
| | | |
| | | /**时间格式转化 |
| | | * @param date 时间 |
| | | * @param format 时间格式 |
| | | * @return 返回的时间格式字符串 |
| | | */ |
| | | public static String dateFormat(Date date, String format) { |
| | | if(!SimpleTool.checkNotNull(date)){ |
| | | return ""; |
| | | } |
| | | SimpleDateFormat df = new SimpleDateFormat(format);//设置日期格式 |
| | | return df.format(date); |
| | | } |
| | | |
| | | /**时间戳转时间 |
| | | * @param timestamp 时间戳 |
| | | * @param format 时间格式 |
| | | * @return 返回的时间格式字符串 |
| | | */ |
| | | public static Date timestampToDate(long timestamp, String format) { |
| | | SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | String sd = sdf.format(new Date(timestamp)); // 时间戳转换成时间 |
| | | return DateUtil.parseString(sd,"yyyy-MM-dd HH:mm:ss"); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyyMMdd格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate(Date date) { |
| | | return Format_1.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyyMMddHHmmss格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_1(Date date) { |
| | | return Format_2.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy-MM-dd HH:mm:ss格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_2(Date date) { |
| | | return date == null ? null : Format_3.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy-MM-dd格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_3(Date date) { |
| | | return date != null ? Format_4.format(date) : null; |
| | | } |
| | | |
| | | /** |
| | | * 转换成HH:mm:ss格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_4(Date date) { |
| | | return Format_5.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyyMM格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_5(Date date) { |
| | | return Format_6.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成mm月dd日 HH:mm格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_6(Date date) { |
| | | return Format_7.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy年mm月格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_7(Date date) { |
| | | return Format_8.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成mm-dd格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_8(Date date) { |
| | | return Format_9.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy年MM月dd日格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_9(Date date) { |
| | | return Format_10.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyyMMddHHmm格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_11(Date date) { |
| | | return Format_12.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy年MM月dd日 HH:mm:ss格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_10(Date date) { |
| | | return Format_11.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy/MM/dd 格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_13(Date date) { |
| | | return Format_13.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy-MM 格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_14(Date date) { |
| | | return Format_14.format(date); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 当前时间之前的时间与当前时间相差多少秒 |
| | | * @param startDate 当前时间之前的时间 |
| | | * @return |
| | | */ |
| | | public static int calLastedTime(Date startDate) { |
| | | long nowDate = new Date().getTime(); |
| | | long startDateTime = startDate.getTime(); |
| | | int diffSeconds = (int) ((nowDate - startDateTime) / 1000); |
| | | return diffSeconds; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 转换成yyyyMMddHHmmssSSS格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_15(Date date) { |
| | | return Format_15.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成yyyy/MM/dd HH:mm格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_16(Date date) { |
| | | return Format_16.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成HH:mm格式的日期字符串 |
| | | * |
| | | * @param date |
| | | * @return |
| | | */ |
| | | public static String formatDate_17(Date date) { |
| | | return Format_17.format(date); |
| | | } |
| | | |
| | | /** |
| | | * 转换成字符串yyyyMMddHHmmss成日�? |
| | | * |
| | | * @param str |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static Date parseString(String str) { |
| | | try { |
| | | return Format_2.parse(str); |
| | | }catch (Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 转换成字符串到指定的日期 |
| | | * |
| | | * @param str |
| | | * @param format |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static Date parseString(String str, String format) { |
| | | SimpleDateFormat sdf = new SimpleDateFormat(format); |
| | | try{ |
| | | return sdf.parse(str); |
| | | }catch (Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /**字符串转成时间yyyy-MM-dd HH:mm:ss*/ |
| | | public static Date parseString_1(String str) |
| | | { |
| | | try{ |
| | | return Format_3.parse(str); |
| | | }catch (Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /**字符串转成时间yyyy-MM-dd*/ |
| | | public static Date parseString_2(String str) |
| | | { |
| | | try{ |
| | | return Format_4.parse(str); |
| | | }catch (Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /**时间上秒叠加 |
| | | * @Author: ChenJiaHe |
| | | * @param dateTime 时间 |
| | | * @param second 秒 |
| | | * @return |
| | | */ |
| | | public static Date addSecond(Date dateTime,int second){ |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(dateTime); |
| | | c.add(Calendar.SECOND, second); |
| | | return c.getTime(); |
| | | } |
| | | |
| | | /**时间上分钟叠加 |
| | | * @Author: ChenJiaHe |
| | | * @param dateTime 时间 |
| | | * @param min 分钟 |
| | | * @return |
| | | */ |
| | | public static Date addMin(Date dateTime,int min){ |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(dateTime); |
| | | c.add(Calendar.MINUTE, min); |
| | | return c.getTime(); |
| | | } |
| | | |
| | | /**时间上小时叠加 |
| | | * @Author: ChenJiaHe |
| | | * @param dateTime 时间 |
| | | * @param hour 小时 |
| | | * @return |
| | | */ |
| | | public static Date addhour(Date dateTime,int hour){ |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(dateTime); |
| | | c.add(Calendar.HOUR, hour); |
| | | return c.getTime(); |
| | | } |
| | | |
| | | /**时间上天数叠加 |
| | | * @Author: ChenJiaHe |
| | | * @param dateTime 时间 |
| | | * @param dayNum 天数 |
| | | * @return |
| | | */ |
| | | public static Date addDay(Date dateTime,int dayNum){ |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(dateTime); |
| | | c.add(Calendar.DATE, dayNum); |
| | | return c.getTime(); |
| | | } |
| | | |
| | | /**时间上月数叠加 |
| | | * @Author: ChenJiaHe |
| | | * @param dateTime 时间 |
| | | * @param dayNum 天数 |
| | | * @return |
| | | */ |
| | | public static Date addMonth(Date dateTime,int dayNum){ |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(dateTime); |
| | | c.add(Calendar.MONTH, dayNum); |
| | | return c.getTime(); |
| | | } |
| | | |
| | | /**时间上年数叠加 |
| | | * @Author: ChenJiaHe |
| | | * @param dateTime 时间 |
| | | * @param dayNum 天数 |
| | | * @return |
| | | */ |
| | | public static Date addYear(Date dateTime,int dayNum){ |
| | | Calendar c = Calendar.getInstance(); |
| | | c.setTime(dateTime); |
| | | c.add(Calendar.YEAR, dayNum); |
| | | return c.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 转换成字符串到指定的日期 |
| | | * |
| | | * @param date |
| | | * @param format |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static String formatDate(Date date, String format) { |
| | | if (date == null) { |
| | | return null; |
| | | } |
| | | |
| | | SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA); |
| | | return sdf.format(date); |
| | | } |
| | | |
| | | /**日期转星期 |
| | | * @param dateTime 字符串时间 |
| | | * @param format 字符串时间格式 |
| | | * @param returnType 返回类型 0星期几1周几 |
| | | * @return 数据 |
| | | */ |
| | | public static String dateToWeek(String dateTime,String format,Integer returnType) throws ParseException { |
| | | SimpleDateFormat f = new SimpleDateFormat(format); |
| | | String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; |
| | | if(SimpleTool.checkNotNull(returnType)&&returnType==1){ |
| | | weekDays = new String[]{"周日", "周一", "周二", "周三", "周四", "周五", "周六"}; |
| | | } |
| | | Calendar cal = Calendar.getInstance(); // 获得一个日历 |
| | | Date datet = null; |
| | | datet = f.parse(dateTime); |
| | | cal.setTime(datet); |
| | | |
| | | int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。 |
| | | if (w < 0) |
| | | w = 0; |
| | | return weekDays[w]; |
| | | } |
| | | |
| | | /**日期转星期 |
| | | * @param dateTime 时间 |
| | | * @param returnType 返回类型 0星期几1周几 |
| | | * @return 数据 |
| | | */ |
| | | public static String dateToWeek(Date dateTime,Integer returnType) { |
| | | String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; |
| | | if(SimpleTool.checkNotNull(returnType)&&returnType==1){ |
| | | weekDays = new String[]{"周日", "周一", "周二", "周三", "周四", "周五", "周六"}; |
| | | } |
| | | Calendar cal = Calendar.getInstance(); // 获得一个日历 |
| | | cal.setTime(dateTime); |
| | | |
| | | int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。 |
| | | if (w < 0) |
| | | w = 0; |
| | | return weekDays[w]; |
| | | } |
| | | |
| | | /** |
| | | * 获取两个时间相差分钟数 |
| | | * @param startTime 开始时间 |
| | | * @param endTime 结束时间 |
| | | * @return 分钟 |
| | | */ |
| | | public static long differMinute(Date startTime, Date endTime) { |
| | | long NTime = startTime.getTime(); |
| | | long OTime = endTime.getTime(); |
| | | return (NTime - OTime) / 1000 / 60; |
| | | } |
| | | |
| | | /** |
| | | * 获取两个时间相差分钟数 |
| | | * @param startTime 开始时间 |
| | | * @param endTime 结束时间 |
| | | * @param remainder 余数进1 |
| | | * @return 分钟 |
| | | */ |
| | | public static int differMinute(Date startTime, Date endTime,boolean remainder) { |
| | | BigDecimal sTime = new BigDecimal(startTime.getTime()); |
| | | BigDecimal eTime = new BigDecimal(endTime.getTime()); |
| | | eTime = eTime.subtract(sTime).setScale(0,RoundingMode.HALF_UP); |
| | | if(remainder){ |
| | | eTime = eTime.divide(BigDecimal.valueOf(60000.0)).setScale(0, RoundingMode.UP); |
| | | }else{ |
| | | eTime = eTime.divide(BigDecimal.valueOf(60000.0)).setScale(0, RoundingMode.DOWN); |
| | | } |
| | | return eTime.intValue(); |
| | | } |
| | | |
| | | /** |
| | | * endTime比startTime多的天数 |
| | | * @param startTime 最小时间 |
| | | * @param endTime 最大时间 |
| | | * @return 返回 |
| | | */ |
| | | public static Integer differDay(Date startTime,Date endTime){ |
| | | Calendar cal1 = Calendar.getInstance(); |
| | | cal1.setTime(startTime); |
| | | |
| | | Calendar cal2 = Calendar.getInstance(); |
| | | cal2.setTime(endTime); |
| | | int day1= cal1.get(Calendar.DAY_OF_YEAR); |
| | | int day2 = cal2.get(Calendar.DAY_OF_YEAR); |
| | | |
| | | int year1 = cal1.get(Calendar.YEAR); |
| | | int year2 = cal2.get(Calendar.YEAR); |
| | | if(year1 != year2) { //同一年 |
| | | int timeDistance = 0 ; |
| | | for(int i = year1 ; i < year2 ; i ++) { |
| | | if(i%4==0 && i%100!=0 || i%400==0) {//闰年 |
| | | timeDistance += 366; |
| | | } |
| | | else {//不是闰年 |
| | | timeDistance += 365; |
| | | } |
| | | } |
| | | |
| | | return timeDistance + (day2-day1) ; |
| | | } |
| | | else { //不同年 |
| | | System.out.println("判断day2 - day1 : " + (day2-day1)); |
| | | return day2-day1; |
| | | } |
| | | } |
| | | |
| | | /**判断两个时间是不是同一天*/ |
| | | public static boolean timeEqual(Date startTime,Date endTime){ |
| | | if(startTime == null || endTime==null){ |
| | | return false; |
| | | } |
| | | boolean status = false; |
| | | if(formatDate(startTime,"yyyyMMdd").equals(formatDate(endTime,"yyyyMMdd"))){ |
| | | status = true; |
| | | } |
| | | return status; |
| | | } |
| | | |
| | | /**把秒转换成X天X时X分X秒*/ |
| | | public static String getChineseStr(Integer second) { |
| | | int day = 24 * 60 * 60; |
| | | int hour = 60 * 60; |
| | | int min = 60; |
| | | |
| | | int dayNum = second / day; |
| | | int hourNum = second % day / hour; |
| | | int minNum = second % day % hour / min; |
| | | second = second % day % hour % min; |
| | | |
| | | String str = dayNum > 0 ? dayNum + "天" : ""; |
| | | str += hourNum > 0 ? hourNum + "时" : ""; |
| | | str += minNum > 0 ? minNum + "分" : ""; |
| | | str += second + "秒"; |
| | | |
| | | return str; |
| | | } |
| | | |
| | | /** |
| | | * 针对str格式的时间做转换 格式为"xx:xx" |
| | | * @param time 传入的时间 |
| | | * @return 返回分钟如果10:25,则返回625 |
| | | */ |
| | | public static int getMinuteNum(String time){ |
| | | |
| | | if(!StringUtils.isEmpty(time)) |
| | | { |
| | | String[] arr = time.split(":"); |
| | | if(arr != null && arr.length == 2) |
| | | { |
| | | return Integer.parseInt(arr[0]) * 60 + Integer.parseInt(arr[1]); |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * 获取当前月的开始时间 |
| | | * @param time 时间 |
| | | * @return 返回时间 格式yyyy-MM-dd 00:00:00 |
| | | */ |
| | | public static Date getMonthStart(Date time) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(time); |
| | | calendar.set(Calendar.DAY_OF_MONTH, 1); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | calendar.set(Calendar.MILLISECOND,0); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前月的开始时间 |
| | | * |
| | | * @param num 0拿取当月,正代表后,负代表前,值为几个(月) |
| | | * @return 返回时间 格式yyyy-MM-dd 00:00:00 |
| | | */ |
| | | public static String getMonthStart(Integer num) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.add(Calendar.MONTH, num); |
| | | calendar.set(Calendar.DAY_OF_MONTH, 1); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); |
| | | return sdf.format(calendar.getTime()); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前月的结束时间 |
| | | * @param date 点前时间 |
| | | * @return 返回时间 格式yyyy-MM-dd 23:59:59999 |
| | | */ |
| | | public static Date getMonthEnd(Date date) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | calendar.set(Calendar.MILLISECOND,999); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前月的结束时间,没有毫秒 |
| | | * @param date 点前时间 |
| | | * @return 返回时间 格式yyyy-MM-dd 23:59:59 |
| | | */ |
| | | public static Date getMonthEndNoMillisecond(Date date) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前月的结束时间 |
| | | * @param num 0拿取当月,正代表后,负代表前,值为几个(月) |
| | | * @return 返回时间 格式yyyy-MM-dd 23:59:59 |
| | | */ |
| | | public static String getMonthEnd(Integer num) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.add(Calendar.MONTH, num); |
| | | calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); |
| | | return sdf.format(calendar.getTime()); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前年的开始时间 |
| | | * @param time 时间 |
| | | * @return 返回时间 格式yyyy-MM-dd 00:00:00 |
| | | */ |
| | | public static Date getYearStart(Date time) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(time); |
| | | calendar.set(Calendar.MONTH, 0); |
| | | calendar.set(Calendar.DAY_OF_MONTH, 1); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | calendar.set(Calendar.MILLISECOND,0); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前年的结束时间 |
| | | * @param time 时间 |
| | | * @return 返回时间 格式yyyy-MM-dd 23:59:59999 |
| | | */ |
| | | public static Date getYearEnd(Date time) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(time); |
| | | calendar.set(Calendar.MONTH, 11); |
| | | calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DATE)); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | calendar.set(Calendar.MILLISECOND,999); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前年的结束时间,没有毫秒 |
| | | * @param time 时间 |
| | | * @return 返回时间 格式yyyy-MM-dd 23:59:59 |
| | | */ |
| | | public static Date getYearEndNoMillisecond(Date time) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(time); |
| | | calendar.set(Calendar.MONTH, 11); |
| | | calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DATE)); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | |
| | | /**这天的开始时间 |
| | | * 日期2000-01-01变2000-01-01 00:00:00 |
| | | */ |
| | | public static String dayToStart(Date date) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); |
| | | return sdf.format(calendar.getTime()); |
| | | } |
| | | |
| | | /**这天的最后时间 |
| | | * 日期2000-01-01变2000-01-01 23:59:59 |
| | | */ |
| | | public static String dayToEnd(Date date) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); |
| | | return sdf.format(calendar.getTime()); |
| | | } |
| | | |
| | | /**这天的开始时间 |
| | | * 日期2000-01-01变2000-01-01 00:00:00 |
| | | */ |
| | | public static Date dayToStartDate(Date date) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | calendar.set(Calendar.MILLISECOND, 0); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /**这天的最后时间 |
| | | * 日期2000-01-01变2000-01-01 23:59:59999 |
| | | */ |
| | | public static Date dayToEndDate(Date date) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | calendar.set(Calendar.MILLISECOND, 999); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /**这天的最后时间,没有毫秒 |
| | | * 日期2000-01-01变2000-01-01 23:59:59 |
| | | */ |
| | | public static Date dayToEndDateNoMillisecond(Date date) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 23); |
| | | calendar.set(Calendar.MINUTE, 59); |
| | | calendar.set(Calendar.SECOND, 59); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /**获取月份的天数 |
| | | * @param date 时间 |
| | | * @return 月份的天数 |
| | | */ |
| | | public static int getMonthDays(Date date) { |
| | | Calendar cal = Calendar.getInstance(); |
| | | cal.setTime(date); |
| | | cal.set(Calendar.DATE, 1); |
| | | cal.roll(Calendar.DATE, -1); |
| | | return cal.getActualMaximum(Calendar.DATE); |
| | | } |
| | | |
| | | /**获取月份的天数 |
| | | * @param year 年份 |
| | | * @param month 月份 |
| | | * @return 月份的天数 |
| | | */ |
| | | public static int getMonthDays(int year, int month) { |
| | | Calendar cal = Calendar.getInstance(); |
| | | cal.set(Calendar.YEAR, year); |
| | | cal.set(Calendar.MONTH, (month - 1)); |
| | | cal.set(Calendar.DATE, 1); |
| | | cal.roll(Calendar.DATE, -1); |
| | | return cal.getActualMaximum(Calendar.DATE); |
| | | } |
| | | |
| | | /**获取月份的天数 |
| | | * @param yearMonth 年月 |
| | | * @param format 时间格式 |
| | | * @return 返回 |
| | | */ |
| | | public static int getMonthDays(String yearMonth,String format) { |
| | | SimpleDateFormat sdf = new SimpleDateFormat(format); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | try { |
| | | calendar.setTime(sdf.parse(yearMonth)); |
| | | } catch (ParseException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | calendar.getActualMaximum(Calendar.DAY_OF_MONTH); |
| | | return calendar.getActualMaximum(Calendar.DAY_OF_MONTH); |
| | | } |
| | | |
| | | /**当天多少点前 |
| | | * @param date 时间 |
| | | * @param num 多少点前,不含当点前,24小时制 |
| | | * @return 月份的天数 |
| | | */ |
| | | public static boolean getFrontMinute(Date date,int num) { |
| | | Calendar cal = Calendar.getInstance(); |
| | | cal.setTime(date); |
| | | cal.set(Calendar.HOUR_OF_DAY, num-1); |
| | | cal.set(Calendar.MINUTE, 59); |
| | | cal.set(Calendar.SECOND, 59); |
| | | |
| | | return date.compareTo(cal.getTime()) < 1; |
| | | } |
| | | |
| | | /** |
| | | * 获得某个日期的当天某点 |
| | | * 例如:2022-12-26 11:20:00 -> 2022-12-26 13:00:00 |
| | | * @param num 24小时 |
| | | */ |
| | | public static String getHourDayTime(Date date,int num) { |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | calendar.set(Calendar.HOUR_OF_DAY, num); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); |
| | | return sdf.format(calendar.getTime()); |
| | | } |
| | | |
| | | /** |
| | | * 获取时间当月剩余天数 |
| | | * */ |
| | | public static Integer getMonthSurplus(Date date) { |
| | | Calendar month = Calendar.getInstance(); |
| | | month.setTime(new Date()); |
| | | month.set(Calendar.DATE, 1); |
| | | month.roll(Calendar.DATE, -1); |
| | | return month.getActualMaximum(Calendar.DATE) - Calendar.getInstance().get(Calendar.DAY_OF_MONTH); |
| | | } |
| | | |
| | | /**获取当前时间所在周的周一00:00:00*/ |
| | | public static Date getMonday(Date date) { |
| | | Calendar calendar = Calendar.getInstance(Locale.CHINA); |
| | | calendar.setTime(date); |
| | | //以周一为首日 |
| | | calendar.setFirstDayOfWeek(Calendar.MONDAY); |
| | | calendar.set(Calendar.HOUR_OF_DAY, 0); |
| | | calendar.set(Calendar.MINUTE, 0); |
| | | calendar.set(Calendar.SECOND, 0); |
| | | //周一 |
| | | calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); |
| | | return calendar.getTime(); |
| | | } |
| | | |
| | | /** |
| | | * 根据出生年月日计算年龄 |
| | | * @param birth |
| | | * @return |
| | | */ |
| | | public static int getAge(Date birth) { |
| | | Calendar cal = Calendar.getInstance(); |
| | | int thisYear = cal.get(Calendar.YEAR); |
| | | int thisMonth = cal.get(Calendar.MONTH); |
| | | int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH); |
| | | |
| | | cal.setTime(birth); |
| | | int birthYear = cal.get(Calendar.YEAR); |
| | | int birthMonth = cal.get(Calendar.MONTH); |
| | | int birthdayOfMonth = cal.get(Calendar.DAY_OF_MONTH); |
| | | |
| | | int age = thisYear - birthYear; |
| | | |
| | | // 未足月 |
| | | if (thisMonth <= birthMonth) { |
| | | // 当月 |
| | | if (thisMonth == birthMonth) { |
| | | // 未足日 |
| | | if (dayOfMonth < birthdayOfMonth) { |
| | | age--; |
| | | } |
| | | } else { |
| | | age--; |
| | | } |
| | | } |
| | | return age; |
| | | } |
| | | |
| | | /** |
| | | * 获取某天结束秒数 |
| | | * @param dateTime 日期 |
| | | * @param lateSecond 延迟秒数 |
| | | * @return |
| | | */ |
| | | public static long todayEndSecond(Date dateTime, Long lateSecond) { |
| | | if(dateTime == null){ |
| | | dateTime = new Date(); |
| | | } |
| | | if(lateSecond == null){ |
| | | lateSecond = 0L; |
| | | } |
| | | Date endTime = DateUtil.dayToEndDate(dateTime); |
| | | return differSecond(dateTime, endTime) + lateSecond; |
| | | } |
| | | |
| | | /** |
| | | * 计算2个实际相差秒数 |
| | | * @param startTime 开始时间 |
| | | * @param endTime 结束时间 |
| | | * @return |
| | | */ |
| | | public static long differSecond(Date startTime, Date endTime) { |
| | | if(startTime == null || endTime == null){ |
| | | return 0L; |
| | | } |
| | | long sTime = startTime.getTime(); |
| | | long eTime = endTime.getTime(); |
| | | return (eTime - sTime) / 1000L; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.*; |
| | | import java.net.URLEncoder; |
| | | |
| | | public class DownFileUtil { |
| | | |
| | | /** |
| | | * 下载文件工具 |
| | | * |
| | | * @param path |
| | | * 完整路径(可用simpleToof工具获取) |
| | | */ |
| | | public static void DownFile(HttpServletRequest request,HttpServletResponse response,String path) { |
| | | final String userAgent = request.getHeader("USER-AGENT"); |
| | | try { |
| | | // AdminUpload adminUpload = dm.find(AdminUpload.class, fileName); |
| | | // String str =adminUpload.getPath(); |
| | | String filePath = path; |
| | | // System.out.println("path"+ServletActionContext.getRequest().getRealPath("/") |
| | | // + filePath); |
| | | // File downfile = new |
| | | // File(ServletActionContext.getRequest().getRealPath("/") + |
| | | // filePath); |
| | | File downfile = new File(filePath); |
| | | String filename = ""; |
| | | if(userAgent.equals("MSIE")){//IE浏览器 |
| | | filename = URLEncoder.encode(downfile.getName(),"UTF8"); |
| | | }else if(userAgent.equals("Mozilla")){//google,火狐浏览器 |
| | | filename = new String(downfile.getName().getBytes(), "ISO8859-1"); |
| | | }else{ |
| | | filename = URLEncoder.encode(downfile.getName(),"UTF8");//其他浏览器 |
| | | } |
| | | InputStream fis = new BufferedInputStream(new FileInputStream( |
| | | downfile)); |
| | | byte[] buffer = new byte[fis.available()]; |
| | | fis.read(buffer); |
| | | fis.close(); |
| | | response.reset(); |
| | | response.addHeader("Content-Disposition", |
| | | "attachment;filename=" + filename); |
| | | response.addHeader("Content-Length", |
| | | "" + downfile.length()); |
| | | OutputStream toClient = new BufferedOutputStream( |
| | | response.getOutputStream()); |
| | | response.setContentType( |
| | | "application/octet-stream"); |
| | | toClient.write(buffer); |
| | | toClient.flush(); |
| | | toClient.close(); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 下载文件工具(提示选择路径) |
| | | * |
| | | * @param path |
| | | * 完整路径(可用simpleToof工具获取) |
| | | */ |
| | | public static void DownFileTips(HttpServletRequest request,HttpServletResponse response,String path) { |
| | | final String userAgent = request.getHeader("USER-AGENT"); |
| | | try { |
| | | // AdminUpload adminUpload = dm.find(AdminUpload.class, fileName); |
| | | // String str =adminUpload.getPath(); |
| | | String filePath = path; |
| | | // System.out.println("path"+ServletActionContext.getRequest().getRealPath("/") |
| | | // + filePath); |
| | | // File downfile = new |
| | | // File(ServletActionContext.getRequest().getRealPath("/") + |
| | | // filePath); |
| | | File downfile = new File(filePath); |
| | | |
| | | String filename = ""; |
| | | if(userAgent.equals("MSIE")){//IE浏览器 |
| | | filename = URLEncoder.encode(downfile.getName(),"UTF8"); |
| | | }else if(userAgent.equals("Mozilla")){//google,火狐浏览器 |
| | | filename = new String(downfile.getName().getBytes(), "ISO8859-1"); |
| | | }else{ |
| | | filename = URLEncoder.encode(downfile.getName(),"UTF8");//其他浏览器 |
| | | } |
| | | InputStream fis = new BufferedInputStream(new FileInputStream( |
| | | downfile)); |
| | | byte[] buffer = new byte[fis.available()]; |
| | | fis.read(buffer); |
| | | fis.close(); |
| | | |
| | | response.addHeader("Content-Disposition", "attachment;filename="+ new String(filename.getBytes())); |
| | | OutputStream toClient= new BufferedOutputStream(response.getOutputStream()); |
| | | response.setContentType("application/vnd.ms-excel;charset=utf-8"); |
| | | |
| | | toClient.write(buffer); |
| | | toClient.flush(); |
| | | toClient.close(); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 下载文件工具(提示选择路径) |
| | | * |
| | | * @param downfile |
| | | * 导出的文件 |
| | | * @param fileName |
| | | * 导出的文件名称 |
| | | */ |
| | | public static void DownFileTips(HttpServletRequest request, HttpServletResponse response, File downfile, String fileName) { |
| | | final String userAgent = request.getHeader("USER-AGENT"); |
| | | try { |
| | | if(StringUtils.isEmpty(fileName)){ |
| | | fileName = downfile.getName(); |
| | | } |
| | | String filename = ""; |
| | | if(userAgent.equals("MSIE")){//IE浏览器 |
| | | filename = URLEncoder.encode(fileName,"UTF8"); |
| | | }else if(userAgent.equals("Mozilla")){//google,火狐浏览器 |
| | | filename = new String(fileName.getBytes(), "ISO8859-1"); |
| | | }else{ |
| | | filename = URLEncoder.encode(fileName,"UTF8");//其他浏览器 |
| | | } |
| | | InputStream fis = new BufferedInputStream(new FileInputStream( |
| | | downfile)); |
| | | byte[] buffer = new byte[fis.available()]; |
| | | fis.read(buffer); |
| | | fis.close(); |
| | | |
| | | response.addHeader("Content-Disposition", "attachment;filename="+ filename); |
| | | OutputStream toClient= new BufferedOutputStream(response.getOutputStream()); |
| | | response.setContentType("application/vnd.ms-excel;charset=utf-8"); |
| | | |
| | | toClient.write(buffer); |
| | | toClient.flush(); |
| | | toClient.close(); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 下载文件工具(提示选择路径) |
| | | * |
| | | * @param inputStream |
| | | * 导出的文件流 |
| | | * @param fileName |
| | | * 导出的文件名称 |
| | | */ |
| | | public static void DownFileTips(HttpServletRequest request, HttpServletResponse response, InputStream inputStream , String fileName) { |
| | | final String userAgent = request.getHeader("USER-AGENT"); |
| | | try { |
| | | if(StringUtils.isEmpty(fileName)){ |
| | | throw new RuntimeException("请输入文件名称"); |
| | | } |
| | | String filename = ""; |
| | | if(userAgent.equals("MSIE")){//IE浏览器 |
| | | filename = URLEncoder.encode(fileName,"UTF8"); |
| | | }else if(userAgent.equals("Mozilla")){//google,火狐浏览器 |
| | | filename = new String(fileName.getBytes(), "ISO8859-1"); |
| | | }else{ |
| | | filename = URLEncoder.encode(fileName,"UTF8");//其他浏览器 |
| | | } |
| | | InputStream fis = new BufferedInputStream(inputStream); |
| | | byte[] buffer = new byte[fis.available()]; |
| | | fis.read(buffer); |
| | | fis.close(); |
| | | |
| | | response.addHeader("Content-Disposition", "attachment;filename="+ filename); |
| | | OutputStream toClient= new BufferedOutputStream(response.getOutputStream()); |
| | | response.setContentType("application/vnd.ms-excel;charset=utf-8"); |
| | | |
| | | toClient.write(buffer); |
| | | toClient.flush(); |
| | | toClient.close(); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 下载文件工具(提示选择路径) |
| | | * |
| | | * @param downfile |
| | | * 导出的文件 |
| | | * @param fileName |
| | | * 导出的文件名称 |
| | | */ |
| | | public static void DownFileTips( HttpServletResponse response, File downfile, String fileName) { |
| | | try { |
| | | if(StringUtils.isEmpty(fileName)){ |
| | | fileName = downfile.getName(); |
| | | } |
| | | String filename = ""; |
| | | filename = URLEncoder.encode(fileName,"UTF8");//其他浏览器 |
| | | InputStream fis = new BufferedInputStream(new FileInputStream( |
| | | downfile)); |
| | | byte[] buffer = new byte[fis.available()]; |
| | | fis.read(buffer); |
| | | fis.close(); |
| | | |
| | | response.addHeader("Content-Disposition", "attachment;filename="+ filename); |
| | | OutputStream toClient= new BufferedOutputStream(response.getOutputStream()); |
| | | response.setContentType("application/vnd.ms-excel;charset=utf-8"); |
| | | |
| | | toClient.write(buffer); |
| | | toClient.flush(); |
| | | toClient.close(); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import com.sun.mail.util.MailSSLSocketFactory; |
| | | |
| | | import javax.activation.DataHandler; |
| | | import javax.activation.DataSource; |
| | | import javax.activation.FileDataSource; |
| | | import javax.mail.*; |
| | | import javax.mail.internet.*; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.security.GeneralSecurityException; |
| | | import java.util.Properties; |
| | | |
| | | /**邮件处理工具 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-07-06 |
| | | */ |
| | | public class EmailUtil { |
| | | /** |
| | | * 发送带附件的邮件 |
| | | * |
| | | * @param receive |
| | | * 收件人 |
| | | * @param subject |
| | | * 邮件主题 |
| | | * @param msg |
| | | * 邮件内容 |
| | | * @param filename |
| | | * 附件地址 |
| | | * @param from |
| | | * 发件人电子邮箱 |
| | | * @param pass |
| | | * 发件人电子邮箱密码 |
| | | * @return |
| | | * @throws GeneralSecurityException |
| | | */ |
| | | public static boolean sendMail(String receive, String subject, String msg, String filename, |
| | | String from,String pass) |
| | | throws GeneralSecurityException { |
| | | if (StringUtils.isEmpty(receive)) { |
| | | return false; |
| | | } |
| | | |
| | | // 指定发送邮件的主机为 smtp.qq.com smtp.163.com |
| | | String host = "smtp.qq.com"; // 邮件服务器 |
| | | |
| | | // 获取系统属性 |
| | | Properties properties = System.getProperties(); |
| | | |
| | | // 设置邮件服务器 |
| | | properties.setProperty("mail.smtp.host", host); |
| | | |
| | | properties.put("mail.smtp.auth", "true"); |
| | | MailSSLSocketFactory sf = new MailSSLSocketFactory(); |
| | | sf.setTrustAllHosts(true); |
| | | properties.put("mail.smtp.ssl.enable", "true"); |
| | | properties.put("mail.smtp.ssl.socketFactory", sf); |
| | | // 获取默认session对象 |
| | | Session session = Session.getDefaultInstance(properties, new Authenticator() { |
| | | public PasswordAuthentication getPasswordAuthentication() { // qq邮箱服务器账户、第三方登录授权码 |
| | | return new PasswordAuthentication(from, pass); // 发件人邮件用户名、密码 |
| | | } |
| | | }); |
| | | |
| | | try { |
| | | // 创建默认的 MimeMessage 对象 |
| | | MimeMessage message = new MimeMessage(session); |
| | | |
| | | // Set From: 头部头字段 |
| | | message.setFrom(new InternetAddress(from)); |
| | | |
| | | // Set To: 头部头字段 |
| | | message.addRecipient(Message.RecipientType.TO, new InternetAddress(receive)); |
| | | |
| | | // Set Subject: 主题文字 |
| | | message.setSubject(subject); |
| | | |
| | | // 创建消息部分 |
| | | BodyPart messageBodyPart = new MimeBodyPart(); |
| | | |
| | | // 消息 |
| | | messageBodyPart.setText(msg); |
| | | |
| | | // 创建多重消息 |
| | | Multipart multipart = new MimeMultipart(); |
| | | |
| | | // 设置文本消息部分 |
| | | multipart.addBodyPart(messageBodyPart); |
| | | |
| | | // 附件部分 |
| | | messageBodyPart = new MimeBodyPart(); |
| | | // 设置要发送附件的文件路径 |
| | | if(SimpleTool.checkNotNull(filename)){ |
| | | DataSource source = new FileDataSource(filename); |
| | | if(!SimpleTool.checkNotNull(source)){ |
| | | throw new RuntimeException("获取附件失败!"); |
| | | } |
| | | messageBodyPart.setDataHandler(new DataHandler(source)); |
| | | // messageBodyPart.setFileName(filename); |
| | | // 处理附件名称中文(附带文件路径)乱码问题 |
| | | //messageBodyPart.setFileName(MimeUtility.encodeText(source.getName())); |
| | | messageBodyPart.setFileName(new String(source.getName().toString().getBytes("UTF-8"))); |
| | | multipart.addBodyPart(messageBodyPart); |
| | | } |
| | | |
| | | // 发送完整消息 |
| | | message.setContent(multipart); |
| | | |
| | | // 发送消息 |
| | | Transport.send(message); |
| | | // System.out.println("Sent message successfully...."); |
| | | return true; |
| | | } catch (MessagingException e) { |
| | | e.printStackTrace(); |
| | | } catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return false; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import jxl.CellType; |
| | | import org.apache.poi.hssf.usermodel.*; |
| | | import org.apache.poi.ss.usermodel.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileOutputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Excel工具类(兼容poi4.0+) |
| | | */ |
| | | public class ExcelFileUtil { |
| | | |
| | | /** |
| | | * 读取 Excel文件内容 |
| | | * |
| | | * @param file |
| | | * @param header 是否包括表头 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> readExcelByeFileData(MultipartFile file, boolean header) throws Exception { |
| | | // 结果集 |
| | | List<List<String>> list = new ArrayList<>(); |
| | | if (file == null){ |
| | | return list; |
| | | } |
| | | String fileName = file.getOriginalFilename(); |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | throw new TipsException("上传文件格式不正确"); |
| | | } |
| | | |
| | | Workbook hssfworkbook = WorkbookFactory.create(file.getInputStream()); |
| | | |
| | | int num = hssfworkbook.getNumberOfSheets(); |
| | | if (num == 0){ |
| | | return list; |
| | | } |
| | | List<String> rowList; |
| | | for (int k = 0; k< num ; k++) { |
| | | Sheet sheet = hssfworkbook.getSheetAt(k); |
| | | |
| | | for (int i = 0; i <= sheet.getLastRowNum(); i++) { |
| | | rowList = new ArrayList<>(); |
| | | // 获取第i行的数据 |
| | | Row row = sheet.getRow(i); |
| | | // getLastCellNum() 获取这一行中单元格的数量 |
| | | for (int j = 0; j < row.getLastCellNum(); j++) { |
| | | // 获取第i行第j列的单元格数据 |
| | | rowList.add(row.getCell(j).toString()); |
| | | } |
| | | list.add(rowList); |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 读取 Excel文件内容 |
| | | * |
| | | * @param file |
| | | * @param header 是否包括表头 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> readExcelByeFileData(File file, boolean header) throws Exception { |
| | | // 结果集 |
| | | List<List<String>> list = new ArrayList<>(); |
| | | if (file == null){ |
| | | return list; |
| | | } |
| | | String fileName = file.getName(); |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | throw new TipsException("上传文件格式不正确"); |
| | | } |
| | | |
| | | Workbook hssfworkbook = WorkbookFactory.create(new FileInputStream(file)); |
| | | |
| | | int num = hssfworkbook.getNumberOfSheets(); |
| | | if (num == 0){ |
| | | return list; |
| | | } |
| | | List<String> rowList; |
| | | for (int k = 0; k< num ; k++) { |
| | | Sheet sheet = hssfworkbook.getSheetAt(k); |
| | | |
| | | for (int i = 0; i <= sheet.getLastRowNum(); i++) { |
| | | rowList = new ArrayList<>(); |
| | | // 获取第i行的数据 |
| | | Row row = sheet.getRow(i); |
| | | // getLastCellNum() 获取这一行中单元格的数量 |
| | | for (int j = 0; j < row.getLastCellNum(); j++) { |
| | | // 获取第i行第j列的单元格数据 |
| | | rowList.add(row.getCell(j).toString()); |
| | | } |
| | | list.add(rowList); |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | |
| | | |
| | | private static String objToString(Object obj) { |
| | | if (obj == null) { |
| | | return ""; |
| | | } else { |
| | | if (obj instanceof String) { |
| | | return (String) obj; |
| | | } else if (obj instanceof Date) { |
| | | return null; |
| | | } else { |
| | | return obj.toString(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import com.monitorjbl.xlsx.StreamingReader; |
| | | import org.apache.poi.hssf.usermodel.*; |
| | | import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException; |
| | | import org.apache.poi.ss.usermodel.*; |
| | | import org.apache.poi.xssf.streaming.SXSSFWorkbook; |
| | | import org.apache.poi.xssf.usermodel.XSSFCell; |
| | | import org.apache.poi.xssf.usermodel.XSSFRow; |
| | | import org.apache.poi.xssf.usermodel.XSSFSheet; |
| | | import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.*; |
| | | import java.text.DateFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * @author hjr |
| | | */ |
| | | public final class ExcelUtil { |
| | | |
| | | /** |
| | | * @param excelName |
| | | * 文件名称 |
| | | * @param outPath |
| | | * 保存路径 |
| | | * @param headList |
| | | * Excel文件Head标题集合 |
| | | * @param fieldList |
| | | * Excel文件Field标题集合 根据field来寻找位置填充表格 |
| | | * @param dataList |
| | | * Excel文件数据内容部分 |
| | | * @throws Exception |
| | | */ |
| | | public static String createExcel(String outPath, String excelName, |
| | | String[] headList, String[] fieldList, |
| | | List<Map<String, Object>> dataList) throws Exception { |
| | | |
| | | String filePath = null; |
| | | // 创建新的Excel 工作簿 |
| | | HSSFWorkbook workbook = new HSSFWorkbook(); |
| | | |
| | | // 在Excel工作簿中建一工作表,其名为缺省值 |
| | | // 如要新建一名为"效益指标"的工作表,其语句为: |
| | | // HSSFSheet sheet = workbook.createSheet("效益指标"); |
| | | HSSFSheet sheet = workbook.createSheet(); |
| | | // 在索引0的位置创建行(最顶端的行) |
| | | HSSFRow row = sheet.createRow(0); |
| | | // =============================================================== |
| | | |
| | | HSSFCell cell; |
| | | for (int i = 0; i < headList.length; i++) { |
| | | // 在索引0的位置创建单元格(左上端) |
| | | cell = row.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(headList[i]); |
| | | } |
| | | // =============================================================== |
| | | if (dataList != null) { |
| | | HSSFRow row_value; |
| | | Map<String, Object> dataMap; |
| | | for (int n = 0; n < dataList.size(); n++) { |
| | | // 在索引1的位置创建行 |
| | | row_value = sheet.createRow(n + 1); |
| | | dataMap = dataList.get(n); |
| | | // =============================================================== |
| | | for (int i = 0; i < fieldList.length; i++) { |
| | | // 在索引0的位置创建单元格(左上端) |
| | | cell = row_value.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(objToString(dataMap.get(fieldList[i]))); |
| | | } |
| | | // =============================================================== |
| | | } |
| | | } |
| | | |
| | | // 新建一输出文件流 |
| | | File file = SimpleTool.createFile(outPath, excelName); |
| | | FileOutputStream fOut = new FileOutputStream(file); |
| | | // 把相应的Excel 工作簿存盘 |
| | | workbook.write(fOut); |
| | | fOut.flush(); |
| | | // 操作结束,关闭文件 |
| | | fOut.close(); |
| | | |
| | | if(outPath.endsWith("/")){ |
| | | filePath = outPath + excelName; |
| | | }else{ |
| | | filePath = outPath +"/"+ excelName; |
| | | } |
| | | return filePath; |
| | | } |
| | | |
| | | /**生成临时文件 |
| | | * @param headList |
| | | * Excel文件Head标题集合 |
| | | * @param fieldList |
| | | * Excel文件Field标题集合 根据field来寻找位置填充表格 |
| | | * @param dataList |
| | | * Excel文件数据内容部分 |
| | | * @throws Exception |
| | | */ |
| | | public static File createExcel(String[] headList, String[] fieldList, |
| | | List<Map<String, Object>> dataList) throws Exception { |
| | | File file = File.createTempFile("temp", ".xlsx"); |
| | | try{ |
| | | // 创建新的Excel 工作簿 |
| | | HSSFWorkbook workbook = new HSSFWorkbook(); |
| | | |
| | | // 在Excel工作簿中建一工作表,其名为缺省值 |
| | | // 如要新建一名为"效益指标"的工作表,其语句为: |
| | | // HSSFSheet sheet = workbook.createSheet("效益指标"); |
| | | HSSFSheet sheet = workbook.createSheet(); |
| | | // 在索引0的位置创建行(最顶端的行) |
| | | HSSFRow row = sheet.createRow(0); |
| | | // =============================================================== |
| | | HSSFCell cell; |
| | | for (int i = 0; i < headList.length; i++) { |
| | | // 在索引0的位置创建单元格(左上端) |
| | | cell = row.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(headList[i]); |
| | | } |
| | | // =============================================================== |
| | | if (dataList != null) { |
| | | HSSFRow row_value; |
| | | Map<String, Object> dataMap; |
| | | for (int n = 0; n < dataList.size(); n++) { |
| | | // 在索引1的位置创建行 |
| | | row_value = sheet.createRow(n + 1); |
| | | dataMap = dataList.get(n); |
| | | // =============================================================== |
| | | for (int i = 0; i < fieldList.length; i++) { |
| | | // 在索引0的位置创建单元格(左上端) |
| | | cell = row_value.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(objToString(dataMap.get(fieldList[i]))); |
| | | } |
| | | // =============================================================== |
| | | } |
| | | } |
| | | |
| | | // 新建一输出文件流 |
| | | FileOutputStream fOut = new FileOutputStream(file); |
| | | // 把相应的Excel 工作簿存盘 |
| | | workbook.write(fOut); |
| | | fOut.flush(); |
| | | // 操作结束,关闭文件 |
| | | fOut.close(); |
| | | }catch (Exception e){ |
| | | |
| | | }finally { |
| | | file.deleteOnExit(); |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | /**生成临时文件 |
| | | * @param headList |
| | | * Excel文件Head标题集合 |
| | | * @param fieldList |
| | | * Excel文件Field标题集合 根据field来寻找位置填充表格 |
| | | * @param dataList |
| | | * Excel文件数据内容部分 |
| | | * @throws Exception |
| | | */ |
| | | public static File createExcel(String[] headList, String[] fieldList, List<Map<String, Object>> dataList |
| | | ,Integer height,Integer width) throws Exception { |
| | | File file = File.createTempFile("temp", ".xls"); |
| | | try{ |
| | | |
| | | if(height == null){ |
| | | height = 450; |
| | | } |
| | | if(width == null){ |
| | | width = 5000; |
| | | } |
| | | // 创建新的Excel 工作簿 |
| | | HSSFWorkbook workbook = new HSSFWorkbook(); |
| | | |
| | | //合并的单元格样式 |
| | | HSSFCellStyle boderStyle = workbook.createCellStyle(); |
| | | //垂直居中 |
| | | boderStyle.setVerticalAlignment(VerticalAlignment.CENTER); |
| | | boderStyle.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式 |
| | | |
| | | // 在Excel工作簿中建一工作表,其名为缺省值 |
| | | // 如要新建一名为"效益指标"的工作表,其语句为: |
| | | // HSSFSheet sheet = workbook.createSheet("效益指标"); |
| | | HSSFSheet sheet = workbook.createSheet(); |
| | | // 在索引0的位置创建行(最顶端的行) |
| | | HSSFRow row = sheet.createRow(0); |
| | | // =============================================================== |
| | | HSSFCell cell; |
| | | for (int i = 0; i < headList.length; i++) { |
| | | //高度 |
| | | row.setHeight(height.shortValue()); |
| | | sheet.setColumnWidth(i,width); |
| | | // 在索引0的位置创建单元格(左上端) |
| | | cell = row.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(headList[i]); |
| | | cell.setCellStyle(boderStyle); |
| | | } |
| | | // =============================================================== |
| | | if (dataList != null) { |
| | | HSSFRow row_value; |
| | | Map<String, Object> dataMap; |
| | | for (int n = 0; n < dataList.size(); n++) { |
| | | // 在索引1的位置创建行 |
| | | row_value = sheet.createRow(n + 1); |
| | | row_value.setHeight(height.shortValue()); |
| | | dataMap = dataList.get(n); |
| | | // =============================================================== |
| | | for (int i = 0; i < fieldList.length; i++) { |
| | | // 在索引0的位置创建单元格(左上端) |
| | | sheet.setColumnWidth(i,width); |
| | | cell = row_value.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(objToString(dataMap.get(fieldList[i]))); |
| | | cell.setCellStyle(boderStyle); |
| | | } |
| | | // =============================================================== |
| | | } |
| | | } |
| | | |
| | | // 新建一输出文件流 |
| | | FileOutputStream fOut = new FileOutputStream(file); |
| | | // 把相应的Excel 工作簿存盘 |
| | | workbook.write(fOut); |
| | | fOut.flush(); |
| | | // 操作结束,关闭文件 |
| | | fOut.close(); |
| | | }catch (Exception e){ |
| | | |
| | | }finally { |
| | | file.deleteOnExit(); |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | /**无限制行数生成ecxel,生成临时文件 |
| | | * @param headList |
| | | * Excel文件Head标题集合 |
| | | * @param fieldList |
| | | * Excel文件Field标题集合 根据field来寻找位置填充表格 |
| | | * @param dataList |
| | | * Excel文件数据内容部分 |
| | | * @param height 单元格高度,默认450 |
| | | * @param width 单元格宽度,默认5000 |
| | | * @throws Exception |
| | | */ |
| | | public static File createXSSExcel(String[] headList, String[] fieldList, List<Map<String, Object>> dataList |
| | | ,Integer height,Integer width) throws Exception { |
| | | File file = File.createTempFile("temp", ".xls"); |
| | | try{ |
| | | |
| | | if(height == null){ |
| | | height = 450; |
| | | } |
| | | if(width == null){ |
| | | width = 5000; |
| | | } |
| | | // 创建新的Excel 工作簿 |
| | | //XSSFWorkbook workbook = new XSSFWorkbook(); |
| | | SXSSFWorkbook workbook = new SXSSFWorkbook(1000); |
| | | |
| | | //合并的单元格样式 |
| | | CellStyle boderStyle = workbook.createCellStyle(); |
| | | //垂直居中 |
| | | boderStyle.setVerticalAlignment(VerticalAlignment.CENTER); |
| | | boderStyle.setAlignment(HorizontalAlignment.CENTER); // 创建一个居中格式 |
| | | |
| | | // 在Excel工作簿中建一工作表,其名为缺省值 |
| | | // 如要新建一名为"效益指标"的工作表,其语句为: |
| | | // HSSFSheet sheet = workbook.createSheet("效益指标"); |
| | | Sheet sheet = workbook.createSheet(); |
| | | // 在索引0的位置创建行(最顶端的行) |
| | | Row row = sheet.createRow(0); |
| | | // =============================================================== |
| | | Cell cell; |
| | | for (int i = 0; i < headList.length; i++) { |
| | | //高度 |
| | | row.setHeight(height.shortValue()); |
| | | sheet.setColumnWidth(i,width); |
| | | // 在索引0的位置创建单元格(左上端) |
| | | cell = row.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(headList[i]); |
| | | cell.setCellStyle(boderStyle); |
| | | } |
| | | // =============================================================== |
| | | if (dataList != null) { |
| | | Row row_value; |
| | | Map<String, Object> dataMap; |
| | | for (int n = 0; n < dataList.size(); n++) { |
| | | // 在索引1的位置创建行 |
| | | row_value = sheet.createRow(n + 1); |
| | | row_value.setHeight(height.shortValue()); |
| | | dataMap = dataList.get(n); |
| | | // =============================================================== |
| | | for (int i = 0; i < fieldList.length; i++) { |
| | | // 在索引0的位置创建单元格(左上端) |
| | | sheet.setColumnWidth(i,width); |
| | | cell = row_value.createCell(i); |
| | | // 定义单元格为字符串类型 |
| | | //cell.setCellType(HSSFCell.CELL_TYPE_STRING); |
| | | // 在单元格中输入一些内容 |
| | | cell.setCellValue(objToString(dataMap.get(fieldList[i]))); |
| | | cell.setCellStyle(boderStyle); |
| | | } |
| | | // =============================================================== |
| | | } |
| | | } |
| | | |
| | | // 新建一输出文件流 |
| | | FileOutputStream fOut = new FileOutputStream(file); |
| | | // 把相应的Excel 工作簿存盘 |
| | | workbook.write(fOut); |
| | | fOut.flush(); |
| | | // 操作结束,关闭文件 |
| | | fOut.close(); |
| | | }catch (Exception e){ |
| | | |
| | | }finally { |
| | | file.deleteOnExit(); |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | |
| | | private static String objToString(Object obj) { |
| | | if (obj == null) { |
| | | return ""; |
| | | } else { |
| | | if (obj instanceof String) { |
| | | return (String) obj; |
| | | } else if (obj instanceof Date) { |
| | | return null;// DateUtil.dateToString((Date) |
| | | // obj,DateUtil.DATESTYLE_SHORT_EX); |
| | | } else { |
| | | return obj.toString(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 读取Excel数据 |
| | | * @param file |
| | | * @param header |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> readExcelData(MultipartFile file, boolean header) throws Exception { |
| | | |
| | | String fileName = file.getOriginalFilename(); |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | throw new TipsException("上传文件格式不正确"); |
| | | } |
| | | |
| | | //判断不同格式处理方法不同 |
| | | if(fileName.matches("^.+\\.(?i)(xls)$")){ |
| | | //xls格式使用HSSF |
| | | return readExcelByeFileData(file, header); |
| | | }else{ |
| | | //xlsx格式使用XSSF |
| | | return readExcelByeFileDataToXSSF(file, header); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 读取 Excel文件内容 |
| | | * |
| | | * @param file |
| | | * @param header 是否包括表头 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> readExcelByeFileData(MultipartFile file, boolean header) throws Exception { |
| | | |
| | | String fileName = file.getOriginalFilename(); |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | throw new TipsException("上传文件格式不正确"); |
| | | } |
| | | |
| | | // 结果集 |
| | | List<List<String>> list = new ArrayList<>(); |
| | | |
| | | HSSFWorkbook hssfworkbook = new HSSFWorkbook(file.getInputStream()); |
| | | |
| | | // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数 |
| | | for(int s=0;s<hssfworkbook.getNumberOfSheets();s++) { |
| | | HSSFSheet hssfsheet = hssfworkbook.getSheetAt(s); |
| | | int col = 0; |
| | | // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题 |
| | | for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) { |
| | | HSSFRow hssfrow = hssfsheet.getRow(j); |
| | | if(hssfrow!=null){ |
| | | if(j == 0) { |
| | | col = hssfrow.getPhysicalNumberOfCells(); |
| | | if(!header) { |
| | | //不包括表头 |
| | | continue; |
| | | } |
| | | } |
| | | // 单行数据 |
| | | List<String> arrayString = new ArrayList<>(); |
| | | for (int i = 0; i < col; i++) { |
| | | HSSFCell cell = hssfrow.getCell(i); |
| | | if (cell == null) { |
| | | arrayString.add(""); |
| | | } else if (cell.getCellType() == CellType.NUMERIC) { |
| | | // arrayString[i] = new Double(cell.getNumericCellValue()).toString(); |
| | | if (CellType.NUMERIC == cell.getCellType()) { |
| | | short format = cell.getCellStyle().getDataFormat(); |
| | | if(format == 14 || format == 31 || format == 57 || format == 58){ |
| | | //日期(中文时间格式的) |
| | | Date d = cell.getDateCellValue(); |
| | | DateFormat formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | }else if (HSSFDateUtil.isCellDateFormatted(cell)) { |
| | | Date d = cell.getDateCellValue(); |
| | | //DateFormat formater = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); |
| | | DateFormat formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | } else { |
| | | if(CellType.STRING == cell.getCellType()){ |
| | | arrayString.add(cell.getStringCellValue()); |
| | | //arrayString[i] =cell.getStringCellValue(); |
| | | }else if(CellType.FORMULA==cell.getCellType()){ |
| | | arrayString.add(cell.getCellFormula()); |
| | | //arrayString[i] =cell.getCellFormula(); |
| | | }else if(CellType.NUMERIC== cell.getCellType()){ |
| | | HSSFDataFormatter dataFormatter = new HSSFDataFormatter(); |
| | | arrayString.add(dataFormatter.formatCellValue(cell)); |
| | | //arrayString[i] =dataFormatter.formatCellValue(cell); |
| | | } |
| | | } |
| | | } |
| | | } else if(cell.getCellType() == CellType.BLANK){ |
| | | arrayString.add(""); |
| | | //arrayString[i] = ""; |
| | | } else { // 如果EXCEL表格中的数据类型为字符串型 |
| | | if(cell.getCellType() != CellType.BOOLEAN){ |
| | | arrayString.add(cell.getStringCellValue().trim()); |
| | | }else{ |
| | | arrayString.add(cell.getBooleanCellValue() ? "TRUE" : "FALSE"); |
| | | } |
| | | //arrayString[i] = cell.getStringCellValue().trim(); |
| | | } |
| | | } |
| | | list.add(arrayString); |
| | | } |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * 读取 Excel文件内容 |
| | | * |
| | | * @param file |
| | | * @param header 是否包括表头 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> readExcelByeFileDataToXSSF(MultipartFile file, boolean header) throws Exception { |
| | | |
| | | String fileName = file.getOriginalFilename(); |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | throw new TipsException("上传文件格式不正确"); |
| | | } |
| | | |
| | | // 结果集 |
| | | List<List<String>> list = new ArrayList<>(); |
| | | |
| | | XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file.getInputStream()); |
| | | |
| | | // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数 |
| | | for(int s=0;s<xssfWorkbook.getNumberOfSheets();s++) { |
| | | XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(s); |
| | | int col = 0; |
| | | // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题 |
| | | for (int j = 0; j < xssfSheet.getPhysicalNumberOfRows(); j++) { |
| | | XSSFRow xssfrow = xssfSheet.getRow(j); |
| | | if(xssfrow!=null){ |
| | | if(j == 0) { |
| | | col = xssfrow.getPhysicalNumberOfCells(); |
| | | if(!header) { |
| | | //不包括表头 |
| | | continue; |
| | | } |
| | | } |
| | | // 单行数据 |
| | | List<String> arrayString = new ArrayList<>(); |
| | | for (int i = 0; i < col; i++) { |
| | | XSSFCell cell = xssfrow.getCell(i); |
| | | if (cell == null) { |
| | | arrayString.add(""); |
| | | } else if (cell.getCellType() == CellType.NUMERIC) { |
| | | // arrayString[i] = new Double(cell.getNumericCellValue()).toString(); |
| | | if (CellType.NUMERIC == cell.getCellType()) { |
| | | short format = cell.getCellStyle().getDataFormat(); |
| | | if(format == 14 || format == 31 || format == 57 || format == 58){ |
| | | //日期(中文时间格式的) |
| | | Date d = cell.getDateCellValue(); |
| | | DateFormat formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | }else if (HSSFDateUtil.isCellDateFormatted(cell)) { |
| | | Date d = cell.getDateCellValue(); |
| | | //DateFormat formater = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); |
| | | DateFormat formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | } else { |
| | | if(CellType.STRING == cell.getCellType()){ |
| | | arrayString.add(cell.getStringCellValue()); |
| | | //arrayString[i] =cell.getStringCellValue(); |
| | | }else if(CellType.FORMULA==cell.getCellType()){ |
| | | arrayString.add(cell.getCellFormula()); |
| | | //arrayString[i] =cell.getCellFormula(); |
| | | }else if(CellType.NUMERIC== cell.getCellType()){ |
| | | HSSFDataFormatter dataFormatter = new HSSFDataFormatter(); |
| | | arrayString.add(dataFormatter.formatCellValue(cell)); |
| | | //arrayString[i] =dataFormatter.formatCellValue(cell); |
| | | } |
| | | } |
| | | } |
| | | } else if(cell.getCellType() == CellType.BLANK){ |
| | | arrayString.add(""); |
| | | //arrayString[i] = ""; |
| | | } else { // 如果EXCEL表格中的数据类型为字符串型 |
| | | if(cell.getCellType() != CellType.BOOLEAN){ |
| | | arrayString.add(cell.getStringCellValue().trim()); |
| | | }else{ |
| | | arrayString.add(cell.getBooleanCellValue() ? "TRUE" : "FALSE"); |
| | | } |
| | | |
| | | |
| | | //arrayString[i] = cell.getStringCellValue().trim(); |
| | | } |
| | | } |
| | | list.add(arrayString); |
| | | } |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | |
| | | /**判断excel的版本*/ |
| | | public static Workbook create(InputStream inp) throws IOException { |
| | | //这样写 excel 能兼容03和07 |
| | | return WorkbookFactory.create(inp); |
| | | } |
| | | |
| | | /**读取excel文件,兼容2003和2007 |
| | | * 通过流读取Excel文件 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> getExcelDataCompatible(File file,boolean header) throws Exception { |
| | | try { |
| | | |
| | | String fileName = file.getName(); |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | throw new TipsException("上传文件格式不正确"); |
| | | } |
| | | |
| | | // 结果集 |
| | | List<List<String>> list = new ArrayList<>(); |
| | | Workbook book = create(new BufferedInputStream(new FileInputStream(file))); |
| | | |
| | | // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数 |
| | | Sheet hssfsheet; |
| | | Row hssfrow; |
| | | List<String> arrayString; |
| | | Cell cell; |
| | | short format; |
| | | Date d; |
| | | DateFormat formater; |
| | | HSSFDataFormatter dataFormatter; |
| | | for(int s=0;s<book.getNumberOfSheets();s++) { |
| | | hssfsheet = book.getSheetAt(s); |
| | | int col = 0; |
| | | // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题 |
| | | for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) { |
| | | hssfrow = hssfsheet.getRow(j); |
| | | if(hssfrow!=null){ |
| | | if(j == 0) { |
| | | col = hssfrow.getPhysicalNumberOfCells(); |
| | | if(!header) { |
| | | //不包括表头 |
| | | continue; |
| | | } |
| | | } |
| | | // 单行数据 |
| | | arrayString = new ArrayList<>(); |
| | | for (int i = 0; i < col; i++) { |
| | | cell = hssfrow.getCell(i); |
| | | if (cell == null) { |
| | | arrayString.add(""); |
| | | } else if (cell.getCellType() == CellType.NUMERIC) { |
| | | // arrayString[i] = new Double(cell.getNumericCellValue()).toString(); |
| | | if (CellType.NUMERIC == cell.getCellType()) { |
| | | format = cell.getCellStyle().getDataFormat(); |
| | | if(format == 14 || format == 31 || format == 57 || format == 58){ |
| | | //日期(中文时间格式的) |
| | | d = cell.getDateCellValue(); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | }else if (HSSFDateUtil.isCellDateFormatted(cell)) { |
| | | d = cell.getDateCellValue(); |
| | | //DateFormat formater = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | } else { |
| | | if(CellType.STRING == cell.getCellType()){ |
| | | arrayString.add(cell.getStringCellValue()); |
| | | //arrayString[i] =cell.getStringCellValue(); |
| | | }else if(CellType.FORMULA==cell.getCellType()){ |
| | | arrayString.add(cell.getCellFormula()); |
| | | //arrayString[i] =cell.getCellFormula(); |
| | | }else if(CellType.NUMERIC== cell.getCellType()){ |
| | | dataFormatter = new HSSFDataFormatter(); |
| | | arrayString.add(dataFormatter.formatCellValue(cell)); |
| | | //arrayString[i] =dataFormatter.formatCellValue(cell); |
| | | } |
| | | } |
| | | } |
| | | } else if(cell.getCellType() == CellType.BLANK){ |
| | | arrayString.add(""); |
| | | //arrayString[i] = ""; |
| | | } else { // 如果EXCEL表格中的数据类型为字符串型 |
| | | arrayString.add(cell.getStringCellValue().trim()); |
| | | //arrayString[i] = cell.getStringCellValue().trim(); |
| | | } |
| | | } |
| | | list.add(arrayString); |
| | | } |
| | | } |
| | | } |
| | | return list; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /**读取excel文件,兼容2003和2007 |
| | | * 通过流读取Excel文件 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> getExcelDataCompatible(MultipartFile file,boolean header) throws Exception { |
| | | try { |
| | | |
| | | String fileName = file.getOriginalFilename(); |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | throw new TipsException("上传文件格式不正确"); |
| | | } |
| | | |
| | | // 结果集 |
| | | List<List<String>> list = new ArrayList<>(); |
| | | Workbook book = create(new BufferedInputStream(file.getInputStream())); |
| | | |
| | | Sheet hssfsheet; |
| | | Row hssfrow; |
| | | List<String> arrayString; |
| | | Cell cell; |
| | | short format; |
| | | Date d; |
| | | DateFormat formater; |
| | | HSSFDataFormatter dataFormatter; |
| | | // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数 |
| | | for(int s=0;s<book.getNumberOfSheets();s++) { |
| | | hssfsheet = book.getSheetAt(s); |
| | | int col = 0; |
| | | // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题 |
| | | for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) { |
| | | hssfrow = hssfsheet.getRow(j); |
| | | if(hssfrow!=null){ |
| | | if(j == 0) { |
| | | col = hssfrow.getPhysicalNumberOfCells(); |
| | | if(!header) { |
| | | //不包括表头 |
| | | continue; |
| | | } |
| | | } |
| | | // 单行数据 |
| | | arrayString = new ArrayList<>(); |
| | | for (int i = 0; i < col; i++) { |
| | | cell = hssfrow.getCell(i); |
| | | if (cell == null) { |
| | | arrayString.add(""); |
| | | } else if (cell.getCellType() == CellType.NUMERIC) { |
| | | // arrayString[i] = new Double(cell.getNumericCellValue()).toString(); |
| | | if (CellType.NUMERIC == cell.getCellType()) { |
| | | format = cell.getCellStyle().getDataFormat(); |
| | | if(format == 14 || format == 31 || format == 57 || format == 58){ |
| | | //日期(中文时间格式的) |
| | | d = cell.getDateCellValue(); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | }else if (HSSFDateUtil.isCellDateFormatted(cell)) { |
| | | d = cell.getDateCellValue(); |
| | | //DateFormat formater = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | } else { |
| | | if(CellType.STRING == cell.getCellType()){ |
| | | arrayString.add(cell.getStringCellValue()); |
| | | //arrayString[i] =cell.getStringCellValue(); |
| | | }else if(CellType.FORMULA==cell.getCellType()){ |
| | | arrayString.add(cell.getCellFormula()); |
| | | //arrayString[i] =cell.getCellFormula(); |
| | | }else if(CellType.NUMERIC== cell.getCellType()){ |
| | | dataFormatter = new HSSFDataFormatter(); |
| | | arrayString.add(dataFormatter.formatCellValue(cell)); |
| | | //arrayString[i] =dataFormatter.formatCellValue(cell); |
| | | } |
| | | } |
| | | } |
| | | } else if(cell.getCellType() == CellType.BLANK){ |
| | | arrayString.add(""); |
| | | //arrayString[i] = ""; |
| | | } else { // 如果EXCEL表格中的数据类型为字符串型 |
| | | arrayString.add(cell.getStringCellValue().trim()); |
| | | //arrayString[i] = cell.getStringCellValue().trim(); |
| | | } |
| | | } |
| | | list.add(arrayString); |
| | | } |
| | | } |
| | | } |
| | | return list; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /**读取excel文件,兼容2003和2007 |
| | | * 通过流读取Excel文件 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static List<List<String>> getExcelDataCompatible(InputStream inputStream,boolean header) throws Exception { |
| | | try { |
| | | // 结果集 |
| | | List<List<String>> list = new ArrayList<>(); |
| | | Workbook book = create(new BufferedInputStream(inputStream)); |
| | | |
| | | Sheet hssfsheet; |
| | | Row hssfrow; |
| | | List<String> arrayString; |
| | | Cell cell; |
| | | short format; |
| | | Date d; |
| | | DateFormat formater; |
| | | HSSFDataFormatter dataFormatter; |
| | | // 遍历该表格中所有的工作表,i表示工作表的数量 getNumberOfSheets表示工作表的总数 |
| | | for(int s=0;s<book.getNumberOfSheets();s++) { |
| | | hssfsheet = book.getSheetAt(s); |
| | | int col = 0; |
| | | // 遍历该行所有的行,j表示行数 getPhysicalNumberOfRows行的总数 去除标题 |
| | | for (int j = 0; j < hssfsheet.getPhysicalNumberOfRows(); j++) { |
| | | hssfrow = hssfsheet.getRow(j); |
| | | if(hssfrow!=null){ |
| | | if(j == 0) { |
| | | col = hssfrow.getPhysicalNumberOfCells(); |
| | | if(!header) { |
| | | //不包括表头 |
| | | continue; |
| | | } |
| | | } |
| | | // 单行数据 |
| | | arrayString = new ArrayList<>(); |
| | | for (int i = 0; i < col; i++) { |
| | | cell = hssfrow.getCell(i); |
| | | if (cell == null) { |
| | | arrayString.add(""); |
| | | } else if (cell.getCellType() == CellType.NUMERIC) { |
| | | // arrayString[i] = new Double(cell.getNumericCellValue()).toString(); |
| | | if (CellType.NUMERIC == cell.getCellType()) { |
| | | format = cell.getCellStyle().getDataFormat(); |
| | | if(format == 14 || format == 31 || format == 57 || format == 58){ |
| | | //日期(中文时间格式的) |
| | | d = cell.getDateCellValue(); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | // DateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | }else if (HSSFDateUtil.isCellDateFormatted(cell)) { |
| | | d = cell.getDateCellValue(); |
| | | //DateFormat formater = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | //arrayString[i] = formater.format(d); |
| | | } else { |
| | | if(CellType.STRING == cell.getCellType()){ |
| | | arrayString.add(cell.getStringCellValue()); |
| | | //arrayString[i] =cell.getStringCellValue(); |
| | | }else if(CellType.FORMULA==cell.getCellType()){ |
| | | arrayString.add(cell.getCellFormula()); |
| | | //arrayString[i] =cell.getCellFormula(); |
| | | }else if(CellType.NUMERIC== cell.getCellType()){ |
| | | dataFormatter = new HSSFDataFormatter(); |
| | | arrayString.add(dataFormatter.formatCellValue(cell)); |
| | | //arrayString[i] =dataFormatter.formatCellValue(cell); |
| | | } |
| | | } |
| | | } |
| | | } else if(cell.getCellType() == CellType.BLANK){ |
| | | arrayString.add(""); |
| | | //arrayString[i] = ""; |
| | | } else { // 如果EXCEL表格中的数据类型为字符串型 |
| | | arrayString.add(cell.getStringCellValue().trim()); |
| | | //arrayString[i] = cell.getStringCellValue().trim(); |
| | | } |
| | | } |
| | | list.add(arrayString); |
| | | } |
| | | } |
| | | } |
| | | return list; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 新版读取Excel,只支持2007以上版本,也就是xslx格式 |
| | | * 支持大数据量 |
| | | * @param file 文件 |
| | | * @return 数据 |
| | | */ |
| | | public static List<List<String>> readExcelData(File file){ |
| | | if(!isExcel(file)){ |
| | | throw new TipsException("请上传excel的文件格式!"); |
| | | } |
| | | List<List<String>> listData = new ArrayList<>(); |
| | | try{ |
| | | //rowCacheSize 缓存到内存中的行数(默认是10) |
| | | //bufferSize 读取资源时,缓存到内存的字节大小(默认是1024) |
| | | //open InputStream或者XLSX格式的File(必须) |
| | | Workbook book = StreamingReader.builder() |
| | | .rowCacheSize(100) |
| | | .bufferSize(10240) |
| | | .open(new FileInputStream(file)); |
| | | listData =readhandle(book); |
| | | }catch (OLE2NotOfficeXmlFileException ex){ |
| | | ex.printStackTrace(); |
| | | throw new RuntimeException("excel版本不为2007及以上"); |
| | | } catch (Exception e){ |
| | | e.printStackTrace(); |
| | | throw new RuntimeException(e.getMessage()); |
| | | } |
| | | return listData; |
| | | } |
| | | |
| | | /** |
| | | * 新版读取Excel,只支持2007以上版本,也就是xslx格式 |
| | | * 支持大数据量 |
| | | * @param file 文件 |
| | | * @return 数据 |
| | | */ |
| | | public static List<List<String>> readExcelData(MultipartFile file){ |
| | | if(!isExcel(file)){ |
| | | throw new TipsException("请上传excel的文件格式!"); |
| | | } |
| | | List<List<String>> listData = new ArrayList<>(); |
| | | try{ |
| | | //rowCacheSize 缓存到内存中的行数(默认是10) |
| | | //bufferSize 读取资源时,缓存到内存的字节大小(默认是1024) |
| | | //open InputStream或者XLSX格式的File(必须) |
| | | Workbook book = StreamingReader.builder() |
| | | .rowCacheSize(100) |
| | | .bufferSize(10240) |
| | | .open(new BufferedInputStream(file.getInputStream())); |
| | | |
| | | listData =readhandle(book); |
| | | }catch (OLE2NotOfficeXmlFileException ex){ |
| | | ex.printStackTrace(); |
| | | throw new RuntimeException("excel版本不为2007及以上"); |
| | | } catch (Exception e){ |
| | | e.printStackTrace(); |
| | | throw new RuntimeException(e.getMessage()); |
| | | } |
| | | return listData; |
| | | } |
| | | |
| | | /** |
| | | * 新版读取Excel,只支持2007以上版本,也就是xslx格式 |
| | | * 支持大数据量 |
| | | * @param file 文件 |
| | | * @return 数据 |
| | | */ |
| | | public static List<List<String>> readExcelData(InputStream file){ |
| | | List<List<String>> listData = new ArrayList<>(); |
| | | try{ |
| | | //rowCacheSize 缓存到内存中的行数(默认是10) |
| | | //bufferSize 读取资源时,缓存到内存的字节大小(默认是1024) |
| | | //open InputStream或者XLSX格式的File(必须) |
| | | Workbook book = StreamingReader.builder() |
| | | .rowCacheSize(100) |
| | | .bufferSize(10240) |
| | | .open(file); |
| | | |
| | | listData =readhandle(book); |
| | | }catch (OLE2NotOfficeXmlFileException ex){ |
| | | ex.printStackTrace(); |
| | | throw new RuntimeException("excel版本不为2007及以上"); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | throw new RuntimeException(e.getMessage()); |
| | | } |
| | | return listData; |
| | | } |
| | | |
| | | /**处理数据*/ |
| | | public static List<List<String>> readhandle(Workbook book){ |
| | | List<List<String>> listData = new ArrayList<>(); |
| | | |
| | | //是否存在数据 |
| | | boolean isData; |
| | | List<String> arrayString; |
| | | short format; |
| | | Date d; |
| | | DateFormat formater; |
| | | Sheet sheet; |
| | | Cell cell; |
| | | //遍历所有的sheet |
| | | for(int i=0;i<book.getNumberOfSheets();i++) { |
| | | sheet = book.getSheetAt(i); |
| | | //列数 |
| | | Integer arrange = null; |
| | | //遍历所有的行 |
| | | for (Row row : sheet) { |
| | | if(row == null){ |
| | | continue; |
| | | } |
| | | isData = false; |
| | | arrayString = new ArrayList<>(); |
| | | if(arrange == null){ |
| | | arrange = row.getPhysicalNumberOfCells(); |
| | | } |
| | | //遍历所有的列 |
| | | for (int j = 0;j<arrange;j++) { |
| | | cell = row.getCell(j); |
| | | if (cell == null) { |
| | | arrayString.add(""); |
| | | }else{ |
| | | if (cell.getCellType() == CellType.NUMERIC) { |
| | | isData = true; |
| | | format = cell.getCellStyle().getDataFormat(); |
| | | if (format == 14 || format == 31 || format == 57 || format == 58) { |
| | | //日期(中文时间格式的) |
| | | d = cell.getDateCellValue(); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | } else if (HSSFDateUtil.isCellDateFormatted(cell)) { |
| | | d = cell.getDateCellValue(); |
| | | formater = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); |
| | | arrayString.add(formater.format(d)); |
| | | } else { |
| | | if (CellType.STRING == cell.getCellType()) { |
| | | arrayString.add(cell.getStringCellValue()); |
| | | } else if (CellType.FORMULA == cell.getCellType()) { |
| | | arrayString.add(cell.getCellFormula()); |
| | | } else { |
| | | arrayString.add(cell.getStringCellValue().trim()); |
| | | } |
| | | } |
| | | } else if (cell.getCellType() == CellType.BLANK) { |
| | | arrayString.add(""); |
| | | } else { // 如果EXCEL表格中的数据类型为字符串型 |
| | | isData = true; |
| | | arrayString.add(cell.getStringCellValue().trim()); |
| | | } |
| | | } |
| | | } |
| | | if (isData) { |
| | | listData.add(arrayString); |
| | | } |
| | | } |
| | | } |
| | | return listData; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * p判断是否excel文件 |
| | | * @param file |
| | | * @return |
| | | */ |
| | | public static boolean isExcel(MultipartFile file){ |
| | | return isExcel(file.getOriginalFilename()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * p判断是否excel文件 |
| | | * @param file |
| | | * @return |
| | | */ |
| | | public static boolean isExcel(File file){ |
| | | return isExcel(file.getName()); |
| | | } |
| | | |
| | | |
| | | /**判断文件格式是不是excel*/ |
| | | public static boolean isExcel(String fileName){ |
| | | if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | public static File createExcelByImg(String[] headList, String[] fieldList, List<Map<String, Object>> dataList, Integer height, Integer width) throws Exception { |
| | | File file = File.createTempFile("temp", ".xls"); |
| | | FileOutputStream fileOut = null; |
| | | BufferedImage bufferImg = null; |
| | | |
| | | try { |
| | | ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); |
| | | if (height == null) { |
| | | height = 450; |
| | | } |
| | | |
| | | if (width == null) { |
| | | width = 1000; |
| | | } |
| | | |
| | | HSSFWorkbook workbook = new HSSFWorkbook(); |
| | | HSSFCellStyle boderStyle = workbook.createCellStyle(); |
| | | boderStyle.setVerticalAlignment(VerticalAlignment.CENTER); |
| | | boderStyle.setAlignment(HorizontalAlignment.CENTER); |
| | | HSSFSheet sheet = workbook.createSheet(); |
| | | HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); |
| | | HSSFRow row = sheet.createRow(0); |
| | | |
| | | HSSFCell anchor; |
| | | for(int i = 0; i < headList.length; ++i) { |
| | | row.setHeight(height.shortValue()); |
| | | sheet.setColumnWidth(i, width); |
| | | anchor = row.createCell(i); |
| | | anchor.setCellValue(headList[i]); |
| | | anchor.setCellStyle(boderStyle); |
| | | } |
| | | |
| | | HSSFRow row_value = null; |
| | | anchor = null; |
| | | HSSFCell cell = null; |
| | | if (dataList != null) { |
| | | for(int n = 0; n < dataList.size(); ++n) { |
| | | row_value = sheet.createRow(n + 1); |
| | | row_value.setHeight(height.shortValue()); |
| | | Map<String, Object> dataMap = (Map)dataList.get(n); |
| | | |
| | | for(int i = 0; i < fieldList.length; ++i) { |
| | | sheet.setColumnWidth(i, width); |
| | | cell = row_value.createCell(i); |
| | | Object value = dataMap.get(fieldList[i]); |
| | | if (value != null && "class java.io.File".equals(value.getClass().toString())) { |
| | | File file2 = (File)value; |
| | | if (file2 == null) { |
| | | cell.setCellValue(""); |
| | | } else { |
| | | bufferImg = ImageIO.read(file2); |
| | | ImageIO.write(bufferImg, "jpg", byteArrayOut); |
| | | HSSFClientAnchor anchor1 = new HSSFClientAnchor(0, 0, 1023, 255, (short)i, n + 1, (short)i, n + 1); |
| | | anchor1.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); |
| | | patriarch.createPicture(anchor1, workbook.addPicture(byteArrayOut.toByteArray(), 5)); |
| | | } |
| | | } else { |
| | | cell.setCellValue(objToString(dataMap.get(fieldList[i]))); |
| | | cell.setCellStyle(boderStyle); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | FileOutputStream fOut = new FileOutputStream(file); |
| | | workbook.write(fOut); |
| | | fOut.flush(); |
| | | fOut.close(); |
| | | } catch (Exception var25) { |
| | | var25.printStackTrace(); |
| | | } finally { |
| | | file.deleteOnExit(); |
| | | } |
| | | |
| | | return file; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import org.apache.commons.fileupload.FileItem; |
| | | import org.apache.commons.fileupload.disk.DiskFileItemFactory; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.multipart.commons.CommonsMultipartFile; |
| | | import sun.misc.BASE64Decoder; |
| | | import sun.misc.BASE64Encoder; |
| | | |
| | | import java.io.*; |
| | | import java.net.URL; |
| | | import java.net.URLConnection; |
| | | import java.util.Base64; |
| | | |
| | | /** |
| | | * 文件转换工具类 |
| | | * @USER: fhx |
| | | * @DATE: 2022/3/2 |
| | | **/ |
| | | public class FileConvertTool { |
| | | |
| | | private static final int BUFFER_SIZE = 2 * 1024; |
| | | |
| | | |
| | | /** 获取网络路径文件流 */ |
| | | public static InputStream getUrlFile(String urlPath) throws IOException { |
| | | if(StringUtils.isEmpty(urlPath)){ |
| | | return null; |
| | | } |
| | | // 构造URL |
| | | URL url = new URL(urlPath); |
| | | // 打开连接 |
| | | URLConnection con = url.openConnection(); |
| | | //设置请求超时为5s |
| | | con.setConnectTimeout(5*1000); |
| | | // 输入流 |
| | | InputStream is = con.getInputStream(); |
| | | return is; |
| | | } |
| | | |
| | | /** |
| | | * 获取文件base64字符串 |
| | | * @param urlPath 文件路径 |
| | | * @return 返回base64编码 |
| | | */ |
| | | public static String getFileBaseStrByUrl(String urlPath) throws IOException { |
| | | InputStream is = getUrlFile(urlPath); |
| | | byte[] bytes = IOUtils.toByteArray(is); |
| | | String encoded = Base64.getEncoder().encodeToString(bytes); |
| | | return encoded; |
| | | } |
| | | |
| | | // inputStream转outputStream |
| | | public static ByteArrayOutputStream parse(final InputStream in) throws Exception { |
| | | final ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); |
| | | int ch; |
| | | while ((ch = in.read()) != -1) { |
| | | swapStream.write(ch); |
| | | } |
| | | return swapStream; |
| | | } |
| | | |
| | | // outputStream转inputStream |
| | | public static ByteArrayInputStream parse(final OutputStream out) throws Exception { |
| | | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| | | baos = (ByteArrayOutputStream) out; |
| | | final ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray()); |
| | | return swapStream; |
| | | } |
| | | |
| | | // inputStream转String |
| | | public static String parse_String(final InputStream in) throws Exception { |
| | | final ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); |
| | | int ch; |
| | | while ((ch = in.read()) != -1) { |
| | | swapStream.write(ch); |
| | | } |
| | | return swapStream.toString(); |
| | | } |
| | | |
| | | // OutputStream 转String |
| | | public static String parse_String(final OutputStream out) throws Exception { |
| | | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| | | baos = (ByteArrayOutputStream) out; |
| | | final ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray()); |
| | | return swapStream.toString(); |
| | | } |
| | | |
| | | // String转inputStream |
| | | public static ByteArrayInputStream parse_inputStream(final String in) throws Exception { |
| | | final ByteArrayInputStream input = new ByteArrayInputStream(in.getBytes()); |
| | | return input; |
| | | } |
| | | |
| | | // String 转outputStream |
| | | public static ByteArrayOutputStream parse_outputStream(final String in) throws Exception { |
| | | return parse(parse_inputStream(in)); |
| | | } |
| | | |
| | | /** |
| | | * 根据byte数组,生成文件 |
| | | */ |
| | | public static File getFile(byte[] bfile, String filePath,String fileName) { |
| | | BufferedOutputStream bos = null; |
| | | FileOutputStream fos = null; |
| | | File file = null; |
| | | try { |
| | | File dir = new File(filePath); |
| | | if(!dir.exists()){//判断文件目录是否存在 |
| | | dir.mkdirs(); |
| | | } |
| | | file = new File(filePath+"/"+fileName); |
| | | fos = new FileOutputStream(file); |
| | | bos = new BufferedOutputStream(fos); |
| | | bos.write(bfile); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | if (bos != null) { |
| | | try { |
| | | bos.close(); |
| | | } catch (IOException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } |
| | | if (fos != null) { |
| | | try { |
| | | fos.close(); |
| | | } catch (IOException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | /** |
| | | * 根据byte数组,生成文件 |
| | | */ |
| | | public static File getFile(InputStream in, String filePath, String fileName) { |
| | | if(in == null){ |
| | | return null; |
| | | } |
| | | BufferedOutputStream bos = null; |
| | | FileOutputStream fos = null; |
| | | File file = null; |
| | | try { |
| | | File dir = new File(filePath); |
| | | //判断文件目录是否存在 |
| | | if(!dir.exists()){ |
| | | dir.mkdirs(); |
| | | } |
| | | file = new File(filePath+"/"+fileName); |
| | | fos = new FileOutputStream(file); |
| | | byte[] b = new byte[BUFFER_SIZE]; |
| | | // while ((in.read(b)) != -1) { |
| | | // fos.write(b); // 写入数据 |
| | | // } |
| | | int len; |
| | | while ((len = in.read(b)) != -1){ |
| | | fos.write(b, 0, len); |
| | | } |
| | | in.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | if (bos != null) { |
| | | try { |
| | | bos.close(); |
| | | } catch (IOException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } |
| | | if (fos != null) { |
| | | try { |
| | | fos.close(); |
| | | } catch (IOException e1) { |
| | | e1.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | /** |
| | | * 获得指定文件的byte数组 |
| | | */ |
| | | private static byte[] getBytes(String filePath){ |
| | | byte[] buffer = null; |
| | | try { |
| | | File file = new File(filePath); |
| | | FileInputStream fis = new FileInputStream(file); |
| | | ByteArrayOutputStream bos = new ByteArrayOutputStream(1000); |
| | | byte[] b = new byte[1000]; |
| | | int n; |
| | | while ((n = fis.read(b)) != -1) { |
| | | bos.write(b, 0, n); |
| | | } |
| | | fis.close(); |
| | | bos.close(); |
| | | buffer = bos.toByteArray(); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return buffer; |
| | | } |
| | | |
| | | public static MultipartFile getMultipartFile(File file) { |
| | | FileItem item = new DiskFileItemFactory().createItem("file" |
| | | , MediaType.MULTIPART_FORM_DATA_VALUE |
| | | , true |
| | | , file.getName()); |
| | | try (InputStream input = new FileInputStream(file); |
| | | OutputStream os = item.getOutputStream()) { |
| | | // 流转移 |
| | | IOUtils.copy(input, os); |
| | | } catch (Exception e) { |
| | | throw new IllegalArgumentException("Invalid file: " + e, e); |
| | | } |
| | | |
| | | return new CommonsMultipartFile(item); |
| | | } |
| | | |
| | | /** |
| | | * 根据路径删除指定的目录或文件,无论存在与否 |
| | | *@param sPath 要删除的目录或文件 |
| | | *@return 删除成功返回 true,否则返回 false。 |
| | | */ |
| | | public static boolean deleteFolder(String sPath) { |
| | | File file = new File(sPath); |
| | | // 判断目录或文件是否存在 |
| | | if (!file.exists()) { |
| | | // 不存在返回 true |
| | | return true; |
| | | } else { |
| | | // 判断是否为文件 |
| | | if (file.isFile()) { // 为文件时调用删除文件方法 |
| | | return deleteFile(sPath); |
| | | } else { // 为目录时调用删除目录方法 |
| | | return deleteDirectory(sPath); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除单个文件 |
| | | * @param sPath 被删除文件的文件名 |
| | | * @return 单个文件删除成功返回true,否则返回false |
| | | */ |
| | | public static boolean deleteFile(String sPath) { |
| | | File file = new File(sPath); |
| | | // 路径为文件且不为空则进行删除 |
| | | if (file.isFile() && file.exists()) { |
| | | file.delete(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 删除单个文件 |
| | | * @param file 被删除文件 |
| | | * @return 单个文件删除成功返回true,否则返回false |
| | | */ |
| | | public static boolean deleteFile(File file) { |
| | | if(file == null){ |
| | | return true; |
| | | } |
| | | // 路径为文件且不为空则进行删除 |
| | | if (file.isFile() && file.exists()) { |
| | | file.delete(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 删除目录(文件夹)以及目录下的文件 |
| | | * @param sPath 被删除目录的文件路径 |
| | | * @return 目录删除成功返回true,否则返回false |
| | | */ |
| | | public static boolean deleteDirectory(String sPath) { |
| | | //如果sPath不以文件分隔符结尾,自动添加文件分隔符 |
| | | if (!sPath.endsWith(File.separator)) { |
| | | sPath = sPath + File.separator; |
| | | } |
| | | File dirFile = new File(sPath); |
| | | //如果dir对应的文件不存在,或者不是一个目录,则退出 |
| | | if (!dirFile.exists() || !dirFile.isDirectory()) { |
| | | return false; |
| | | } |
| | | boolean flag = true; |
| | | //删除文件夹下的所有文件(包括子目录) |
| | | File[] files = dirFile.listFiles(); |
| | | for (int i = 0; i < files.length; i++) { |
| | | //删除子文件 |
| | | if (files[i].isFile()) { |
| | | flag = deleteFile(files[i].getAbsolutePath()); |
| | | if (!flag) break; |
| | | } //删除子目录 |
| | | else { |
| | | flag = deleteDirectory(files[i].getAbsolutePath()); |
| | | if (!flag) break; |
| | | } |
| | | } |
| | | if (!flag) return false; |
| | | //删除当前目录 |
| | | if (dirFile.delete()) { |
| | | return true; |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public static String encodeBase64File(File file) throws Exception { |
| | | FileInputStream fileInputStream = new FileInputStream(file); |
| | | byte[] bytes = new byte[fileInputStream.available()]; |
| | | // 读取到 byte 里面 |
| | | fileInputStream.read(bytes); |
| | | fileInputStream.close(); |
| | | BASE64Encoder base64Encoder = new BASE64Encoder(); |
| | | // 得到文件 之后转成beye 然后使用base64转码 |
| | | // 转码 |
| | | String encode = base64Encoder.encode(bytes); |
| | | return encode; |
| | | } |
| | | |
| | | public static String encodeBase64File(MultipartFile multipartFile) throws Exception { |
| | | if (multipartFile == null) { |
| | | throw new TipsException("未检查到上传的文件!"); |
| | | } |
| | | String imageBaseStr = null; |
| | | try { |
| | | String contentType = multipartFile.getContentType(); |
| | | byte[] imageBytes = multipartFile.getBytes(); |
| | | BASE64Encoder base64Encoder = new BASE64Encoder(); |
| | | // imageBaseStr = "data:" + contentType + ";base64," + base64Encoder.encode(imageBytes); |
| | | imageBaseStr = base64Encoder.encode(imageBytes); |
| | | imageBaseStr = imageBaseStr.replaceAll("[\\s*\t\n\r]", ""); |
| | | } catch (IOException e) { |
| | | throw new TipsException("文件转换base64异常"); |
| | | } |
| | | //返回生成的编码 |
| | | return imageBaseStr; |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import org.apache.commons.io.FileUtils; |
| | | |
| | | import java.io.*; |
| | | import java.net.URL; |
| | | |
| | | /** |
| | | * 文件读取工具类 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-06-17 |
| | | */ |
| | | public class FileUtil { |
| | | |
| | | /** |
| | | * @param pathUrl 网络路径 |
| | | * @return 文件 |
| | | */ |
| | | public static File getUrlFile(String pathUrl){ |
| | | File temp = null; |
| | | try{ |
| | | URL url = new URL(pathUrl); |
| | | temp = File.createTempFile("temp", ".xls"); |
| | | FileUtils.copyURLToFile(url, temp); |
| | | temp.deleteOnExit(); |
| | | }catch (Exception e){ |
| | | throw new RuntimeException("通过URL获取文件出错",e); |
| | | } |
| | | return temp; |
| | | } |
| | | |
| | | /** |
| | | * 读取文件内容,作为字符串返回 |
| | | */ |
| | | public static String readFileAsString(String filePath) throws IOException { |
| | | File file = new File(filePath); |
| | | if (!file.exists()) { |
| | | throw new FileNotFoundException(filePath); |
| | | } |
| | | |
| | | if (file.length() > 1024 * 1024 * 1024) { |
| | | throw new IOException("File is too large"); |
| | | } |
| | | |
| | | StringBuilder sb = new StringBuilder((int) (file.length())); |
| | | // 创建字节输入流 |
| | | FileInputStream fis = new FileInputStream(filePath); |
| | | // 创建一个长度为10240的Buffer |
| | | byte[] bbuf = new byte[10240]; |
| | | // 用于保存实际读取的字节数 |
| | | int hasRead = 0; |
| | | while ( (hasRead = fis.read(bbuf)) > 0 ) { |
| | | sb.append(new String(bbuf, 0, hasRead)); |
| | | } |
| | | fis.close(); |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 根据文件路径读取byte[] 数组 |
| | | */ |
| | | public static byte[] readFileByBytes(String filePath) throws IOException { |
| | | File file = new File(filePath); |
| | | if (!file.exists()) { |
| | | throw new FileNotFoundException(filePath); |
| | | } else { |
| | | ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); |
| | | BufferedInputStream in = null; |
| | | |
| | | try { |
| | | in = new BufferedInputStream(new FileInputStream(file)); |
| | | short bufSize = 1024; |
| | | byte[] buffer = new byte[bufSize]; |
| | | int len1; |
| | | while (-1 != (len1 = in.read(buffer, 0, bufSize))) { |
| | | bos.write(buffer, 0, len1); |
| | | } |
| | | |
| | | byte[] var7 = bos.toByteArray(); |
| | | return var7; |
| | | } finally { |
| | | try { |
| | | if (in != null) { |
| | | in.close(); |
| | | } |
| | | } catch (IOException var14) { |
| | | var14.printStackTrace(); |
| | | } |
| | | |
| | | bos.close(); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import com.hx.exception.TipsException; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.*; |
| | | import java.net.FileNameMap; |
| | | import java.net.URL; |
| | | import java.net.URLConnection; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** 文件处理工具 |
| | | * @author ChenJiaHe |
| | | * @Date 2020-06-17 |
| | | */ |
| | | public class FileUtils { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(FileUtils.class); |
| | | |
| | | private static int BUFFER_SIZE = 1024; |
| | | |
| | | /** |
| | | * @param path |
| | | * @MethodName fileIsExists |
| | | * @Description 文件是否存在 |
| | | * @Author ChenJiaHe |
| | | * @Date 2019/9/7 9:13 |
| | | * @Since JDK 1.8 |
| | | */ |
| | | public static boolean fileIsExists(String path) { |
| | | File file = new File(path); |
| | | if (file.exists()) { |
| | | return true; |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param sourceFile |
| | | * @param targetFile |
| | | * @MethodName copyFile |
| | | * @Description 复制文件 |
| | | * @Author ChenJiaHe |
| | | * @Date 2019/9/7 9:36 |
| | | * @Since JDK 1.8 |
| | | */ |
| | | public static void copyFile(File sourceFile, File targetFile) throws IOException { |
| | | BufferedInputStream inputStream = null; |
| | | BufferedOutputStream outputStream = null; |
| | | try { |
| | | inputStream = new BufferedInputStream(new FileInputStream(sourceFile)); |
| | | outputStream = new BufferedOutputStream(new FileOutputStream(targetFile)); |
| | | byte[] b = new byte[BUFFER_SIZE]; |
| | | int len; |
| | | while ((len = inputStream.read(b)) != -1) { |
| | | outputStream.write(b, 0, len); |
| | | } |
| | | outputStream.flush(); |
| | | } catch (Exception e) { |
| | | logger.error("copy file error", e); |
| | | } finally { |
| | | if (inputStream != null) { |
| | | inputStream.close(); |
| | | } |
| | | if (outputStream != null) { |
| | | outputStream.close(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param path |
| | | * @param fileType 文件类型,0 = 文件夹 1 = 文件 |
| | | * @MethodName getAllFiles |
| | | * @Description 讀取文件夹下的,不包括子文件夹内 |
| | | * @Author ChenJiaHe |
| | | * @Date 2019/9/17 15:56 |
| | | * @Since JDK 1.8 |
| | | */ |
| | | public static List<String> getAllFiles(String path, String fileType) { |
| | | List<String> fileList = new ArrayList<>(); |
| | | File fileDic = new File(path); |
| | | File[] files = fileDic.listFiles(); |
| | | for (File file : files) { |
| | | if ("1".equals(fileType)) { |
| | | if (file.isFile()) { |
| | | fileList.add(file.toString()); |
| | | } |
| | | } |
| | | if ("0".equals(fileType)) { |
| | | if (file.isDirectory()) { |
| | | fileList.add(file.toString()); |
| | | } |
| | | } |
| | | } |
| | | return fileList; |
| | | } |
| | | |
| | | /** |
| | | * @param path |
| | | * @MethodName getFolderFiles |
| | | * @Description 递归获取所有包括子文件夹的文件 |
| | | * @Author ChenJiaHe |
| | | * @Date 2019/9/17 16:11 |
| | | * @Since JDK 1.8 |
| | | */ |
| | | public static void getAllFileName(String path, List<String> listFileName) { |
| | | try { |
| | | File file = new File(path); |
| | | File[] files = file.listFiles(); |
| | | String[] names = file.list(); |
| | | if (names != null) { |
| | | String[] completNames = new String[names.length]; |
| | | for (int i = 0; i < names.length; i++) { |
| | | completNames[i] = path + names[i]; |
| | | } |
| | | listFileName.addAll(Arrays.asList(completNames)); |
| | | } |
| | | for (File a : files) { |
| | | // 如果文件夹下有子文件夹,获取子文件夹下的所有文件全路径。 |
| | | if (a.isDirectory()) { |
| | | getAllFileName(a.getAbsolutePath() + "\\", listFileName); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 读取文件内容,作为字符串返回 |
| | | */ |
| | | public static String readFileAsString(String filePath) throws IOException { |
| | | File file = new File(filePath); |
| | | if (!file.exists()) { |
| | | throw new FileNotFoundException(filePath); |
| | | } |
| | | |
| | | if (file.length() > 1024 * 1024 * 1024) { |
| | | throw new IOException("File is too large"); |
| | | } |
| | | |
| | | StringBuilder sb = new StringBuilder((int) (file.length())); |
| | | // 创建字节输入流 |
| | | FileInputStream fis = new FileInputStream(filePath); |
| | | // 创建一个长度为10240的Buffer |
| | | byte[] bbuf = new byte[10240]; |
| | | // 用于保存实际读取的字节数 |
| | | int hasRead = 0; |
| | | while ( (hasRead = fis.read(bbuf)) > 0 ) { |
| | | sb.append(new String(bbuf, 0, hasRead)); |
| | | } |
| | | fis.close(); |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 根据文件路径读取byte[] 数组 |
| | | */ |
| | | public static byte[] readFileByBytes(String filePath) throws IOException { |
| | | File file = new File(filePath); |
| | | if (!file.exists()) { |
| | | throw new FileNotFoundException(filePath); |
| | | } else { |
| | | ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); |
| | | BufferedInputStream in = null; |
| | | |
| | | try { |
| | | in = new BufferedInputStream(new FileInputStream(file)); |
| | | short bufSize = 1024; |
| | | byte[] buffer = new byte[bufSize]; |
| | | int len1; |
| | | while (-1 != (len1 = in.read(buffer, 0, bufSize))) { |
| | | bos.write(buffer, 0, len1); |
| | | } |
| | | |
| | | byte[] var7 = bos.toByteArray(); |
| | | return var7; |
| | | } finally { |
| | | try { |
| | | if (in != null) { |
| | | in.close(); |
| | | } |
| | | } catch (IOException var14) { |
| | | var14.printStackTrace(); |
| | | } |
| | | |
| | | bos.close(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 2020-06-29 |
| | | * cjh |
| | | * 图片格式判断 |
| | | * */ |
| | | public static boolean imageFormatJudge(MultipartFile firs) { |
| | | String imageName = firs.getOriginalFilename(); |
| | | //截取格式 |
| | | String suffix =imageName.substring(imageName.lastIndexOf(".") + 1); |
| | | //格式字母转小写 |
| | | suffix = suffix.toLowerCase(); |
| | | //进行判断 |
| | | if(suffix.equals("png")) { |
| | | return true; |
| | | }else if(suffix.equals("jpg")){ |
| | | return true; |
| | | }else if(suffix.equals("jpeg")){ |
| | | return true; |
| | | }else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 2020-06-29 |
| | | * cjh |
| | | * 图片格式判断 |
| | | * */ |
| | | public static boolean imageFormatJudge(File firs) { |
| | | String imageName = firs.getName(); |
| | | //截取格式 |
| | | String suffix =imageName.substring(imageName.lastIndexOf(".") + 1); |
| | | //格式字母转小写 |
| | | suffix = suffix.toLowerCase(); |
| | | //进行判断 |
| | | if(suffix.equals("png")) { |
| | | return true; |
| | | }else if(suffix.equals("jpg")){ |
| | | return true; |
| | | }else if(suffix.equals("jpeg")){ |
| | | return true; |
| | | }else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /**视频上传的方法 |
| | | * 保存到服务器里面的 |
| | | * @param platformIconFile 视频文件 |
| | | * @param unifiedFolder NG指向的前端文件夹(统一文件夹),如:user/local/images/ |
| | | * @param saveFolder 保存到的文件夹,如:/bananer/ |
| | | * @param autoDateFolder 是否生成日期文件夹 |
| | | * @return 图片路径 |
| | | * 2020-06-29 ChenJiaHe |
| | | */ |
| | | public static String videoFileUpload(MultipartFile platformIconFile,String unifiedFolder,String saveFolder |
| | | ,boolean autoDateFolder) { |
| | | String fileName = ""; |
| | | try { |
| | | if(platformIconFile == null) { |
| | | throw new TipsException("请上传视频文件!"); |
| | | } |
| | | if(!getMimeType(platformIconFile.getOriginalFilename())){ |
| | | throw new TipsException("请上传视频格式的文件!"); |
| | | } |
| | | |
| | | //设置图片大小 |
| | | // String.format("%.1f",platformIconFile.getSize()/1024.0); |
| | | if(autoDateFolder){ |
| | | if(saveFolder.endsWith("/")){ |
| | | saveFolder = saveFolder+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | }else{ |
| | | saveFolder = saveFolder+"/"+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | } |
| | | } |
| | | fileName = dateFormat(new Date(),"yyyyMMddHHmmssSSS"); |
| | | if(unifiedFolder.endsWith("/")){ |
| | | if(saveFolder.startsWith("/")){ |
| | | saveFolder = saveFolder.replaceFirst("/",""); |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+saveFolder; |
| | | } |
| | | }else{ |
| | | if(saveFolder.startsWith("/")){ |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+"/"+saveFolder; |
| | | } |
| | | } |
| | | fileName = saveFolder+fileUp(platformIconFile,unifiedFolder,fileName); |
| | | } catch (RuntimeException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return fileName; |
| | | } |
| | | |
| | | /**图片上传的方法 |
| | | * 保存到服务器里面的 |
| | | * @param platformIconFile 图片文件 |
| | | * @param unifiedFolder NG指向的前端文件夹(统一文件夹),如:user/local/images/ |
| | | * @param saveFolder 保存到的文件夹,如:/bananer/ |
| | | * @param autoDateFolder 是否生成日期文件夹 |
| | | * @return 图片路径 |
| | | * 2020-06-29 ChenJiaHe |
| | | */ |
| | | public static String handleFileUpload(File platformIconFile,String unifiedFolder,String saveFolder |
| | | ,boolean autoDateFolder) { |
| | | String fileName = ""; |
| | | try { |
| | | if(platformIconFile == null) { |
| | | throw new TipsException("请上传图片!"); |
| | | } |
| | | if(!imageFormatJudge(platformIconFile)) { |
| | | throw new TipsException("请上传png、jpg和jpeg格式的图片!"); |
| | | } |
| | | |
| | | //设置图片大小 |
| | | // String.format("%.1f",platformIconFile.getSize()/1024.0); |
| | | if(autoDateFolder){ |
| | | if(saveFolder.endsWith("/")){ |
| | | saveFolder = saveFolder+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | }else{ |
| | | saveFolder = saveFolder+"/"+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | } |
| | | } |
| | | fileName = dateFormat(new Date(),"yyyyMMddHHmmssSSS"); |
| | | if(unifiedFolder.endsWith("/")){ |
| | | if(saveFolder.startsWith("/")){ |
| | | saveFolder = saveFolder.replaceFirst("/",""); |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+saveFolder; |
| | | } |
| | | }else{ |
| | | if(saveFolder.startsWith("/")){ |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+"/"+saveFolder; |
| | | } |
| | | } |
| | | fileName = saveFolder+fileUp(platformIconFile,unifiedFolder,fileName); |
| | | } catch (RuntimeException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return fileName; |
| | | } |
| | | |
| | | /**图片上传的方法 |
| | | * 保存到服务器里面的 |
| | | * @param platformIconFile 图片文件 |
| | | * @param unifiedFolder NG指向的前端文件夹(统一文件夹),如:user/local/images/ |
| | | * @param saveFolder 保存到的文件夹,如:/bananer/ |
| | | * @param autoDateFolder 是否生成日期文件夹 |
| | | * @return 图片路径 |
| | | * 2020-06-29 ChenJiaHe |
| | | */ |
| | | public static String handleFileUpload(MultipartFile platformIconFile,String unifiedFolder,String saveFolder |
| | | ,boolean autoDateFolder) { |
| | | String fileName = ""; |
| | | try { |
| | | if(platformIconFile == null) { |
| | | throw new TipsException("请上传图片!"); |
| | | } |
| | | if(!imageFormatJudge(platformIconFile)) { |
| | | throw new TipsException("请上传png、jpg和jpeg格式的图片!"); |
| | | } |
| | | |
| | | //设置图片大小 |
| | | // String.format("%.1f",platformIconFile.getSize()/1024.0); |
| | | if(autoDateFolder){ |
| | | if(saveFolder.endsWith("/")){ |
| | | saveFolder = saveFolder+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | }else{ |
| | | saveFolder = saveFolder+"/"+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | } |
| | | } |
| | | fileName = dateFormat(new Date(),"yyyyMMddHHmmssSSS"); |
| | | if(unifiedFolder.endsWith("/")){ |
| | | if(saveFolder.startsWith("/")){ |
| | | saveFolder = saveFolder.replaceFirst("/",""); |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+saveFolder; |
| | | } |
| | | }else{ |
| | | if(saveFolder.startsWith("/")){ |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+"/"+saveFolder; |
| | | } |
| | | } |
| | | fileName = saveFolder+fileUp(platformIconFile,unifiedFolder,fileName); |
| | | } catch (RuntimeException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return fileName; |
| | | } |
| | | |
| | | /** |
| | | * 音频上传 |
| | | * @param platformIconFile |
| | | * @param unifiedFolder |
| | | * @param saveFolder |
| | | * @param autoDateFolder |
| | | * @return |
| | | */ |
| | | public static String handleAudioUpload(MultipartFile platformIconFile,String unifiedFolder,String saveFolder |
| | | ,boolean autoDateFolder) { |
| | | String fileName = ""; |
| | | try { |
| | | if(platformIconFile == null) { |
| | | throw new TipsException("请上传音频!"); |
| | | } |
| | | |
| | | if(autoDateFolder){ |
| | | if(saveFolder.endsWith("/")){ |
| | | saveFolder = saveFolder+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | }else{ |
| | | saveFolder = saveFolder+"/"+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | } |
| | | } |
| | | |
| | | fileName = dateFormat(new Date(),"yyyyMMddHHmmssSSS"); |
| | | if(unifiedFolder.endsWith("/")){ |
| | | if(saveFolder.startsWith("/")){ |
| | | saveFolder = saveFolder.replaceFirst("/",""); |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+saveFolder; |
| | | } |
| | | }else{ |
| | | if(saveFolder.startsWith("/")){ |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+"/"+saveFolder; |
| | | } |
| | | } |
| | | fileName = saveFolder+fileUp(platformIconFile,unifiedFolder,fileName); |
| | | } catch (RuntimeException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return fileName; |
| | | } |
| | | |
| | | /** |
| | | * 文件上传 |
| | | * @param platformIconFile |
| | | * @param unifiedFolder |
| | | * @param saveFolder |
| | | * @param autoDateFolder |
| | | * @return |
| | | */ |
| | | public static String handleOtherFileUpload(MultipartFile platformIconFile,String unifiedFolder,String saveFolder |
| | | ,boolean autoDateFolder) { |
| | | String fileName = ""; |
| | | try { |
| | | if(platformIconFile == null) { |
| | | throw new TipsException("请上传文件!"); |
| | | } |
| | | |
| | | if(autoDateFolder){ |
| | | if(saveFolder.endsWith("/")){ |
| | | saveFolder = saveFolder+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | }else{ |
| | | saveFolder = saveFolder+"/"+dateFormat(new Date(),"yyyyMM")+"/"; |
| | | } |
| | | } |
| | | |
| | | fileName = dateFormat(new Date(),"yyyyMMddHHmmssSSS"); |
| | | if(unifiedFolder.endsWith("/")){ |
| | | if(saveFolder.startsWith("/")){ |
| | | saveFolder = saveFolder.replaceFirst("/",""); |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+saveFolder; |
| | | } |
| | | }else{ |
| | | if(saveFolder.startsWith("/")){ |
| | | unifiedFolder = unifiedFolder + saveFolder; |
| | | }else{ |
| | | unifiedFolder = unifiedFolder+"/"+saveFolder; |
| | | } |
| | | } |
| | | fileName = saveFolder+fileUp(platformIconFile,unifiedFolder,fileName); |
| | | } catch (RuntimeException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return fileName; |
| | | } |
| | | |
| | | /** |
| | | * 2020-06-29 ChenJiaHe |
| | | * @param file //文件对象 |
| | | * @param filePath //上传路径 |
| | | * @param fileName //文件名 |
| | | * @return 文件名 |
| | | */ |
| | | public static String fileUp(MultipartFile file, String filePath, String fileName){ |
| | | String extName = ""; // 扩展名格式: |
| | | try { |
| | | if (file.getOriginalFilename().lastIndexOf(".") >= 0){ |
| | | extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); |
| | | } |
| | | copyFile(file.getInputStream(), filePath, fileName+extName).replaceAll("-", ""); |
| | | } catch (IOException e) { |
| | | System.out.println(e); |
| | | } |
| | | return fileName+extName; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 2020-06-29 ChenJiaHe |
| | | * @param file //文件对象 |
| | | * @param filePath //上传路径 |
| | | * @param fileName //文件名 |
| | | * @return 文件名 |
| | | */ |
| | | public static String fileUp(File file, String filePath, String fileName){ |
| | | String extName = ""; // 扩展名格式: |
| | | try { |
| | | if (file.getName().lastIndexOf(".") >= 0){ |
| | | extName = file.getName().substring(file.getName().lastIndexOf(".")); |
| | | } |
| | | copyFile(file, filePath, fileName+extName).replaceAll("-", ""); |
| | | } catch (IOException e) { |
| | | System.out.println(e); |
| | | } |
| | | return fileName+extName; |
| | | } |
| | | |
| | | /** |
| | | * 写文件到当前目录的upload目录中 |
| | | * |
| | | * @param in |
| | | * @param fileName |
| | | * @throws IOException |
| | | */ |
| | | private static String copyFile(InputStream in, String dir, String realName)throws IOException { |
| | | File file = new File(dir, realName); |
| | | file.setWritable(true); |
| | | if (!file.exists()) { |
| | | if (!file.getParentFile().exists()) { |
| | | file.getParentFile().mkdirs(); |
| | | } |
| | | file.createNewFile(); |
| | | } |
| | | org.apache.commons.io.FileUtils.copyInputStreamToFile(in, file); |
| | | return realName; |
| | | } |
| | | |
| | | /** |
| | | * 写文件到当前目录的upload目录中 |
| | | * |
| | | * @param in |
| | | * @param fileName |
| | | * @throws IOException |
| | | */ |
| | | private static String copyFile(File fileIn, String dir, String realName)throws IOException { |
| | | File file = new File(dir, realName); |
| | | file.setWritable(true); |
| | | if (!file.exists()) { |
| | | if (!file.getParentFile().exists()) { |
| | | file.getParentFile().mkdirs(); |
| | | } |
| | | file.createNewFile(); |
| | | } |
| | | org.apache.commons.io.FileUtils.copyFile(fileIn,file); |
| | | return realName; |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param date 时间 |
| | | * @param format 时间格式 |
| | | * @return 返回的时间格式字符串 |
| | | */ |
| | | public static String dateFormat(Date date,String format) { |
| | | SimpleDateFormat df = new SimpleDateFormat(format);//设置日期格式 |
| | | return df.format(date); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @param stream 文件流 |
| | | * @param saveUrl 保存到的文件夹 |
| | | * @param fileName 文件图片 |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static File inputStreamToFile(InputStream stream,String saveUrl,String fileName) throws IOException { |
| | | if(saveUrl.endsWith("/")){ |
| | | saveUrl = saveUrl + fileName; |
| | | }else{ |
| | | saveUrl = saveUrl +"/"+ fileName; |
| | | } |
| | | File targetFile = new File(saveUrl); |
| | | org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, targetFile); |
| | | return targetFile; |
| | | } |
| | | |
| | | /**判断是不是视频文件 |
| | | * @param fileName 文件名称 |
| | | * @return boolean true是视频文件 |
| | | */ |
| | | public static boolean getMimeType(String fileName) { |
| | | boolean b = false; |
| | | FileNameMap fileNameMap = URLConnection.getFileNameMap(); |
| | | String type = fileNameMap.getContentTypeFor(fileName); |
| | | //是视频type是为空的 |
| | | if(StringUtils.isEmpty(type)) { |
| | | b = true; |
| | | } |
| | | return b; |
| | | } |
| | | |
| | | /** |
| | | * 判断是否为视频 |
| | | * @param fileName |
| | | * @return |
| | | */ |
| | | public static String isVideo(String fileName) { |
| | | FileNameMap fileNameMap = URLConnection.getFileNameMap(); |
| | | String type = fileNameMap.getContentTypeFor(fileName); |
| | | return type; |
| | | } |
| | | |
| | | public static File httpUrlFile(String netUrl) throws IOException { |
| | | File file = File.createTempFile("temp123", ".xls"); |
| | | InputStream inStream = null; |
| | | FileOutputStream os = null; |
| | | |
| | | try { |
| | | file = File.createTempFile("net_url", ".jpg"); |
| | | URL urlfile = new URL(netUrl); |
| | | inStream = urlfile.openStream(); |
| | | os = new FileOutputStream(file); |
| | | |
| | | byte[] buffer = new byte[8192]; |
| | | |
| | | int bytesRead; |
| | | while((bytesRead = inStream.read(buffer, 0, 8192)) != -1) { |
| | | os.write(buffer, 0, bytesRead); |
| | | } |
| | | } catch (Exception var15) { |
| | | var15.printStackTrace(); |
| | | } finally { |
| | | try { |
| | | if (null != os) { |
| | | os.close(); |
| | | } |
| | | |
| | | if (null != inStream) { |
| | | inStream.close(); |
| | | } |
| | | } catch (Exception var14) { |
| | | var14.printStackTrace(); |
| | | } |
| | | |
| | | } |
| | | |
| | | return file; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | /* |
| | | * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. |
| | | */ |
| | | package com.hx.util; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.google.gson.GsonBuilder; |
| | | import com.google.gson.JsonParseException; |
| | | |
| | | import java.lang.reflect.Type; |
| | | |
| | | /** |
| | | * Json工具类. |
| | | */ |
| | | public class GsonUtils { |
| | | private static Gson gson = new GsonBuilder().create(); |
| | | |
| | | public static String toJson(Object value) { |
| | | return gson.toJson(value); |
| | | } |
| | | |
| | | public static <T> T fromJson(String json, Class<T> classOfT) throws JsonParseException { |
| | | return gson.fromJson(json, classOfT); |
| | | } |
| | | |
| | | public static <T> T fromJson(String json, Type typeOfT) throws JsonParseException { |
| | | return (T) gson.fromJson(json, typeOfT); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.apache.commons.io.IOUtils; |
| | | |
| | | import java.io.OutputStream; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * http 工具类 |
| | | */ |
| | | public class HttpMethodUtil { |
| | | |
| | | /** 请求http协议 获取信息工具 |
| | | * @param url 请求链接 |
| | | * @param data 请求数据(body) |
| | | * @param keyValues form表单数据 key参数名称,value参数值 |
| | | * @param header 请求头 |
| | | * @param requestMethod 请求头方法,默认POST |
| | | * @return |
| | | */ |
| | | public static String HttpURLUtilJson(String url, String data,Map<String,Object> keyValues,Map<String,String> header,String requestMethod) { |
| | | HttpURLConnection con = null; |
| | | URL u = null; |
| | | String wxMsgXml = null; |
| | | try { |
| | | StringBuilder dataP = new StringBuilder(); |
| | | if (keyValues != null && !keyValues.isEmpty()) { |
| | | for (Map.Entry<String, Object> entry : keyValues.entrySet()) { |
| | | dataP.append((String)entry.getKey()).append("="); |
| | | dataP.append(entry.getValue()); |
| | | dataP.append("&"); |
| | | } |
| | | System.out.println("dataP:"+dataP.toString()); |
| | | dataP.deleteCharAt(dataP.length() - 1); |
| | | url = url+"?"+dataP; |
| | | } |
| | | |
| | | if(StringUtils.isEmpty(requestMethod)){ |
| | | requestMethod = "POST"; |
| | | } |
| | | u = new URL(url); |
| | | con = (HttpURLConnection) u.openConnection(); |
| | | con.setRequestMethod(requestMethod); |
| | | con.setDoOutput(true); |
| | | con.setDoInput(true); |
| | | con.setUseCaches(false); |
| | | con.setReadTimeout(300000); |
| | | con.setRequestProperty("Charset", "UTF-8"); |
| | | con.setRequestProperty("Content-Type", "application/json"); |
| | | if(header != null){ |
| | | for (Map.Entry<String, String> entry : header.entrySet()) { |
| | | con.setRequestProperty(entry.getKey(),entry.getValue()); |
| | | } |
| | | } |
| | | |
| | | if (data != null) { |
| | | OutputStream os = con.getOutputStream(); |
| | | os.write(data.getBytes("utf-8")); |
| | | } |
| | | |
| | | if(HttpURLConnection.HTTP_OK != con.getResponseCode() && HttpURLConnection.HTTP_CREATED != con.getResponseCode()){ |
| | | throw new RuntimeException("请求url失败:"+con.getResponseCode()); |
| | | } |
| | | // 读取返回内容 |
| | | wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8"); |
| | | // //System.out.println("HttpURLUtil:"+wxMsgXml); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | if (con != null) { |
| | | con.disconnect(); |
| | | } |
| | | } |
| | | return wxMsgXml; |
| | | } |
| | | |
| | | /** |
| | | * 请求http协议 获取信息工具 |
| | | * @param url 请求链接 |
| | | * @param data 请求数据(body) |
| | | * @param keyValues form表单数据 key参数名称,value参数值 |
| | | * @param header 请求头 |
| | | * @param requestMethod 请求头方法,默认POST |
| | | * @return |
| | | */ |
| | | public static String request(String url, String data,Map<String,Object> keyValues,Map<String,String> header,String requestMethod, String contentType) { |
| | | HttpURLConnection con = null; |
| | | URL u = null; |
| | | String wxMsgXml = null; |
| | | try { |
| | | StringBuilder dataP = new StringBuilder(); |
| | | if (keyValues != null && !keyValues.isEmpty()) { |
| | | for (Map.Entry<String, Object> entry : keyValues.entrySet()) { |
| | | dataP.append((String)entry.getKey()).append("="); |
| | | dataP.append(entry.getValue()); |
| | | dataP.append("&"); |
| | | } |
| | | System.out.println("dataP:"+dataP.toString()); |
| | | dataP.deleteCharAt(dataP.length() - 1); |
| | | url = url+"?"+dataP; |
| | | } |
| | | |
| | | if(StringUtils.isEmpty(requestMethod)){ |
| | | requestMethod = "POST"; |
| | | } |
| | | |
| | | if(StringUtils.isEmpty(contentType)){ |
| | | contentType = "application/json"; |
| | | } |
| | | |
| | | u = new URL(url); |
| | | con = (HttpURLConnection) u.openConnection(); |
| | | con.setRequestMethod(requestMethod); |
| | | con.setDoOutput(true); |
| | | con.setDoInput(true); |
| | | con.setUseCaches(false); |
| | | con.setReadTimeout(300000); |
| | | con.setRequestProperty("Charset", "UTF-8"); |
| | | con.setRequestProperty("Content-Type", contentType); |
| | | if(header != null){ |
| | | for (Map.Entry<String, String> entry : header.entrySet()) { |
| | | con.setRequestProperty(entry.getKey(),entry.getValue()); |
| | | } |
| | | } |
| | | |
| | | if (data != null) { |
| | | OutputStream os = con.getOutputStream(); |
| | | os.write(data.getBytes("utf-8")); |
| | | } |
| | | |
| | | if(HttpURLConnection.HTTP_OK != con.getResponseCode() && HttpURLConnection.HTTP_CREATED != con.getResponseCode()){ |
| | | throw new RuntimeException("请求url失败:"+con.getResponseCode()); |
| | | } |
| | | // 读取返回内容 |
| | | wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8"); |
| | | // //System.out.println("HttpURLUtil:"+wxMsgXml); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | if (con != null) { |
| | | con.disconnect(); |
| | | } |
| | | } |
| | | return wxMsgXml; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | public class HttpResponse { |
| | | private int code; |
| | | private String content; |
| | | |
| | | public HttpResponse(int status, String content) { |
| | | this.code = status; |
| | | this.content = content; |
| | | } |
| | | |
| | | public int getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(int code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getContent() { |
| | | return content; |
| | | } |
| | | |
| | | public void setContent(String content) { |
| | | this.content = content; |
| | | } |
| | | |
| | | public String toString(){ |
| | | return new StringBuilder("[ code = ").append(code) |
| | | .append(" , content = ").append(content).append(" ]").toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.hx.util; |
| | | |
| | | import org.apache.commons.io.IOUtils; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.BufferedReader; |
| | | import java.io.IOException; |
| | | import java.util.Enumeration; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** HttpServletRequestUtil 获取请求中的body |
| | | * @author wangrenhuang |
| | | * @Date 2021-10-19 |
| | | */ |
| | | public class HttpServletRequestUtil { |
| | | |
| | | /** |
| | | * 获取bady |
| | | * */ |
| | | public static String getBody(HttpServletRequest request) { |
| | | String wxMsgXml = null; |
| | | if(request == null){ |
| | | return wxMsgXml; |
| | | } |
| | | try{ |
| | | wxMsgXml = IOUtils.toString(request.getInputStream(), |
| | | "utf-8"); |
| | | return wxMsgXml; |
| | | }catch (Exception e){ |
| | | wxMsgXml = null; |
| | | } |
| | | return wxMsgXml; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * |
| | | * 获取请求头 |
| | | * */ |
| | | public static Map<String,String> getHeader(HttpServletRequest request) { |
| | | Enumeration<String> enumeration = request.getHeaderNames(); |
| | | Map<String,String> map = new HashMap<>(16); |
| | | StringBuffer headers = new StringBuffer(); |
| | | while (enumeration.hasMoreElements()) { |
| | | String name = enumeration.nextElement(); |
| | | String value = request.getHeader(name); |
| | | map.put(name,value); |
| | | } |
| | | |
| | | return map; |
| | | } |
| | | } |
hx_common/src/main/java/com/hx/util/HttpUtil.java
hx_common/src/main/java/com/hx/util/IPUtils.java
hx_common/src/main/java/com/hx/util/ImageBase64Util.java
hx_common/src/main/java/com/hx/util/ImagesAddDomain.java
hx_common/src/main/java/com/hx/util/JwtConstant.java
hx_common/src/main/java/com/hx/util/JwtTool.java
hx_common/src/main/java/com/hx/util/MD5.java
hx_common/src/main/java/com/hx/util/MD5Util.java
hx_common/src/main/java/com/hx/util/MapUtil.java
hx_common/src/main/java/com/hx/util/MultipartFileUtil.java
hx_common/src/main/java/com/hx/util/MyRedisTemplate.java
hx_common/src/main/java/com/hx/util/NumberUtil.java
hx_common/src/main/java/com/hx/util/OBSUtil.java
hx_common/src/main/java/com/hx/util/OSSUtil.java
hx_common/src/main/java/com/hx/util/QRCodeUtil.java
hx_common/src/main/java/com/hx/util/RegValidatorUtil.java
hx_common/src/main/java/com/hx/util/RequestMethod.java
hx_common/src/main/java/com/hx/util/SerializeUtil.java
hx_common/src/main/java/com/hx/util/SimpleEncrypt.java
hx_common/src/main/java/com/hx/util/SimpleTool.java
hx_common/src/main/java/com/hx/util/StreamUtils.java
hx_common/src/main/java/com/hx/util/StringUtils.java
hx_common/src/main/java/com/hx/util/TempltUtil.java
hx_common/src/main/java/com/hx/util/TengXunMapUtil.java
hx_common/src/main/java/com/hx/util/ThreadPoolUtils.java
hx_common/src/main/java/com/hx/util/WebUtil.java
hx_common/src/main/java/com/hx/util/XmlUtil.java
hx_common/src/main/java/com/hx/util/code/NumberTool.java
hx_common/src/main/java/com/hx/util/corp/CorpMpUtil.java
hx_common/src/main/java/com/hx/util/corp/entity/AppLetInfo.java
hx_common/src/main/java/com/hx/util/corp/entity/OpenIdAUserId.java
hx_common/src/main/java/com/hx/util/corp/entity/WeiXinInfo.java
hx_common/src/main/java/com/hx/util/gaode/AddressCode.java
hx_common/src/main/java/com/hx/util/gaode/GaoDeMapUtil.java
hx_common/src/main/java/com/hx/util/mysql/aes/MysqlHexAesTool.java
hx_common/src/main/java/com/hx/util/rsa/Base64.java
hx_common/src/main/java/com/hx/util/rsa/RSASignature.java
hx_common/src/main/java/com/hx/util/rsa/RSAUtil.java
hx_common/src/main/java/com/hx/util/thread/ExecutorServiceTool.java
hx_common/src/main/java/com/hx/wx/gzh/WxGzhUtil.java
hx_common/src/main/java/com/hz/util/http/HttpHzUtil.java
hx_common/src/main/java/com/hz/util/http/dto/HttpHzResponse.java
hx_common/src/main/java/com/qq/weixin/mp/aes/AesException.java
hx_common/src/main/java/com/qq/weixin/mp/aes/ByteGroup.java
hx_common/src/main/java/com/qq/weixin/mp/aes/PKCS7Encoder.java
hx_common/src/main/java/com/qq/weixin/mp/aes/SHA1.java
hx_common/src/main/java/com/qq/weixin/mp/aes/WXBizMsgCrypt.java
hx_common/src/main/java/com/qq/weixin/mp/aes/XMLParse.java
pom.xml |