十六:自定义拦截器

参考文档

16.1 编写拦截器类

extends WebMvcConfigurerAdapter 重写WebMvcConfigurerAdapter,如下:

 package com.wu.interceptor;

 import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration//声明这是一个配置
public class MyInterceptor extends WebMvcConfigurerAdapter { @Override
public void addInterceptors(InterceptorRegistry registry) {
//以内部类的创建拦截器
HandlerInterceptor interceptor=new HandlerInterceptor() { @Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("自定义拦截器");
//返回true时放行
return true;
} @Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
} @Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
};
//注册拦截器并设置拦截路径
registry.addInterceptor(interceptor).addPathPatterns("/**");
} }

MyInterceptor.java

注意:需要在拦截器类上添加 @Configuration,声明这是一个配置类,还需要在启动类中需要扫描到该类,如以下所示:

 package com.wu.app;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; //@EnableAutoConfiguration
//@ComponentScan("com.wu.controller")//默认扫描的是当前包和当前包的子包
@SpringBootApplication(scanBasePackages={"com.wu.controller","com.wu.interceptor"})
public class SpringApplications {
//程序启动入口
public static void main(String []args){
SpringApplication.run(SpringApplications.class, args);
}
}

在启动类中添加扫描到拦截器类的包路径

16.2 测试定义的拦截器是否生效

编写Controller类简单测试刚刚定义的拦截器是否有效,如下:

 package com.wu.controller;

 import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class TestController {
@RequestMapping("/test")
public String test(){
System.out.println("这是一个测试");
return "test";
}
}

TestController.java

在控制台中可以看到输出顺序:

十七:全局异常处理器的简单实现

参考文档

17.1 编写异常处理器类

 package com.wu.controller;

 import java.util.HashMap;
import java.util.Map; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Map<String,Object> handleException(Exception e){
Map<String,Object> map=new HashMap<>();
map.put("errorCode","500");
map.put("Msg",e.toString());
return map;
}
}

GlobalExceptionHandler.java

17.2 编写测试类

 package com.wu.controller;

 import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class TestController {
@RequestMapping("/test")
public String test(){
int a=1/0;
return "test";
}
}

TestController.java

测试结果:

十八:SpringBoot中的异步调用

18.1 相关知识

参考文档:Java中的FutureFuture接口

Future接口的作用:

  • 代表异步计算的执行结果;
  • 用于可取消的task;(比使用interrupt实现取消要方便 )

18.2在Service层中编写异步测试类

 package com.wu.service;

 import java.util.concurrent.Future;

 public interface AsyncService {
Future<String> doTask1()throws Exception;
Future<String> doTask2()throws Exception;
Future<String> doTask3()throws Exception;
}

AsyncService.java

 package com.wu.service;

 import java.util.Random;
import java.util.concurrent.Future; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
@Service
public class AsyncServiceImp implements AsyncService {
@Async
@Override
public Future<String> doTask1() throws Exception {
System.out.println("任务一开始");
long start=System.currentTimeMillis();
Thread.sleep(new Random().nextInt(10000));
long end =System.currentTimeMillis();
System.out.println("任务一结束时间:"+(end-start)+"ms");
return new AsyncResult<String>("任务一结束");
}
@Async
@Override
public Future<String> doTask2() throws Exception {
System.out.println("任务二开始");
long start=System.currentTimeMillis();
Thread.sleep(new Random().nextInt(10000));
long end =System.currentTimeMillis();
System.out.println("任务二结束时间:"+(end-start)+"ms");
return new AsyncResult<String>("任务二结束");
}
@Async
@Override
public Future<String> doTask3() throws Exception {
System.out.println("任务三开始");
long start=System.currentTimeMillis();
Thread.sleep(new Random().nextInt(10000));
long end =System.currentTimeMillis();
System.out.println("任务三结束时间:"+(end-start)+"ms");
return new AsyncResult<String>("任务三结束");
} }

AsyncServiceImp.java

 package com.wu.controller;

 import java.util.concurrent.Future;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import com.wu.service.AsyncService;
