diff --git a/Readme.md b/Readme.md index 12cd8ec..dc11418 100644 --- a/Readme.md +++ b/Readme.md @@ -3,4 +3,7 @@ ##更新记录 2020/5/22 : 创建工程(代码有问题,先提交) -2020/5/26 : AspectJ代码提交,代码报错未解决 \ No newline at end of file +2020/5/26 : AspectJ代码提交,代码报错未解决 + +2020/5/29 : 增加Properties文件字段读取两种方式(propertiesScan),PostConstruct的使用、BeanPostProcessor在Bean初始化前后进行处理(init)、统一异常处理的两种方式(exceptionHandler)、统一出参报文处理(response) +新增上下文刷新判断处理类(refreshEvent)、添加HttpSession监听器(listener) \ No newline at end of file diff --git a/src/main/java/config/MvcComponentLoader.java b/src/main/java/config/MvcComponentLoader.java index 50fe74b..b2e6535 100644 --- a/src/main/java/config/MvcComponentLoader.java +++ b/src/main/java/config/MvcComponentLoader.java @@ -76,8 +76,8 @@ public class MvcComponentLoader extends WebMvcConfigurerAdapter { * @return */ // @Bean - // public MyExceptionHandler getExceptionHandler() { - // return new MyExceptionHandler(); + // public ExceptionResolver getExceptionHandler() { + // return new ExceptionResolver(); // } /** @@ -86,7 +86,7 @@ public class MvcComponentLoader extends WebMvcConfigurerAdapter { */ @Override public void extendHandlerExceptionResolvers(List exceptionResolvers) { - // exceptionResolvers.add(new MyExceptionHandler()); + // exceptionResolvers.add(new ExceptionResolver()); // ... } diff --git a/src/main/java/config/WebInitializer.java b/src/main/java/config/WebInitializer.java index 5c86796..fa73292 100644 --- a/src/main/java/config/WebInitializer.java +++ b/src/main/java/config/WebInitializer.java @@ -1,5 +1,6 @@ package config; +import config.refreshEvent.ContextRefreshEvent; import filter.FilterDelegator; import filter.WelcomeHandlingFilter; import org.springframework.util.StringUtils; @@ -30,11 +31,12 @@ public class WebInitializer extends AbstractAnnotationConfigDispatcherServletIni @Override public void onStartup(ServletContext servletContext) throws ServletException { super.onStartup(servletContext); - /**配置和监听器*/ + // 配置和监听器 registerServletFilters(servletContext); registerListeners(servletContext); - // QuartzListener quartzListener = new QuartzListener(); - // servletContext.addListener(quartzListener.getClass()); + //刷新事件需要作为监听器在这边配置 + ContextRefreshEvent refreshEvent = new ContextRefreshEvent(); + servletContext.addListener(refreshEvent.getClass()); } diff --git a/src/main/java/config/exceptionHandler/AnnoExceptionHandler.java b/src/main/java/config/exceptionHandler/AnnoExceptionHandler.java new file mode 100644 index 0000000..4b2bdea --- /dev/null +++ b/src/main/java/config/exceptionHandler/AnnoExceptionHandler.java @@ -0,0 +1,52 @@ +package config.exceptionHandler; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.ModelAndView; + +@ControllerAdvice +public class AnnoExceptionHandler { + + /** + * @a + * @param exception + * @return + */ + @ExceptionHandler(CustomGenericException.class)//可以直接写@ExceptionHandler,不指明异常类,会自动映射 + public ModelAndView customGenericExceptionHnadler(CustomGenericException exception){ //还可以声明接收其他任意参数 + ModelAndView modelAndView = new ModelAndView("generic_error"); + modelAndView.addObject("errCode",exception.getErrCode()); + modelAndView.addObject("errMsg",exception.getErrMsg()); + return modelAndView; + } + + @ExceptionHandler(Exception.class)//可以直接写@EceptionHandler,IOExeption继承于Exception + public ModelAndView allExceptionHandler(Exception exception){ + ModelAndView modelAndView = new ModelAndView("generic_error"); + modelAndView.addObject("errMsg", "this is Exception.class"); + return modelAndView; + } + + + public class CustomGenericException extends RuntimeException{ + private static final long serialVersionUID = 1L; + + private String errCode; + private String errMsg; + + public String getErrCode() { + return errCode; + } + + + public String getErrMsg() { + return errMsg; + } + + public CustomGenericException(String errCode, String errMsg) { + this.errCode = errCode; + this.errMsg = errMsg; + } + } + +} diff --git a/src/main/java/config/exceptionHandler/ExceptionResolver.java b/src/main/java/config/exceptionHandler/ExceptionResolver.java new file mode 100644 index 0000000..4164e06 --- /dev/null +++ b/src/main/java/config/exceptionHandler/ExceptionResolver.java @@ -0,0 +1,56 @@ +package config.exceptionHandler; + +import org.springframework.core.annotation.Order; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.view.json.MappingJackson2JsonView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author 志军 + * 继承spring的问题处理类, spring有默认的异常处理体系,默认的异常处理体系是先进行处理的。 + * 这里继承Order接口可以把我们的处理器作为位置0的处理器。但是默认的异常处理器的位置也是0,所以我们无法控制他们谁先处理 + * + * 可以参考MvcComponentLoader的描述 + * + * 通过继承接口进行处理是第一种方式 + */ +@Order(value = 0) +public class ExceptionResolver implements HandlerExceptionResolver { + + + /** + * 厉害了。这边也可测试一下如果是不给这个异常放在第一位的话,会出现什么情况, + * 其他的异常处理体系是不是会把异常进行处理 + */ + @Override + public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + System.out.printf("发现了异常,进入%s类", ExceptionResolver.class.getName()); + System.out.printf("错误信息:%s", ex.getMessage()); + //这里是匹配错误类型,把错误信息加上的地方 - 你可能会匹配很多的错误,这里的做法应该是对错误进行分类。 + ExceptionResponse exceptionResponse = null; + if (ex instanceof MethodArgumentNotValidException) { + MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) ex; + //这里面包含了错误的信息 + System.out.println(methodArgumentNotValidException.toString()); + exceptionResponse = new ExceptionResponse("500","报错"); + } + //最后就是异常处理返回 + MappingJackson2JsonView view = new MappingJackson2JsonView(); + view.setExtractValueFromSingleKeyModel(true); + return new ModelAndView(view, "response",exceptionResponse); + } + +} + class ExceptionResponse{ + private String code; + private String message; + + ExceptionResponse(String code, String message) { + this.code = code; + this.message = message; + } + } diff --git a/src/main/java/config/init/InitPost.java b/src/main/java/config/init/InitPost.java new file mode 100644 index 0000000..e577ad2 --- /dev/null +++ b/src/main/java/config/init/InitPost.java @@ -0,0 +1,22 @@ +package config.init; + +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * @author 志军 + * 测试一下@PostConstruct注解 + */ +@Component +public class InitPost { + + /** + * 该注解相当于servlet的init方法,且只会执行一次 + * 不知道这个的执行顺序,后面可以再了解一下 + */ + @PostConstruct + public void initPost(){ + System.out.println("我被初始化了"); + } +} diff --git a/src/main/java/config/init/SelfBeanPostProcess.java b/src/main/java/config/init/SelfBeanPostProcess.java new file mode 100644 index 0000000..0988a5a --- /dev/null +++ b/src/main/java/config/init/SelfBeanPostProcess.java @@ -0,0 +1,46 @@ +/* + * @(#) MyBeanPostProcess + * 版权声明 黄志军, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:黄志军 + *
@author selfImpr + *
2018-05-28 22:19:40 + *
@description + * + * + */ + +package config.init; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Component; + +/** + * @author 志军 + * 自定义Bean初始化前后处理的方法 + * 这边Spring使用的也是模板模式 + */ +@Component +public class SelfBeanPostProcess implements BeanPostProcessor { + + /** + * 在Bean初始化之前进行处理 + */ + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + System.out.println("beanName-----------" + beanName); + return bean; + } + + /** + * 在Bean初始化之后进行处理 + */ + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } +} diff --git a/src/main/java/config/propertiesScan/PropertiesScan.java b/src/main/java/config/propertiesScan/PropertiesScan.java new file mode 100644 index 0000000..93bf852 --- /dev/null +++ b/src/main/java/config/propertiesScan/PropertiesScan.java @@ -0,0 +1,42 @@ +package config.propertiesScan; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; + +/** + * @author selfimpr + * @description 通过该配置来实现对properties的属性进行读取 + * @date 2017/11/11 21:25 + * + * @PropertySource注解 解决中文乱码问题 好像还是需要设置IDEA的编码 + * //参考地址:http://blog.csdn.net/j3oker/article/details/53839210 + */ +@Configuration +@PropertySource(value = "classpath:appilcation.properties",encoding = "UTF-8") +public class PropertiesScan { + + @Value("${area_id}") + public String isBorder; + + @Value("${local_request_id}") + public String borderColor; + + public String getIsBorder() { + return isBorder; + } + + public String getBorderColor() { + return borderColor; + } + + /** + * 要想使用@Value 用${}占位符注入属性,这个bean是必须的,这个就是占位bean,另一种方式是不用value直接用Envirment变量直接getProperty('key') + */ + @Bean + public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } +} \ No newline at end of file diff --git a/src/main/java/config/propertiesScan/PropertiesScanByListener.java b/src/main/java/config/propertiesScan/PropertiesScanByListener.java new file mode 100644 index 0000000..4bf709c --- /dev/null +++ b/src/main/java/config/propertiesScan/PropertiesScanByListener.java @@ -0,0 +1,96 @@ +package config.propertiesScan; + +import util.FileUtil; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * 通过这个类来扫描获取所有的properties下面的文件 + * 这个监听器在Servlet上下文初始化过程中进行处理 + * @author 志军 + */ +@WebListener +public class PropertiesScanByListener implements ServletContextListener { + + private Map map = new HashMap<>(); + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext servletContext = sce.getServletContext(); + String resourcesPath = servletContext.getRealPath("/") + "WEB-INF\\classes\\cache"; + traceFilesAndGetProperties(resourcesPath); + servletContext.setAttribute("properties", map); + System.out.println(map); + } + + private void traceFilesAndGetProperties(String path) { + if (FileUtil.isDir(path)) { + File[] files = new File(path).listFiles(); + if (files == null || files.length == 0) { + System.out.println("文件夹是空的!"); + } else { + for (File file2 : files) { + if (file2.isDirectory()) { + System.out.println("文件夹:" + file2.getAbsolutePath()); + traceFilesAndGetProperties(file2.getAbsolutePath()); + } else { + //是否是配置文件 + if (file2.getAbsolutePath().contains(".properties")) { + getProperties(file2.getAbsolutePath()); + } + } + } + } + return; + } + + if (FileUtil.isFile(path)){ + if (new File(path).getAbsolutePath().contains(".properties")) { + getProperties(new File(path).getAbsolutePath()); + } + return; + } + + throw new RuntimeException("文件不存在"); + } + + private void getProperties(String filePath) { + Properties properties = new Properties(); + InputStream in = null; + try { + in = new FileInputStream(filePath); + properties.load(in); + for (Object o : properties.keySet()) { + String key = (String) o; + String value = properties.getProperty(key); + map.put(key, value); + } + } catch (IOException e) { + throw new RuntimeException(e ); + } finally { + try { + if (null != in) { + in.close(); + } + } catch (IOException e) { + System.out.println("文件流关闭失败:"+e.toString()); + } + } + } + + + @Override + public void contextDestroyed(ServletContextEvent sce) { + + } +} diff --git a/src/main/java/config/refreshEvent/ContextRefreshEvent.java b/src/main/java/config/refreshEvent/ContextRefreshEvent.java new file mode 100644 index 0000000..b40cd78 --- /dev/null +++ b/src/main/java/config/refreshEvent/ContextRefreshEvent.java @@ -0,0 +1,57 @@ +package config.refreshEvent; + +import org.quartz.*; +import org.quartz.impl.StdSchedulerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.PropertySource; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +@Component +@PropertySource("classpath:/app.properties") +public class ContextRefreshEvent implements ApplicationListener { + + @Autowired + private Environment environment; + + /** + * 程序启动,上下文刷新或者初始化的时候会调用该方法 + * Event raised when an {@code ApplicationContext} gets initialized or refreshed. + * 这边是选择在 onStartup方法上去配置这个监听器,但是也可以直接用@WebListener去注册这个监听器 + */ + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + //因为Spring有两个上下文容器,所以这边加上一个判断,让程序运营在住容器的时候就进行定时任务的执行. + if (event.getApplicationContext().getParent() == null) { + try { + //"0 0 3/1 3 * ? * "; + String timerTime = environment.getProperty("cron"); + Trigger trigger = TriggerBuilder + .newTrigger() + .withIdentity("dummyTriggerName", "group1") + .withSchedule(CronScheduleBuilder.cronSchedule(timerTime)) + .build(); + JobDetail job = JobBuilder.newJob(HelloJob.class) + .withIdentity("dummyJobName", "group1").build(); + Scheduler scheduler = new StdSchedulerFactory().getScheduler(); + scheduler.start(); + scheduler.scheduleJob(job, trigger); + } catch (SchedulerException e) { + throw new RuntimeException(e); + } + } + } + + class HelloJob implements Job { + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + System.out.print("hello quartz "); + } + } + +} + + + diff --git a/src/main/java/config/response/ResponseObject.java b/src/main/java/config/response/ResponseObject.java new file mode 100644 index 0000000..6fb780d --- /dev/null +++ b/src/main/java/config/response/ResponseObject.java @@ -0,0 +1,81 @@ +/* + * @(#) ShareResponseObject + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-11-13 20:34:52 + */ + +/** + * + */ + +package config.response; + +/** + * 响应对象。 + * + */ +public class ResponseObject { + + /** + * 状态码 + */ + private String status; + + /** + * 描述信息 + */ + private String message; + + /** + * 错误信息 + */ + private String errorMessage; + + /** + * 数据对象 + */ + private T dataView; + + public ResponseObject(String code, String message, T value) { + this.status = code; + this.message = message; + this.dataView = value; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public T getDataView() { + return dataView; + } + + public void setDataView(T dataView) { + this.dataView = dataView; + } +} diff --git a/src/main/java/config/response/ResponseProcess.java b/src/main/java/config/response/ResponseProcess.java new file mode 100644 index 0000000..13d74b1 --- /dev/null +++ b/src/main/java/config/response/ResponseProcess.java @@ -0,0 +1,53 @@ +/* + * @(#) ResponseConfiguration + * 版权声明 黄志军, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:黄志军 + *
@author selfImpr + *
2018-05-31 14:59:23 + *
@description + * + * + */ + +package config.response; + +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJacksonValue; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.mvc.method.annotation.AbstractMappingJacksonResponseBodyAdvice; + +/** + * 这里通过一个注解和继承的方式,对所有出控制器(被某一个注解标注的类) - 这里自定了一个注解为TestResponse + * 对这种类进行参数的处理 + * 好像这个注解还有叠加的作用.... + * 这个注解也可以作为异常处理的操作。即在每个方法上面添加处理的class。还想这样很麻烦啊,还不如用异常处理器 + * @author 志军 + */ +@ControllerAdvice +public class ResponseProcess extends AbstractMappingJacksonResponseBodyAdvice { + + /** + * 这个注解好像是必须捕获ResponseBody这个解决才会进行执行,@ResponseBody表明这个返回的东西是在报文里面, + * 且如果不配置转换器,spring会自动提供7个,但是如果我们想规定顺序就要自己配置 + */ + @Override + public boolean supports(MethodParameter returnType, Class> converterType) { + System.out.println( returnType.getMethod().getName()); + return returnType.hasMethodAnnotation(ResponseBody.class); + } + + @Override + protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType, MethodParameter returnType, + ServerHttpRequest request, ServerHttpResponse response) { + Object value = bodyContainer.getValue(); + ResponseObject object = new ResponseObject<>("200", "调度成功", value); + bodyContainer.setValue(object); + } +} diff --git a/src/main/java/controller/PropertiesGetController.java b/src/main/java/controller/PropertiesGetController.java new file mode 100644 index 0000000..ab3f1d2 --- /dev/null +++ b/src/main/java/controller/PropertiesGetController.java @@ -0,0 +1,25 @@ +package controller; + +import config.propertiesScan.PropertiesScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * @author selfimpr + * @description 测试SpringConfig利用注解来实现properties配置文件的读取 + * @date 2017/11/11 21:26 + */ + +@Controller +public class PropertiesGetController { + + @Autowired + private PropertiesScan propertiesConfig; + + @RequestMapping("/get/properties") + public void getProperties() { + System.out.println(propertiesConfig.getIsBorder()); + System.out.println(propertiesConfig.getBorderColor()); + } +} diff --git a/src/main/java/listener/TestHttpSessionListener.java b/src/main/java/listener/TestHttpSessionListener.java new file mode 100644 index 0000000..3b05623 --- /dev/null +++ b/src/main/java/listener/TestHttpSessionListener.java @@ -0,0 +1,47 @@ +package listener; + +import org.apache.log4j.Logger; + +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +/** + * 处理Session创建和消亡的类,这边通过@WebListener注解直接声明为监听器 + * @author 志军 + */ +@WebListener +public class TestHttpSessionListener implements HttpSessionListener { + + private Logger logger = Logger.getLogger(HttpSessionListener.class); + @Override + public void sessionCreated(HttpSessionEvent se) { + + SessionListenerTask sessionListenerTask = new SessionListenerTask(); + HttpSession session = se.getSession(); + // 设置session过期时间 --这种方式并不科学 + se.getSession().setMaxInactiveInterval(20); + logger.debug("session创建时间:"+session.getCreationTime()); + + //为了让页面加载看起来更流畅,这里模拟了两个情况,一个是用线程实现不等待,一个是加载数据库等待 + if(SessionListenerTask.isIsFirst()){ + sessionListenerTask.run(); + SessionListenerTask.setIsFirst(false); + }else{ + //这里是同步情况 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + System.out.println("session 加载开始,时间为:" + System.currentTimeMillis()); + } + + @Override + public void sessionDestroyed(HttpSessionEvent se) { + se.getSession().getCreationTime(); + System.out.println("session过期了"); + } +} diff --git a/src/main/java/model/FileItem.java b/src/main/java/model/FileItem.java new file mode 100644 index 0000000..feb4ded --- /dev/null +++ b/src/main/java/model/FileItem.java @@ -0,0 +1,28 @@ + + +package model; + +import java.io.InputStream; + +public class FileItem { + + private String fileName; + + private InputStream inputStream; + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public InputStream getInputStream() { + return inputStream; + } + + public void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; + } +} diff --git a/src/main/java/util/FileUtil.java b/src/main/java/util/FileUtil.java new file mode 100644 index 0000000..795ebd1 --- /dev/null +++ b/src/main/java/util/FileUtil.java @@ -0,0 +1,263 @@ + + +package util; + + +import com.google.common.collect.Lists; +import model.FileItem; +import org.springframework.util.CollectionUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * + * @author huangzj1 + */ +public class FileUtil { + + private static final byte[] BUF = new byte[1024]; + + private static final int BUF_SIZE = 1024; + + public static void deleteFile(String filePath) { + File file = new File(filePath); + if (!file.exists()) { + throw new RuntimeException("文件不存在"); + } + + file.delete(); + } + + + /** + * 支持输入流存储到对应文件夹下,仅对文件夹有效 + * @param fileItems 输入流、文件名 数组 + * @param dirPath 文件夹路径 + */ + public static void storeFiles(List fileItems, String dirPath) { + File file = new File(dirPath); + if (!file.exists() && !file.isDirectory()) { + file.mkdir(); + } + + fileItems.forEach(fileItem -> { + File fileItemFile = new File(dirPath + File.separator + fileItem.getFileName()); + FileOutputStream fileOutputStream; + + try { + //创建文件 + fileItemFile.createNewFile(); + fileOutputStream = new FileOutputStream(fileItemFile); + int len; + while ((len = fileItem.getInputStream().read(BUF, 0, BUF_SIZE)) != -1) { + fileOutputStream.write(BUF, 0, len); + } + + fileOutputStream.close(); + fileItem.getInputStream().close(); + } catch (IOException e) { + throw new RuntimeException("生成文件错误"); + } + }); + } + + public static boolean fileExist(String filePath){ + File file = new File(filePath); + return file.exists(); + } + + public static boolean isFile(String filePath){ + File file = new File(filePath); + if ( file.exists()){ + return file.isFile(); + } + return false; + } + + public static boolean isDir(String filePath){ + File file = new File(filePath); + if ( file.exists()){ + return file.isDirectory(); + } + return false; + } + + /** + * 文件已存在或者创建成功返回true + * 文件不存在或者非文件(文件夹)或者创建失败,返回false + */ + public static boolean createFile(String filePath){ + if(fileExist(filePath)){ + return isFile(filePath); + } + File file = new File(filePath); + try { + return file.createNewFile(); + } catch (IOException e) { + return false; + } + } + + /** + * 创建并获取一个File对象 + * 如果是文件、创建成功返回对应的文件对象 + * 其他情况直接返回null. + */ + public static File createGetFile(String filePath){ + if(fileExist(filePath)){ + if ( isFile(filePath)){ + return new File(filePath); + } + } + File file = new File(filePath); + try { + boolean result = file.createNewFile(); + if (result){ + return file; + } + } catch (IOException e) { + return null; + } + return null; + } + + /** + * 文件转换成byte数组 + */ + public static byte[] fileToByte(String filePath) { + FileInputStream in = null; + try { + in = new FileInputStream(new File(filePath)); + byte[] bytes = new byte[in.available()]; + in.read(bytes); + return bytes; + } catch (IOException e) { + throw new RuntimeException("转换失败",e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * byte数组写入文件 + */ + public static void bytesToFile(String filePath,byte[] content){ + FileOutputStream out = null; + try { + out = new FileOutputStream(new File(filePath)); + out.write(content); + out.flush(); + } catch (IOException e) { + throw new RuntimeException("写入失败",e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + + /** + * 拿到文件夹下面的所有文件夹(包括它自己) + */ + public static List findAllDirFromDir(String dirPath){ + File dir = new File(dirPath); + if(!dir.exists() || !dir.isDirectory()){ + throw new RuntimeException("非文件夹或者文件夹位置错误"); + } + List result = findDir(dir); + result.add(dir); + return result; + } + + private static List findDir(File file ){ + List list = Lists.newArrayList(); + for(File child : Objects.requireNonNull(file.listFiles())){ + if(child.isDirectory()){ + list.add(child); + List tempList = findDir(child); + if(!CollectionUtils.isEmpty(tempList)){ + list.addAll(tempList); + } + } + } + return list; + } + + + /** + * 拿到文件夹下面的所有空文件夹 + */ + public static List findAllEmptyDirFromDir( String dirPath){ + List list = Lists.newArrayList(); + File dir = new File(dirPath); + if(!dir.exists() || !dir.isDirectory()){ + throw new RuntimeException("非文件夹或者文件夹位置错误"); + } + List allList = findAllDirFromDir(dirPath); + for(File dirFile:allList){ + if(isEmptyFile(dirFile)){ + list.add(dirFile); + } + } + return list; + } + + + /** + * 通过目录获取目录下所有的文件 + */ + public static List findAllFile(File dir){ + List list = Lists.newArrayList(); + for (File file : Objects.requireNonNull(dir.listFiles())){ + if(file.isFile()){ + list.add(file); + }else{ + List tempList = findAllFile(file); + if(!CollectionUtils.isEmpty(tempList)){ + list.addAll(tempList); + } + } + } + return list; + } + + private static boolean isEmptyFile(File dir) { + List child = findAllFile(dir); + return CollectionUtils.isEmpty(child); + } + + + /** + * 拿到文件夹下面的所有非空文件夹 + */ + public static List findAllNotEmptyDirFromDir( String dirPath){ + List list = Lists.newArrayList(); + File dir = new File(dirPath); + if(!dir.exists() || !dir.isDirectory()){ + throw new RuntimeException("非文件夹或者文件夹位置错误"); + } + List allList = findAllDirFromDir(dirPath); + for(File dirFile:allList){ + if(!isEmptyFile(dir)){ + list.add(dirFile); + } + } + return list; + } +} diff --git a/src/main/resources/app.properties b/src/main/resources/app.properties new file mode 100644 index 0000000..f032d90 --- /dev/null +++ b/src/main/resources/app.properties @@ -0,0 +1,4 @@ +#spring ṩEnvironmentapplication.propertiesapplication-$(profile).propertiesļ +#Dzһ +#quartzʱ +cron=0 0 3/1 3 * ? * diff --git a/src/main/resources/appilcation.properties b/src/main/resources/appilcation.properties new file mode 100644 index 0000000..31b8f46 --- /dev/null +++ b/src/main/resources/appilcation.properties @@ -0,0 +1,2 @@ +area_id=\u9EC4\u5FD7\u519B +local_request_id=JOINT_THEME diff --git a/src/main/resources/application-a.properties b/src/main/resources/application-a.properties new file mode 100644 index 0000000..00867cb --- /dev/null +++ b/src/main/resources/application-a.properties @@ -0,0 +1 @@ +b=1 \ No newline at end of file