1、视图解析器ViewResolver
2、静态资料的目录
3、默认首页index.html
4、图标名字和图标所在目录,favicon.ico
5、类型转换器Converter,格式转换器的Formatter
6、消息转换器HttpMessageConverters,我们直接向页面返回JSON格式的数据就靠它实现
7、消息代码解析器MessageCodesResolver, 作用配置了错误代码显示规则的一些东西,JSR303数据校验要用到它
在项目开发中,这些默认配置是绝对不够用的,所以,必须在它们的基础上扩展更多我们需要的配置。
SpringBoot 提供了相应扩展接口WebMvcConfigurer,在SpringBoot的配置类上实现它并加上@Configuretion注解就可以了
在之前使用SpringMVC时,可以在springmvc.xml配置文件中直接配置路径映射。
如果模板页面只是动态渲染,不需要后台的数据,那个我们就可以配置路径映射。这样就不需要在controller类里写映射方法返回页面。比如:欢迎页面,路径映射或者controller或者静态index方式实现,只是动态动态渲染,路径映射方式更好。
在SpringBoot 中创建配置类,实现接口WebMvcConfigurer
@Configuration
public class AddMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index") // 访问的路径
.setViewName("index"); // 视图名
registry.addViewController("/hello").setViewName("hello");
}
}
index.html 简单展示下:
注意:
1)关于扩展,有一个特殊的注解 @EnableWebMvc ,它的作用是全面接管SpringMvc的配置,也就是说SpringBoot的所有关于SpringMvc的自动配置都会失效(包括静态资源页的访问等等),而只有我们自己做的配置才会生效,所以什么都需要我们自己手动配置所有的类。
2)官方解释:
如果要保留Spring Boot MVC功能,并且要添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),可以添加自己的@configuration类(类型为webmvcconfigurer),但不添加@enableWebMVC。如果要提供RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,可以声明WebMVCregistrationsAdapter实例以提供此类组件。
如果要完全控制SpringMVC,可以添加自己的@configuration,并用@enableWebMVC注释。
3)Springboot提供了大量的自动配置,如果项目不想使用它的自动配置,可以可以在启动类上使用exclude排除。一般没必要排除。
@SpringBootApplication(exclude = {WebMvcAutoConfiguration.class, DataSourceAutoConfiguration.class})
1)在配置类中添加 拦截器配置
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 配置拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login", "/", "/index");
}
}
2)创建拦截器实现类
public class LoginInterceptors extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle 方法。。。");
return super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle 方法。。。");
super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
System.out.println("afterCompletion 方法。。。");
super.afterCompletion(request, response, handler, ex);
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("afterConcurrentHandlingStarted 方法。。。");
super.afterConcurrentHandlingStarted(request, response, handler);
}
}
preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应。
postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器才会执行。
3)访问url 接口拦截:
传送门:springmvc自定义数据转换器
Springboot项目中,这里定义字符串日期转换为Date转换器,全局的配置。
@Component
public class StringToDateConverter implements Converter {
// 这里约定日期时间格式为:yyyy-MM-dd HH:mm:ss
private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String DATE_FORMAT = "yyyy-MM-dd";
private final String DATE_REG = "^\\d+$";
@Override
public Date convert(String value) {
if (StringUtils.isBlank(value)) {
return null;
}
value = value.trim();
try {
if (value.contains("-")) {
SimpleDateFormat format;
if (value.contains(":")) {
// 表示传入的是日期时间
format = new SimpleDateFormat(DATETIME_FORMAT);
} else {
// 表示传入的是日期
format = new SimpleDateFormat(DATE_FORMAT);
}
return format.parse(value);
} else if (value.matches(DATE_REG)) {
// 表示传入的是时间戳
Long lDate = new Long(value);
return new Date(lDate);
}
} catch (Exception e) {
throw new RuntimeException(String.format("parse %s to Date fail", value));
}
return null;
}
controller中
@GetMapping("/stringToDate")
@ResponseBody
public User stringToDate(User user){
return user;
}
// http://127.0.0.1:8080/stringToDate?id=5&name=李四&birthday=2018-10-22
如果不使用全局配置,对每个pojo,可以使用注解单独配置,这里使用的是jackson组件
@JsonFormat(shape = JsonFormat.Shape.STRING, timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonSerialize(using = DateSerializer.class)
private Date birthday;
如果想在项目启动阶段需要做一些数据初始化的操作,这些操作有一个共同的特点,只在项目启动时进行,以后都不再执行。
在Servlet项目中,会想到web基础中的三大组件( Servlet、Filter、Listener )中的 Listener 处理,一般定义一个 ServletContextListener,然后就可以监听到项目启动和销毁,进而做出相应的数据初始化和销毁操作。比如:
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("服务器启动时触发,可以做数据初始化等操作");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("服务器关闭时触发,可以做数据备份等操作");
}
}
@Configuration
public class WebConfig {
@Bean
public ServletListenerRegistrationBean myListernerBean(){
return new ServletListenerRegistrationBean(new MyListener());
}
}
在 SpringBoot项目中,使用更为简便。Spring Boot 中针对系统启动任务提供了两种解决方案,分别是 CommandLineRunner 和 ApplicationRunner。两者用法基本一致,主要体现在对参数的处理上,可以根据项目中的实际情况选择合适的解决方案。
1、方式一:CommandLineRunner
使用 CommandLineRunner时,需要注意:这里参数传递时没有key,直接写value即可。
自定义 MyCommandLineRunner 类并实现 CommandLineRunner 接口即可。
@Component
@Order(999)
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println(Arrays.toString(args));
}
}
当项目启动时,这里的 run 方法就会被自动执行。
如果在 IDEA 中,我们可以通过如下方式来传入参数:
如果将项目打包,在命令行中启动项目,可以在启动时的命令行后面传入参数:
2、方式二:ApplicationRunner
ApplicationRunner 可以接收更多类型的参数(ApplicationRunner 除了可以接收 CommandLineRunner 的参数之外,还可以接收 key/value形式的参数)。
自定义 MyApplicationRunner类并实现 ApplicationRunner 接口即可。
@Component
@Order(1000)
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List nonOptionArgs = args.getNonOptionArgs();
System.out.println("nonOptionArgs==" + nonOptionArgs);
String[] sourceArgs = args.getSourceArgs();
System.out.println("sourceArgs==" + Arrays.toString(sourceArgs));
Set optionNames = args.getOptionNames();
for (String optionName : optionNames) {
System.out.println("key==" + optionName + ",value==" + args.getOptionValues(optionName));
}
}
}
ApplicationArguments中的几个方法:
当项目启动时,这里的 run 方法就会被自动执行。
如果在 IDEA 中,我们可以通过如下方式来传入参数:
如果将项目打包,在命令行中启动项目,可以在启动时的命令行后面传入参数:
Spring Boot 中针对系统关闭任务提供了两种解决方案:
方式一:实现DisposableBean接口
@Component
public class MyDisposableBean implements DisposableBean, ExitCodeGenerator {
@Override
public void destroy() throws Exception {
System.out.println("服务器被关闭了>>>>>>>>>>>>>>>");
}
@Override
public int getExitCode() {
return 5;
}
}
方式二:使用@PreDestroy注解
@Component
public class MyDisposableBean2 {
@PreDestroy
public void myDestory() {
System.out.println("服务器被关闭了>>>>>>>>>>使用@PreDestroy>>>>>");
}
}
参考文章:https://blog.csdn.net/She_lock/article/details/86241685
ends ~