SpringBoot 静态资源访问
什么是静态资源?
- 静态资源类型:html、css、js、image等
- 动态资源类型:Servlet、JSP、Spring/Mybatis/Boot
SpringBoot对静态资源管理
在SpringBoot工程中,有几个默认约定的文件夹用于存放静态资源信息。(src/main/resources/)
- public 优先级最低
- static
- resources
- META-INF/resources 优先级最高
可以自定义静态资源目录,方法如下:
@Configuration
public class ResourcesConfiguration extends WebMvcConfigurerAdapter{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mystatic/**")
.addResourceLocations("classpath:/myresources/");
}
}
Thymeleaf模板技术
模板简介
velocity、freemark、thymeleaf技术都属于模板技术。
SpringBoot默认支持thymeleaf技术。
模板技术优点:
- 执行效率高于JSP
- 模板技术单一,易学、易用
SpringBoot Thymeleaf应用
thymeleaf模板技术,模板文件扩展名为.html,页面中需要使用th:xx表达式。编写时HTML模板页面,语法要求追加xmlns:th定义然后在使用th表达式。
<html xmlns:th="http://www.thymeleaf.org">xxxxxx
模板中的html标记比较严格,有开始和结束匹配。
SpringBoot有一个templates文件,是默认存放html模板文件位置。
案例1:Hello World
-
在pom.xml中追加thymeleaf定义
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
-
在src/main/resources目录下添加templates文件夹并追加hello.html模板文件
<html xmlns:th="http://www.thymeleaf.org"> <head> <title>thymeleaf示例</title> </head> <body> <h1 th:text="${msg}"></h1> </body> </html>
-
定义HelloController,将消息放入Model中
@Controller public class HelloController { @RequestMapping("/hello1.do") public ModelAndView hello1(){ ModelAndView mav = new ModelAndView(); mav.setViewName("hello"); mav.getModel().put("msg", "Hello Thymeleaf!"); return mav; } @RequestMapping("/hello2.do") public ModelAndView hello2(){ ModelAndView mav = new ModelAndView(); mav.setViewName("hello"); mav.getModel().put("msg", "你好模板技术!"); return mav; } }
案例2:列表显示
-
ListController
@Controller public class ListController { @RequestMapping("/list.do") public ModelAndView list(){ ModelAndView mav = new ModelAndView(); mav.setViewName("list");//templates/list.html List<City> list = new ArrayList<City>(); list.add(new City(1,"北京")); list.add(new City(2,"上海")); list.add(new City(3,"广州")); list.add(new City(4,"深圳")); mav.getModel().put("cities", list); return mav; } }
-
list.html模板文件
<html xmlns:th="http://www.thymeleaf.org"> <head> <title>thymeleaf示例</title> </head> <body> <h1>列表显示</h1> <table> <tr> <td>编号</td> <td>名称</td> </tr> <tr th:each="c:${cities}"> <td th:text="${c.id}"></td> <td th:text="${c.name}"></td> </tr> </table> <select> <option th:each="c:${cities}" th:value="${c.id}" th:text="${c.name}"></option> </select> </body>
案例3:重构列表分页案例
-
在pom.xml追加mybatis、jdbc等定义
<!-- jdbc --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- mybatis-spring --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.3</version> </dependency> <!-- ojdbc6 --> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </dependency>
-
在application.properties追加数据库参数定义
spring.datasource.username=SCOTT spring.datasource.password=TIGER spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE spring.datasource.driverClassName=oracle.jdbc.OracleDriver
-
定义实体类Book.java
-
定义Mapper接口BookDao.java
public interface BookDao { @Select("select * from xdl_book") public List<Book> findAll(); @Select("select * from xdl_book where id=#{id}") public Book findById(int id); @Delete("delete from xdl_book where id=#{id}") public int deleteById(int id); @Update("update xdl_book set author=#{author,jdbcType=VARCHAR},publishing=#{publishing,jdbcType=VARCHAR},publish_time=#{publish_time,jdbcType=DATE},isbn=#{isbn,jdbcType=VARCHAR},total_page=#{total_page,jdbcType=NUMERIC},book_summary=#{book_summary,jdbcType=VARCHAR} where id=#{id}") public int update(Book book); @Insert("insert into xdl_book (id,author,publishing,publish_time,total_page,book_summary) values (xdl_book_id_seq.nextval,#{author},#{publishing},#{publish_time},#{total_page},#{book_summary})") public int save(Book book); }
-
在主启动类前追加@MapperScanner标记
@SpringBootApplication @MapperScan(basePackages={"cn.xdl.dao"}) public class BootApplication { public static void main(String[] args){ SpringApplication.run(BootApplication.class, args); } }
-
定义BookController
@Controller public class BookController { @Autowired private BookDao bookDao; @RequestMapping("/book/page/{p}") public ModelAndView list(@PathVariable("p")int p){ ModelAndView mav = new ModelAndView(); mav.setViewName("book"); Page page = PageHelper.startPage(p,3); List<Book> list = bookDao.findAll(); int totalPage = page.getPages(); mav.getModel().put("books", list); mav.getModel().put("totalPage", totalPage); mav.getModel().put("currentPage", p); return mav; } @RequestMapping("/book/{id}/delete") public ModelAndView delete(@PathVariable("id")int id){ bookDao.deleteById(id); ModelAndView mav = new ModelAndView(); RedirectView view = new RedirectView("/book/page/1"); mav.setView(view); return mav; } }
-
在templates/下定义book.html模板文件
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <base href="/"/> <meta charset="UTF-8"/> <title>Insert title here</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="js/bootstrap.min.css"/> <!-- jQuery文件。务必在bootstrap.min.js 之前引入 --> <script type="text/javascript" src="js/jquery.min.js"></script> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script type="text/javascript" src="js/bootstrap.min.js"></script> </head> <body> <div class="container"> <h1>图书列表</h1> <button class="btn btn-info">新增</button> <table id="tb_book" class="table table-striped table-hover"> <tr class="danger"> <td>序号</td> <td>作者</td> <td>出版社</td> <td>出版时间</td> <td>总页数</td> <td>操作</td> </tr> <tr th:each="book,stat:${books}"> <td th:text="${stat.count}"></td> <td th:text="${book.author}"></td> <td th:text="${book.publishing}"></td> <td th:text="${book.publish_time}"></td> <td th:text="${book.total_page}"></td> <td> <a class="btn btn-danger" href="#">删除</a> </td> </tr> </table> <div id="pages"> <a th:each="p:${#numbers.sequence(1,totalPage)}" th:text="${p}" class="btn btn-warning" th:href="@{'book/page/'+${p}}"></a> </div> </div> </body> </html>
-
将jquery.js、css等文件放入static或public等静态资源目录下
-
禁用thymeleaf中HTML模板校验
-
在pom.xml中追加nekohtml定义
<dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> </dependency>
-
在application.properties追加参数
spring.thymeleaf.mode=LEGACYHTML5
-
SpringBoot AOP
-
在pom.xml中追加spring-boot-starter-aop定义
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
-
编写切面组件追加@Aspect、@Around定义
@Component @Aspect public class WatchBean { @Around("within(cn.xdl.controller.*)") public Object execute(ProceedingJoinPoint pjp) throws Throwable{ //追加前面逻辑 StopWatch watch = new StopWatch(); watch.start(); Object obj = pjp.proceed();//执行目标方法,获取返回结果 watch.stop(); long time = watch.getTotalTimeMillis();//执行时间 String method = pjp.getSignature().getName();//目标方法名 //追加后面逻辑 System.out.println(method+"方法执行了"+time+"ms"); return obj; } }
SpringBoot任务调度
启动服务器立刻调用任务
SpringBoot提供了CommandLineRunner和ApplicationRunner接口,程序猿可以实现接口及其方法,将启动任务写到方法中。
-
使用CommandLineRunner
@Component @Order(1) public class Task1Bean implements CommandLineRunner{ @Override public void run(String... args) throws Exception { System.out.println("启动服务器自动执行任务1"); } }
-
使用ApplicationRunner
@Component @Order(2) public class Task2Bean implements ApplicationRunner{ @Override public void run(ApplicationArguments args) throws Exception { System.out.println("启动服务器自动执行任务2"); } }
可以通过@Order标记定义任务执行顺序。
周期性定时调用任务
可以在服务器启动后,指定时间或周期调用执行任务处理。
-
定义任务类,类和方法定义没有限制
@Component//扫描@EnableScheduling//启用任务计划调度public class Task3Bean {
@Scheduled(cron="0/5 * * * * ?") public void execute(){ System.out.println("周期调用Task3任务:"+new Date()); }
}
-
根据需求指定@EnableScheduling和@Scheduled
-
编写cron表达式,参考下面资料