import com.wu.service.AsyncServiceImp; @RestController
public class TestController {
@Autowired
private AsyncService asyncService =new AsyncServiceImp(); @RequestMapping("/async")
public String testAsync() throws Exception{
long start=System.currentTimeMillis();
Future<String> task1 = asyncService.doTask1();
Future<String> task2 = asyncService.doTask2();
Future<String> task3 = asyncService.doTask3();
//判断三个任务是否结束
while(true){
if(task1.isDone()&&task2.isDone()&&task3.isDone()){
break;
}
//当前线程停一会再判断
Thread.sleep(1000);
}
long end =System.currentTimeMillis();
return "总耗时:"+(end-start)+"ms";
}
}

TestController.java

 package com.wu.app;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication(scanBasePackages={"com.wu.controller","com.wu.service"})
@EnableAsync//启用异步调用
public class SpringApplications {
//程序启动入口
public static void main(String []args){
SpringApplication.run(SpringApplications.class, args);
}
}

启动类中也需要配置扫描和启动异步

18.3 显示结果

18.4 总结

在需要异步加载的方法上加上注解 @Async

在启动类中需要扫描相应的包,和启动异步调用 @EnableAsync

 十九:SpringBoot整合Jsp

19.1 前言

SpringBoot官方不推荐使用Jsp,因为Jsp相对于一些模板引擎性能较低,官方推荐使用Thymeleaf

19.2 创建war工程,并添加相应依赖

注意:SpringBoot整合Jsp需要创建的是war工程

 <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.wu</groupId>
<artifactId>SpringBoot_Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>SpringBoot_Child4</artifactId>
<packaging>war</packaging> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- 添加servlet依赖模块 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 添加jstl标签库依赖模块 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!--添加tomcat依赖模块.-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- 使用jsp引擎,springboot内置tomcat没有此依赖 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency> </dependencies>
</project>

pom.xml

 spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

application.properties

 package com.wu.controller;

 import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class TestJspController {
@RequestMapping("/test")
public String test(){
return "test";
}
}

TestJspController.jsp

 package com.wu.app;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication(scanBasePackages={"com.wu.controller"})
public class SpringApplications {
//程序启动入口
public static void main(String []args){
SpringApplication.run(SpringApplications.class, args);
}
}

启动类

test.jsp文件所在位置:

19.3 简单测试结果

二十:SpringBoot整合Freemarker

20.0     参考文档1    Freemarker基本语法入门

20.1 在pom.xml中加入相关依赖

       <!-- Freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

Freemarker依赖

20.2 简单应用

SpringBoot默认读取的是src/main/resources/templates

如:

 <html>
<head>
<title>Welcome!</title>
</head>
<body>
${name}
</body>
</html>

test.ftl

 package com.wu.controller;

 import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class TestFreemarkerController {
@RequestMapping("/test")
public String test(Model model){
model.addAttribute("name","這是一個測試。");
return "test";
}
}

TestFreemarkerController.java

记得在启动类中扫描相应的包,之后启动,结果如下:

20.3 SpringBoot与Freemarker相关的配置可以在application.properties配置

 # 是否允许HttpServletRequest属性覆盖(隐藏)控制器生成的同名模型属性。
spring.freemarker.allow-request-override=false
# 是否允许HttpSession属性覆盖(隐藏)控制器生成的同名模型属性。
spring.freemarker.allow-session-override=false
# 是否启用模板缓存。
spring.freemarker.cache=false
# 模板编码。
spring.freemarker.charset=UTF-8
# 是否检查模板位置是否存在。
spring.freemarker.check-template-location=true
# Content-Type value.
spring.freemarker.content-type=text/html
# 是否启用freemarker
spring.freemarker.enabled=true
# 设定所有request的属性在merge到模板的时候,是否要都添加到model中.
spring.freemarker.expose-request-attributes=false
# 是否在merge模板的时候,将HttpSession属性都添加到model中
spring.freemarker.expose-session-attributes=false
# 设定是否以springMacroRequestContext的形式暴露RequestContext给Spring’s macro library使用
spring.freemarker.expose-spring-macro-helpers=true
# 是否优先从文件系统加载template,以支持热加载,默认为true
spring.freemarker.prefer-file-system-access=true
# 设定模板的后缀.
spring.freemarker.suffix=.ftl
# 设定模板的加载路径,多个以逗号分隔,默认:
spring.freemarker.template-loader-path=classpath:/templates/
# 设定FreeMarker keys.
spring.freemarker.settings.template_update_delay=0
spring.freemarker.settings.default_encoding=UTF-8
spring.freemarker.settings.classic_compatible=true SpringBoot整合Freemarker的相关属性配置

