feat(Java_SpringExample): 增加Properties文件字段读取两种方式(propertiesScan),PostConstruct的使用、BeanPostProcessor在Bean初始化前后进行处理(init)、统一异常处理的两种方式(exceptionHandler)、统一出参报文处理(response)、新增上下文刷新判断处理类(refreshEvent)、添加HttpSession监听器(listener)
This commit is contained in:
@@ -4,3 +4,6 @@
|
|||||||
2020/5/22 : 创建工程(代码有问题,先提交)
|
2020/5/22 : 创建工程(代码有问题,先提交)
|
||||||
|
|
||||||
2020/5/26 : AspectJ代码提交,代码报错未解决
|
2020/5/26 : AspectJ代码提交,代码报错未解决
|
||||||
|
|
||||||
|
2020/5/29 : 增加Properties文件字段读取两种方式(propertiesScan),PostConstruct的使用、BeanPostProcessor在Bean初始化前后进行处理(init)、统一异常处理的两种方式(exceptionHandler)、统一出参报文处理(response)
|
||||||
|
新增上下文刷新判断处理类(refreshEvent)、添加HttpSession监听器(listener)
|
||||||
@@ -76,8 +76,8 @@ public class MvcComponentLoader extends WebMvcConfigurerAdapter {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
// @Bean
|
// @Bean
|
||||||
// public MyExceptionHandler getExceptionHandler() {
|
// public ExceptionResolver getExceptionHandler() {
|
||||||
// return new MyExceptionHandler();
|
// return new ExceptionResolver();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +86,7 @@ public class MvcComponentLoader extends WebMvcConfigurerAdapter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||||
// exceptionResolvers.add(new MyExceptionHandler());
|
// exceptionResolvers.add(new ExceptionResolver());
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package config;
|
package config;
|
||||||
|
|
||||||
|
import config.refreshEvent.ContextRefreshEvent;
|
||||||
import filter.FilterDelegator;
|
import filter.FilterDelegator;
|
||||||
import filter.WelcomeHandlingFilter;
|
import filter.WelcomeHandlingFilter;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@@ -30,11 +31,12 @@ public class WebInitializer extends AbstractAnnotationConfigDispatcherServletIni
|
|||||||
@Override
|
@Override
|
||||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||||
super.onStartup(servletContext);
|
super.onStartup(servletContext);
|
||||||
/**配置和监听器*/
|
// 配置和监听器
|
||||||
registerServletFilters(servletContext);
|
registerServletFilters(servletContext);
|
||||||
registerListeners(servletContext);
|
registerListeners(servletContext);
|
||||||
// QuartzListener quartzListener = new QuartzListener();
|
//刷新事件需要作为监听器在这边配置
|
||||||
// servletContext.addListener(quartzListener.getClass());
|
ContextRefreshEvent refreshEvent = new ContextRefreshEvent();
|
||||||
|
servletContext.addListener(refreshEvent.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package config.init;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 志军
|
||||||
|
* 测试一下<code>@PostConstruct</code>注解
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class InitPost {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该注解相当于servlet的init方法,且只会执行一次
|
||||||
|
* 不知道这个的执行顺序,后面可以再了解一下
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
public void initPost(){
|
||||||
|
System.out.println("我被初始化了");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* @(#) MyBeanPostProcess
|
||||||
|
* 版权声明 黄志军, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:黄志军
|
||||||
|
* <br> @author selfImpr
|
||||||
|
* <br> 2018-05-28 22:19:40
|
||||||
|
* <br> @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
*
|
||||||
|
* <code>@PropertySource</code>注解 解决中文乱码问题 好像还是需要设置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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<String, String> 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<ContextRefreshedEvent> {
|
||||||
|
|
||||||
|
@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 ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* @(#) ShareResponseObject
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 2018-11-13 20:34:52
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package config.response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应对象。
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ResponseObject<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态码
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* @(#) ResponseConfiguration
|
||||||
|
* 版权声明 黄志军, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:黄志军
|
||||||
|
* <br> @author selfImpr
|
||||||
|
* <br> 2018-05-31 14:59:23
|
||||||
|
* <br> @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<? extends HttpMessageConverter<?>> 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> object = new ResponseObject<>("200", "调度成功", value);
|
||||||
|
bodyContainer.setValue(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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创建和消亡的类,这边通过<code>@WebListener</code>注解直接声明为监听器
|
||||||
|
* @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过期了");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<FileItem> 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<File> findAllDirFromDir(String dirPath){
|
||||||
|
File dir = new File(dirPath);
|
||||||
|
if(!dir.exists() || !dir.isDirectory()){
|
||||||
|
throw new RuntimeException("非文件夹或者文件夹位置错误");
|
||||||
|
}
|
||||||
|
List<File> result = findDir(dir);
|
||||||
|
result.add(dir);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<File> findDir(File file ){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
for(File child : Objects.requireNonNull(file.listFiles())){
|
||||||
|
if(child.isDirectory()){
|
||||||
|
list.add(child);
|
||||||
|
List<File> tempList = findDir(child);
|
||||||
|
if(!CollectionUtils.isEmpty(tempList)){
|
||||||
|
list.addAll(tempList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拿到文件夹下面的所有空文件夹
|
||||||
|
*/
|
||||||
|
public static List<File> findAllEmptyDirFromDir( String dirPath){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
File dir = new File(dirPath);
|
||||||
|
if(!dir.exists() || !dir.isDirectory()){
|
||||||
|
throw new RuntimeException("非文件夹或者文件夹位置错误");
|
||||||
|
}
|
||||||
|
List<File> allList = findAllDirFromDir(dirPath);
|
||||||
|
for(File dirFile:allList){
|
||||||
|
if(isEmptyFile(dirFile)){
|
||||||
|
list.add(dirFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过目录获取目录下所有的文件
|
||||||
|
*/
|
||||||
|
public static List<File> findAllFile(File dir){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
for (File file : Objects.requireNonNull(dir.listFiles())){
|
||||||
|
if(file.isFile()){
|
||||||
|
list.add(file);
|
||||||
|
}else{
|
||||||
|
List<File> tempList = findAllFile(file);
|
||||||
|
if(!CollectionUtils.isEmpty(tempList)){
|
||||||
|
list.addAll(tempList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isEmptyFile(File dir) {
|
||||||
|
List<File> child = findAllFile(dir);
|
||||||
|
return CollectionUtils.isEmpty(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拿到文件夹下面的所有非空文件夹
|
||||||
|
*/
|
||||||
|
public static List<File> findAllNotEmptyDirFromDir( String dirPath){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
File dir = new File(dirPath);
|
||||||
|
if(!dir.exists() || !dir.isDirectory()){
|
||||||
|
throw new RuntimeException("非文件夹或者文件夹位置错误");
|
||||||
|
}
|
||||||
|
List<File> allList = findAllDirFromDir(dirPath);
|
||||||
|
for(File dirFile:allList){
|
||||||
|
if(!isEmptyFile(dir)){
|
||||||
|
list.add(dirFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#spring 提供的Environment会加载application.properties和application-$(profile).properties文件。
|
||||||
|
#这里就是测试一下
|
||||||
|
#用于做quartz定时任务
|
||||||
|
cron=0 0 3/1 3 * ? *
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
area_id=\u9EC4\u5FD7\u519B
|
||||||
|
local_request_id=JOINT_THEME
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
b=1
|
||||||
Reference in New Issue
Block a user