修复定时任务执行失败后还继续执行的bug,优化Redis发生异常时,程序正常执行,优化Excel大数据导出,优化QueryHelp,其他细节优化

pull/182/head
dqjdda 2019-09-26 16:57:39 +08:00
parent a481b16bcf
commit f9bb8cf241
25 changed files with 137 additions and 87 deletions

View File

@ -3,14 +3,14 @@ package me.zhengjie.redis;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -74,8 +74,8 @@ public class RedisConfig extends CachingConfigurerSupport {
}
/**
* key
* 使 @Cacheable(keyGenerator="keyGenerator")
* key使
* 使 @Cacheable
* @return
*/
@Bean
@ -91,4 +91,34 @@ public class RedisConfig extends CachingConfigurerSupport {
return sb.toString();
};
}
@Bean
@Override
public CacheErrorHandler errorHandler() {
// 异常处理当Redis发生异常时打印日志但是程序正常走
log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
@Override
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
log.error("Redis occur handleCacheGetErrorkey -> [{}]", key, e);
}
@Override
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
log.error("Redis occur handleCachePutErrorkey -> [{}]value -> [{}]", key, value, e);
}
@Override
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
log.error("Redis occur handleCacheEvictErrorkey -> [{}]", key, e);
}
@Override
public void handleCacheClearError(RuntimeException e, Cache cache) {
log.error("Redis occur handleCacheClearError", e);
}
};
return cacheErrorHandler;
}
}

View File