SpringBoot中Freemarker的属性配置

二十一:SpringBoot整合Thymeleaf

21.0  Thymeleaf的常用语法解析     参考文档2

21.1 在pom.xml中加入相关依赖

      <!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Thymeleaf的依赖

21.2 简单应用

默认读取的是src/main/resources/templates/

如:

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Thymeleaf_Test</title>
</head>
<body>
<span th:text="${name}"></span>
</body>
</html>

test.html

 package com.wu.controller;

 import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class TestThymeleafController {
@RequestMapping("/test")
public String test(Model model){
model.addAttribute("name","这也是一个测试!");
return "test";
}
}

TestThymeleafController.java

 #关闭thymeleaf缓存,开发时使用,否者不能实时显示
spring.thymeleaf.cache=false
#检查模板是否纯在,然后再呈现
spring.thymeleaf.check-template-location=true
#content-type的值
spring.thymeleaf.content-type=text/html
#启用MVC Thymeleaf视图分辨率
spring.thymeleaf.enabled=true
#编码格式
spring.thymeleaf.encoding=UTF-8
#前缀,此为默认
spring.thymeleaf.prefix=classpath:/templates/
#后缀,常用.html
spring.thymeleaf.suffix=.html
#模板编码,thymeleaf对html的标签约束非常严格,所有的标签必须有开有闭,比如<br></br>或者<br/>是可以的,但是<br>会报错,配置spring.thymeleaf.mode=LEGACYHTML5 目的就是为了解决这个问题,可以使页面松校验。
spring.thymeleaf.mode=LEGACYHTML5

在application.properties中可以配置Thymeleaf的相关属性

在启动类中启动,查看

报错,原因:在全局配置中配置了spring.thymeleaf.mode=LEGACYHTML5,是非严格检查,需要加入nekohtml的依赖,如:

       <!-- nekohtml -->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.15</version>
</dependency>

nekohtml的依赖

之后重新启动,查看结果如下:

二十二:SpringBoot实现定时任务调用

22.1  spring-boot-quartz    推荐参考

22.2  spring-boot-scheduler

编写任务类:

 package com.wu.job;

 import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; @Component
public class MyJob {
@Scheduled(fixedRate=2000)//每两秒执行一次
public void run(){
System.out.println("执行作业");
}
}

MyJob.java

在启动类中开启任务调度

 package com.wu.app;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication(scanBasePackages={"com.wu.job"})
@EnableScheduling//开启任务调度
public class SpringApplications {
//程序启动入口
public static void main(String []args){
SpringApplication.run(SpringApplications.class, args);
}
}

启动类

结果:每隔2秒打印一次(v_v)

注意:在需要定时任务调度的方法上添加@Scheduled 注解;在启动类上加上 @EnableScheduling 扫描方法所在类的包

最新文章

  1. [Solution] 一步一步WCF(1) 快速入门
  2. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[2]--DIH
  3. Sublime Text 3配置与vim模式(待完整)
  4. HDU 5510 Bazinga 暴力匹配加剪枝
  5. Maven创建工程项目如何下载所需要的jar包
  6. 传输层-UDP
  7. Android第三方应用分享图文到微信朋友圈 &amp; 微信回调通知分享状态
  8. Mahout canopy聚类
  9. Java基础学习-常量和变量
  10. liteUploader上传控件的封装使用
  11. XBee模块户外通信距离测试
  12. github install
  13. Python - Windows系统下安装使用virtualenv
  14. SVN服务器搭建实录
  15. linux下apache中httpd.conf的ServerAdmin 是设置的什么?
  16. js深复制
  17. java中的数据结构[copy]
  18. EJB的魅惑来源
  19. SharpGL学习笔记(九) OpenGL的光照模型, 术语解释
  20. HDU 2719 The Seven Percent Solution (水题。。。)

热门文章

  1. 在Visual Studio2015中使用单元测试
  2. Qt Resource系统概说(资源压缩不压缩都可以)
  3. 原生Js封装的产品图片360度展示
  4. python列表的内置方法
  5. HTML连载9-video标签的第二种格式&amp;audio标签
  6. mogodbshell中数组对象查询修改方法
  7. Django框架之前端渲染-模板层
  8. C++程序设计1(侯捷video 7-13)
  9. ZooKeeper —— 单机环境和集群环境搭建
  10. VsCode 快捷键(Mac)