- Freemarker的作用就是将动态页面转换成伪的静态html页面,提高效率
使用Freemarker整合spring boot2
- 导入Freemarker的maven依赖的时候无需指明版本,因为Spring Boot的parent会自动做版本规范,自己提供了版本
- 因为我们的目的是要跳转页面所以不能使用@RestController应该是使用@Controller
- 后缀是==*.ftl==,默认会在resources下面的静态目录中找(如 static,templates)
- ftl取值也是用${}
整合JSP
- Springboot整合JSP不是很好,需要引入外部的支持,导入JSP的maven依赖
- 创建SpringBoot整合JSP的时候,一定要是war类型的,否则会找不到页面
- 不要把JSP的页面存放在resources目录下面,JSP页面编译之后不在class下,resources是做资源文件的,如果放下面可能会被直接访问到(JSP一般是不允许被直接访问到的),一般我们自己建立一个目录存放jsp文件
全局捕获异常
-
全部捕获异常的原理其实就是利用了AOP的技术,采用异常通知进行捕获
-
@ExceptionHandler表示拦截异常
(1)@ControllerAdvice是controller的一个辅助类,最常用的就是作为全局异常处理的切面类
(2)@ControllerAdvice可以指定扫描范围,利用其basePackages属性
(3)@ControllerAdvice约定了几种可行的返回值,如果是直接返回model类,需要使用@ResponseBody进行json转化
-----(3.1)返回String,表示跳转到某个view
-----(3.2)返回modelAndView
-----(3.3)返回model+@ResponseBody -
举例说明:
(1)在HelloController中写一个错误:
package com.xiyou.myspringboot.controller;
import org.springframework.boot.SpringApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String index() {
int i = 1/0;
return "Hello World!";
}
}
(2)定义全局异常处理器:
package com.xiyou.myspringboot.controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
/**
* 全局异常处理
*/
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public Map<String, Object> exceptionHandler(Exception e) {
System.out.println("错误信息: " + e.getMessage());
HashMap<String, Object> map = new HashMap<>();
map.put("errorCode", "101");
map.put("errorMsg", "系统错误");
return map;
}
}
其中捕捉异常的方法,可以有Exception对象,也可以不要
(3)返回结果:
错误信息: / by zero
SpringBoot整合log4j
- 我们SpringBoot自带的是logback的日志,要想使用log4j,应该先排除logback的日志,然后倒入log4j的日志:
- pom文件如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<!-- 排除自带的logback依赖 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- springboot-log4j -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
- 举例说明:利用@Lombok的@Slf4j完成切面日志:(不使用log4j的pom依赖)
(1)新增POM文件依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
(2)新增AOP
package com.xiyou.myspringboot.aop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* 利用AOP实现全局日志管理器
*/
@Aspect
@Component
@Slf4j
public class WebLogAspect {
/**
* 定义切点
*/
@Pointcut("execution(public * com.xiyou.myspringboot.controller.*.*(..))")
public void webLog(){
}
/**
* 做一个前置通知(进入方法之前会进入这个方法,这个方法在环绕通知之前执行)
*/
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 得到请求
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录请求的内容
log.info("URL : " + request.getRequestURL().toString());
}
/**
* 定义一个执行成功后的通知
*/
@AfterReturning("webLog()")
public void doAfterReturning(JoinPoint joinPoint) throws Throwable {
log.info("执行完成: " + joinPoint);
}
}
(3)显示结果:
执行结果:
2019-09-19 09:44:49.094 INFO 38492 --- [nio-8081-exec-1] com.xiyou.myspringboot.aop.WebLogAspect : URL : http://localhost:8081/hi
2019-09-19 09:44:49.108 INFO 38492 --- [nio-8081-exec-1] com.xiyou.myspringboot.aop.WebLogAspect : 执行完成: execution(String com.xiyou.myspringboot.controller.HiController.sayHi())
lombok插件
- lombok插件底层使用ASM字节码技术(CGLIB)也是使用该技术,修改字节码文件,自己生成get和set方法
- 依赖的pom文件是:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
@async进行异步调用
-
@async异步调用的原理是利用AOP技术底层创建多线程去调用该方法,在方法上加
(1)在service层写一个用于异步调用的方法(最好是一个独立的类,因为要生成动态代理)
(2)在指定的方法上标明@Async表示异步执行
(3)在启动类上加上@EnableAsync -
程序演示:
(1)pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
(2)controller
@RestController
@Slf4j
public class IndexController {
@Autowired
private UserService userService;
@RequestMapping("/index")
public String index() {
log.info("##01##");
userService.userThread();
log.info("##04##");
return "success";
}
}
(3)service
@Service
@Slf4j
public class UserService {
@Async // 类似与开启线程执行..
public void userThread() {
log.info("##02##");
try {
Thread.sleep(5 * 1000);
} catch (Exception e) {
// TODO: handle exception
}
log.info("##03##");
}
}
(4)主启动类
@EnableAsync // 开启异步注解
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
自定义参数@Value
- @value写在字段上,一般用于给变量初始化
- 项目启动的时候就加载配置文件,进行赋值了
- @Value是通过取application.propertires的值进行赋值操作的
- 举例说明:
(1)application.properties
name=itmayiedu.com
(2)Controller类进行读取
@Value("${name}")
private String name;
@ResponseBody
@RequestMapping("/getValue")
public String getValue() {
return name;
}
不同环境区分不同环境配置文件
- 一般将环境分为开发(dev),测试(test),生产环境(prod),生产环境的配置文件只能由运维修改
- 一般是在resources目录下新建文件application-XXX.properties ,比如:
(1)application-dev.properties :开发环境
(2)application-test.properties : 测试环境
(3)application-prod.properties : 生产环境 - 在application.properties通过命令spring.profiles.active=pre来指定哪一个配置文件生效