对Spring Web MVC封装,简化MVC结构web应用开发。
1. SpringBoot MVC开发Restful服务(前后分离)*
按rest规则发送HTTP请求–>Spring MVC–>返回JSON结果
主要步骤:
- 导入spring-boot-starter-web(springmvc、rest、jackson、tomcat)
- 在application.properties修改tomcat端口
- 定义启动类RunBoot,追加@SpringBootApplication
- 定义Controller、Service、Dao组件
2. SpringBoot MVC开发JSP应用(PC浏览器)
HTTP请求–>Spring MVC–>JSP–>HTML响应输出结果
主要步骤:
- 导入spring-boot-starter-web、jasper解析器、jstl
- 在application.properties修改tomcat端口、viewResolver
- 定义启动类RunBoot,追加@SpringBootApplication
- 定义Controller组件,返回ModelAndView
- 在src/main/webapp下定义JSP组件
3. SpringBoot MVC开发Thymeleaf应用(PC浏览器)*
HTTP请求–>Spring MVC–>Thymeleaf模板–>HTML响应输出结果
主要步骤:
- 导入spring-boot-starter-web、spring-boot-starter-thymeleaf
- 在application.properties修改tomcat端口
- 定义启动类RunBoot,追加@SpringBootApplication
- 定义Controller组件,返回ModelAndView
- 在src/main/resources/templates下定义模板文件
1
2
3
4<html xmlns:th="https://www.thymeleaf.org/">
<h1>Hello</h1>
<h2 th:text="${data}"></h2>
</html>- th:text表达式作用:将模型中的数据以只读文本显示到元素中
- th:text表达式作用:将模型中的数据以只读文本显示到元素中。
- th:if 表达式作用:if判断逻辑
- th:each 表达式作用:循环逻辑
- th:href 表达式作用:动态生成href链接
Thymeleaf模板和JSP区别
- 运行机制不同
- JSP–>Servlet–>HTML
- 模板+数据–>HTML输出
- 模板简单易用;JSP相对复杂些
- JSP:9大内置对象、EL、JSTL、嵌入Java代码、框架标签
- 模板:模板表达式
- 模板效率高,比JSP性能好
- 模板:缓存
4. SpringBoot MVC静态资源处理
静态资源包含图片、js、css等,动态资源servlet、jsp等。
SpringBoot中src/main/resources目录下有几个约定的静态资源存放位置
- META-INF/resources(优先级最高)
- resources
- static
- public(优先级最低)
自定义静态资源访问路径,编写一个配置文件
1 | //@Configuration |
5. SpringBoot MVC异常处理
异常处理机制
- SpringBoot底层提供了异常处理机制。SpringBoot提供了一个ErrorMvcAutoConfiguration自动配置组件,创建了一个BasicErrorController对象,提供两个/error请求处理,一个返回html,另一个返回json。当MVC底层遇到异常会用转发方式发出/error请求。
可以自定义ErrorController替代底层BasicErrorController,将错误提示转发到自定义提示界面(全局)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//@RequestMapping("/error")
public class MyErrorController implements ErrorController{
public ModelAndView errorHtml() {
ModelAndView mav = new ModelAndView();
mav.setViewName("myerror");
return mav;
}
public Object error(HttpServletRequest request) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("msg", "程序发生了异常");
return map;
}
public String getErrorPath() {
return "/error";
}
}@ExceptionHandler异常处理(局部)
- ErrorController管理全局异常,@ExceptionHandler管理所在Controller组件的异常。
1
2
3
4
5
6
7
8
public Object error(Exception ex) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("msg", "发生异常");
map.put("type", ex.getClass());
return map;
}
- ErrorController管理全局异常,@ExceptionHandler管理所在Controller组件的异常。
可以将上述方法封装成一个BasicController,通过@ControllerAdvice作用到所有Controller组件上。
1 | //等价于所有Controller都继承它 |
6. SpringBoot AOP
引入spring-boot-starter-aop
定义一个切面组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//将Bean组件纳入Spring容器
//将Bean组件定义为Aspect切面
public class MyAspectBean {
//前置通知
public void before() {
System.out.println("----开始处理----");
}
//最终通知
public void after() {
System.out.println("----处理完毕----");
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
StopWatch watch = new StopWatch();
watch.start();
Object obj = pjp.proceed();//调用目标组件方法
watch.stop();
System.out.println("处理时间:"+watch.getTotalTimeMillis()+" 毫秒");
return obj;
}
}配置切面组件
- @Aspect、@Before、@After、@Around、@AfterReturning、@AfterThrowing等
7. SpringBoot MVC拦截器
编写一个拦截器组件,实现HandlerInterceptor接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
System.out.println("执行了MyInterceptor拦截器");
String user = (String)request.getSession().getAttribute("user");
if(user == null) {
response.sendRedirect("/tologin");
return false;//阻止后续流程执行
}
return true;//继续执行后续处理
}
}配置拦截器组件
1
2
3
4
5
6
7
8
public class MyInterceptorConfiguration implements WebMvcConfigurer{
private MyInterceptor my;
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(my).addPathPatterns("/direction/list");
}
}
8. SpringBoot整合Servlet/Filter
8.1 整合Servlet
首先导入spring-boot-starter-web
8.1.1 整合Servlet方式一:
编写一个Servlet组件,继承HttpServlet
在Servlet类定义前使用@WebServlet
1
2
3
4
5
6
7
8
9
public class HelloServlet extends HttpServlet{
public void service(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
response.getWriter().println("Hello SpringBoot Servlet");
}
}启动类前需要使用@ServletComponentScan扫描@WebServlet配置
1
2
3
4
5
6
7
//扫描@WebServlet、@WebFilter、@WebListener组件
public class RunBoot {
public static void main(String[] args) {
SpringApplication.run(RunBoot.class, args);
}
}
8.1.2 整合Servlet方式二:
编写一个Servlet组件,继承HttpServlet
1
2
3
4
5
6
7
8public class SomeServlet extends HttpServlet {
public void service(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
response.getWriter().println("Hello Spring Some Servlet");
}
}使用ServletRegistrationBean+@Bean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class RunBoot {
public static void main(String[] args) {
SpringApplication.run(RunBoot.class, args);
}
public ServletRegistrationBean<Servlet> someservlet(){
ServletRegistrationBean<Servlet> bean = new ServletRegistrationBean<Servlet>();
bean.setServlet(new SomeServlet());
bean.setLoadOnStartup(1);
List<String> urls = new ArrayList<>();
urls.add("/some.do");
bean.setUrlMappings(urls);
return bean;
}
}
8.2 整合Filter
在SpringBoot整合Servlet的基础上整合Filter
8.2.1 整合Filter方式一:
编写一个Filter组件,继承Filter
在Filter类定义前使用@WebFilter
1
2
3
4
5
6
7
8
9
10
11
public class HelloFilter implements Filter{
public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain
) throws IOException, ServletException {
System.out.println("-----hello filter------servlet执行之前");
chain.doFilter(request, response);
System.out.println("-----hello filter------servlet执行之后");
}
}启动类前需要使用@ServletComponentScan扫描@WebServlet配置
1
2
3
4
5
6
7
//扫描@WebServlet、@WebFilter、@WebListener组件
public class RunBoot {
public static void main(String[] args) {
SpringApplication.run(RunBoot.class, args);
}
}
8.2.2 整合Filter方式二:
编写一个Filter组件,继承Filter
1
2
3
4
5
6
7
8
9
10public class SomeFilter implements Filter{
public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain
) throws IOException, ServletException {
System.out.println("-----som filter------servlet执行之前");
chain.doFilter(request, response);
System.out.println("-----som filter------servlet执行之后");
}
}使用FilterRegistrationBean+@Bean 注册过滤器并设置拦截的请求地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class RunBoot {
public static void main(String[] args) {
SpringApplication.run(RunBoot.class, args);
}
...
public FilterRegistrationBean<Filter> somefilter(){
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<Filter>();
bean.setFilter(new SomeFilter());
// 配置要拦截的请求
bean.addUrlPatterns("/some.do");
return bean;
}
}
9. SpringBoot 任务调度
9.1 服务器启动后自动调用
tomcat服务器启动后自动调用任务,可以使用ApplicationRunner或CommandLineRunner接口。
1 |
|
多个Task任务,可以通过@Order指定先后顺序,多个任务是线程同步调用。
9.2 程序运行后定时调用任务
Spring提供了一个Spring Schedule模块,封装了任务调用,之前都是采用Quartz组件调用。
1 |
|
使用Spring Schedule还需要指定cron表达式,表达式具体规则:
1 | 秒 分 时 日 月 星期 年(可省略) |
cron表达式案例:
1 | "30 * * * * ?" 每半分钟触发任务 |
9.3 SpringBoot+Quartz
导入spring-boot-starter-quartz, 编写Job任务组件,继承QuartzJobBean
1 | public class MyTask5 extends QuartzJobBean{ |
配置Job组件(JobDetail、Tigger)
1 |
|