@ -3,6 +3,7 @@ package me.zhengjie.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import me.zhengjie.exception.BadRequestException;
@ -197,24 +198,20 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
* @return
* @throws Exception
*/
public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response){
// 通过工具类创建writer
ExcelWriter writer = ExcelUtil.getWriter();
public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response) throws IOException {
String tempPath =System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx";
File file = new File(tempPath);
BigExcelWriter writer= ExcelUtil.getBigWriter(file);
// 一次性写出内容,使用默认样式,强制输出标题
writer.write(list, true);
//response为HttpServletResponse对象
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//test.xls是弹出下载对话框的文件名不能为中文中文请自行编码
response.setHeader("Content-Disposition","attachment;filename=file.xls");
ServletOutputStream out= null;
try {
out = response.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
response.setHeader("Content-Disposition","attachment;filename=file.xlsx");
ServletOutputStream out=response.getOutputStream();
// 终止后删除临时文件
file.deleteOnExit();
writer.flush(out, true);
// 关闭writer释放内存
writer.close();
//此处记得关闭输出Servlet流
IoUtil.close(out);
}

View File

@ -1,10 +1,7 @@
package me.zhengjie.utils;
import org.springframework.data.domain.Page;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
*
@ -39,11 +36,9 @@ public class PageUtil extends cn.hutool.core.util.PageUtil {
* @return
*/
public static Map toPage(Page page) {
Map map = new HashMap();
Map<String,Object> map = new LinkedHashMap<>(2);
map.put("content",page.getContent());
map.put("totalElements",page.getTotalElements());
return map;
}
@ -53,8 +48,7 @@ public class PageUtil extends cn.hutool.core.util.PageUtil {
* @return
*/
public static Map toPage(Object object, Object totalElements) {
Map map = new HashMap();
Map<String,Object> map = new LinkedHashMap<>(2);
map.put("content",object);
map.put("totalElements",totalElements);

View File

@ -41,7 +41,7 @@ public class QueryHelp {
String attributeName = isBlank(propName) ? field.getName() : propName;
Class<?> fieldType = field.getType();
Object val = field.get(query);
if (ObjectUtil.isNull(val)) {
if (ObjectUtil.isNull(val) || "".equals(val)) {
continue;
}
Join join = null;
@ -58,13 +58,24 @@ public class QueryHelp {
continue;
}
if (ObjectUtil.isNotEmpty(joinName)) {
switch (q.join()) {
case LEFT:
join = root.join(joinName, JoinType.LEFT);
break;
case RIGHT:
join = root.join(joinName, JoinType.RIGHT);
break;
String[] joinNames = joinName.split(">");
for (String name : joinNames) {
switch (q.join()) {
case LEFT:
if(ObjectUtil.isNotEmpty(join)){
join = join.join(name, JoinType.LEFT);
} else {
join = root.join(name, JoinType.LEFT);
}
break;
case RIGHT:
if(ObjectUtil.isNotEmpty(join)){
join = join.join(name, JoinType.RIGHT);
} else {
join = root.join(name, JoinType.RIGHT);
}
break;
}
}
}
switch (q.type()) {

View File

@ -21,7 +21,7 @@ public interface QuartzJobService {
* @param pageable
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(JobQueryCriteria criteria, Pageable pageable);
/**

View File

@ -1,6 +1,7 @@
package me.zhengjie.modules.quartz.task;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.exception.BadRequestException;
import org.springframework.stereotype.Component;
/**

View File

@ -25,6 +25,7 @@ public class ExecutionJob extends QuartzJobBean {
private Logger logger = LoggerFactory.getLogger(this.getClass());
// 建议自定义线程池实现方式,该处仅供参考
private ExecutorService executorService = Executors.newSingleThreadExecutor();
@Override
@ -61,8 +62,7 @@ public class ExecutionJob extends QuartzJobBean {
// 任务状态 0成功 1失败
log.setIsSuccess(false);
log.setExceptionDetail(ThrowableUtil.getStackTrace(e));
//出错就暂停任务
quartzManage.pauseJob(quartzJob);
quartzJob.setIsPause(false);
//更新状态
quartzJobService.updateIsPause(quartzJob);
} finally {

View File

@ -1,17 +1,19 @@
package me.zhengjie.modules.quartz.utils;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.utils.SpringContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
/**
*
* @author
*/
@Slf4j
public class QuartzRunnable implements Runnable {
public class QuartzRunnable implements Callable {
private Object target;
private Method method;
@ -30,17 +32,13 @@ public class QuartzRunnable implements Runnable {
}
@Override
public void run() {
try {
ReflectionUtils.makeAccessible(method);
if (StringUtils.isNotBlank(params)) {
method.invoke(target, params);
} else {
method.invoke(target);
}
} catch (Exception e) {
log.error("定时任务执行失败",e);
public Object call() throws Exception {
ReflectionUtils.makeAccessible(method);
if (StringUtils.isNotBlank(params)) {
method.invoke(target, params);
} else {
method.invoke(target);
}
return null;
}
}

View File

@ -27,6 +27,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@ -59,7 +60,7 @@ public class UserController {
@Log("导出用户数据")
@GetMapping(value = "/users/download")
@PreAuthorize("hasAnyRole('ADMIN','USER_ALL','USER_SELECT')")
public void update(HttpServletResponse response, UserQueryCriteria criteria){
public void update(HttpServletResponse response, UserQueryCriteria criteria) throws IOException {
userService.download(userService.queryAll(criteria), response);
}

View File

@ -22,7 +22,7 @@ public interface DeptService {
* @param criteria
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
List<DeptDTO> queryAll(DeptQueryCriteria criteria);
/**
@ -60,7 +60,7 @@ public interface DeptService {
* @param deptDTOS
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object buildTree(List<DeptDTO> deptDTOS);
/**
@ -68,7 +68,7 @@ public interface DeptService {
* @param pid
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
List<Dept> findByPid(long pid);
Set<Dept> findByRoleIds(Long id);

View File

@ -47,6 +47,6 @@ public interface DictDetailService {
@CacheEvict(allEntries = true)
void delete(Long id);
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Map queryAll(DictDetailQueryCriteria criteria, Pageable pageable);
}

View File

@ -21,7 +21,7 @@ public interface DictService {
* @param pageable
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(DictQueryCriteria dict, Pageable pageable);
/**

View File

@ -23,7 +23,7 @@ public interface MenuService {
* @param criteria
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
List<MenuDTO> queryAll(MenuQueryCriteria criteria);
/**

View File

@ -67,7 +67,7 @@ public interface PermissionService {
* @param permissionDTOS
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object buildTree(List<PermissionDTO> permissionDTOS);
/**
@ -75,7 +75,7 @@ public interface PermissionService {
* @param criteria
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
List<PermissionDTO> queryAll(PermissionQueryCriteria criteria);
Set<Permission> getDeletePermission(List<Permission> permissions, Set<Permission> permissionSet);

View File

@ -58,7 +58,7 @@ public interface RoleService {
@Cacheable(key = "'findByUsers_Id:' + #p0")
List<RoleSmallDTO> findByUsers_Id(Long id);
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Integer findByRoles(Set<Role> roles);
/**
@ -85,7 +85,7 @@ public interface RoleService {
* @param pageable
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(Pageable pageable);
/**
@ -94,7 +94,7 @@ public interface RoleService {
* @param criteria
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(RoleQueryCriteria criteria, Pageable pageable);
/**
@ -102,7 +102,7 @@ public interface RoleService {
* @param criteria
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
List<RoleDTO> queryAll(RoleQueryCriteria criteria);
@CacheEvict(allEntries = true)

View File

@ -11,6 +11,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
@ -81,11 +82,11 @@ public interface UserService {
@CacheEvict(allEntries = true)
void updateEmail(String username, String email);
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(UserQueryCriteria criteria, Pageable pageable);
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
List<UserDTO> queryAll(UserQueryCriteria criteria);
void download(List<UserDTO> queryAll, HttpServletResponse response);
void download(List<UserDTO> queryAll, HttpServletResponse response) throws IOException;
}

View File

@ -180,7 +180,7 @@ public class UserServiceImpl implements UserService {
}
@Override
public void download(List<UserDTO> queryAll, HttpServletResponse response) {
public void download(List<UserDTO> queryAll, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (UserDTO userDTO : queryAll) {
List roles = userDTO.getRoles().stream().map(RoleSmallDTO::getName).collect(Collectors.toList());

View File

@ -1,2 +1,4 @@
# If you use SLF4J. First, you need to tell log4jdbc-log4j2 that you want to use the SLF4J logger
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.auto.load.popular.drivers=false
log4jdbc.drivers=com.mysql.cj.jdbc.Driver

View File

@ -3,10 +3,12 @@ package ${package}.service;
import ${package}.domain.${className};
import ${package}.service.dto.${className}DTO;
import ${package}.service.dto.${className}QueryCriteria;
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author ${author}
@ -16,24 +18,24 @@ import org.springframework.data.domain.Pageable;
public interface ${className}Service {
/**
* queryAll 分页
* 查询数据分页
* @param criteria
* @param pageable
* @return
*/
//@Cacheable(keyGenerator = "keyGenerator")
Object queryAll(${className}QueryCriteria criteria, Pageable pageable);
//@Cacheable
Map<String,Object> queryAll(${className}QueryCriteria criteria, Pageable pageable);
/**
* queryAll 不分页
* 查询所有数据不分页
* @param criteria
* @return
*/
//@Cacheable(keyGenerator = "keyGenerator")
public Object queryAll(${className}QueryCriteria criteria);
//@Cacheable
List<${className}DTO> queryAll(${className}QueryCriteria criteria);
/**
* findById
* 根据ID查询
* @param ${pkChangeColName}
* @return
*/
@ -41,7 +43,7 @@ public interface ${className}Service {
${className}DTO findById(${pkColumnType} ${pkChangeColName});
/**
* create
* 创建
* @param resources
* @return
*/
@ -49,14 +51,14 @@ public interface ${className}Service {
${className}DTO create(${className} resources);
/**
* update
* 编辑
* @param resources
*/
//@CacheEvict(allEntries = true)
void update(${className} resources);
/**
* delete
* 删除
* @param ${pkChangeColName}
*/
//@CacheEvict(allEntries = true)

View File

@ -32,6 +32,8 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import java.util.List;
import java.util.Map;
/**
* @author ${author}
@ -48,13 +50,13 @@ public class ${className}ServiceImpl implements ${className}Service {
private ${className}Mapper ${changeClassName}Mapper;
@Override
public Object queryAll(${className}QueryCriteria criteria, Pageable pageable){
public Map<String,Object> queryAll(${className}QueryCriteria criteria, Pageable pageable){
Page<${className}> page = ${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(${changeClassName}Mapper::toDto));
}
@Override
public Object queryAll(${className}QueryCriteria criteria){
public List<${className}DTO> queryAll(${className}QueryCriteria criteria){
return ${changeClassName}Mapper.toDto(${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}

View File

@ -45,7 +45,7 @@ public class PictureController {
public ResponseEntity upload(@RequestParam MultipartFile file){
String userName = SecurityUtils.getUsername();
Picture picture = pictureService.upload(file,userName);
Map map = new HashMap(3);
Map<String,Object> map = new HashMap<>(3);
map.put("errno",0);
map.put("id",picture.getId());
map.put("data",new String[]{picture.getUrl()});

View File

@ -22,7 +22,7 @@ public interface LocalStorageService {
* @param pageable
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(LocalStorageQueryCriteria criteria, Pageable pageable);
/**
@ -30,7 +30,7 @@ public interface LocalStorageService {
* @param criteria
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
public Object queryAll(LocalStorageQueryCriteria criteria);
/**

View File

@ -20,7 +20,7 @@ public interface PictureService {
* @param pageable
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(PictureQueryCriteria criteria, Pageable pageable);
/**

View File

@ -24,7 +24,7 @@ public interface QiNiuService {
* @param pageable
* @return
*/
@Cacheable(keyGenerator = "keyGenerator")
@Cacheable
Object queryAll(QiniuQueryCriteria criteria, Pageable pageable);
/**

11
pom.xml
View File

@ -160,6 +160,17 @@
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/xerces/xercesImpl -->
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
</dependency>
<!-- fastjson -->
<dependency>