一、环境

1.1、Idea 2020.1

1.2、JDK 1.8

二、目的

spring boot 整合thymeleaf模板开发web项目

三、步骤

3.1、点击File -> New Project -> Spring Initializer,点击next

3.2、在对应地方修改自己的项目信息

3.3、选择Web依赖,选中Spring Web。可以选择Spring Boot版本,本次默认为2.2.6,点击Next

3.4、项目结构

 
四、添加配置文件

添加配置文件logback.xml 通过springProfile属性识别不同环境配置
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3.  
  4. <include resource="org/springframework/boot/logging/logback/base.xml"/>
  5.  
  6. <!-- logger name="org.springframework" level="DEBUG"/-->
  7.  
  8. </configuration>
配置默认application.properties
  1. # Allow Thymeleaf templates to be reloaded at dev time
  2. spring.thymeleaf.cache: false
  3. server.tomcat.access_log_enabled: true
  4. server.tomcat.basedir: target/tomcat
  1.  
配置message.properties
  1. form.message=Message
  2. form.messages=Messages
  3. form.submit=Submit
  4. form.summary=Summary
  5. form.title=Messages : Create
  6.  
  7. list.create=Create Message
  8. list.table.created=Created
  9. list.table.empty=No messages
  10. list.table.id=Id
  11. list.table.summary=Summary
  12. list.title=Messages : View all
  13.  
  14. navbar.messages=Messages
  15. navbar.thymeleaf=Thymeleaf
  16.  
  17. view.delete=delete
  18. view.messages=Messages
  19. view.modify=modify
  20. view.success=Successfully created a new message
  21. view.title=Messages : View
  1.  
添加css样式文件
/static/css/bootstrap.min.css
添加页面文件
templates/fragments.html
templates/messages/form.html
templates/messages/list.html
templates/messages/view.html
添加实体类
  1. package org.ouyushan.springboot.web.thymeleaf.entity;
  2.  
  3. import javax.validation.constraints.NotEmpty;
  4. import java.util.Calendar;
  5.  
  6. /**
  7. * @Description:
  8. * @Author: ouyushan
  9. * @Email: ouyushan@hotmail.com
  10. * @Date: 2020/4/29 14:33
  11. */
  12. public class Message {
  13.  
  14. private Long id;
  15.  
  16. @NotEmpty(message = "Text is required.")
  17. private String text;
  18.  
  19. @NotEmpty(message = "Summary is required.")
  20. private String summary;
  21.  
  22. private Calendar created = Calendar.getInstance();
  23.  
  24. public Long getId() {
  25. return this.id;
  26. }
  27.  
  28. public void setId(Long id) {
  29. this.id = id;
  30. }
  31.  
  32. public Calendar getCreated() {
  33. return this.created;
  34. }
  35.  
  36. public void setCreated(Calendar created) {
  37. this.created = created;
  38. }
  39.  
  40. public String getText() {
  41. return this.text;
  42. }
  43.  
  44. public void setText(String text) {
  45. this.text = text;
  46. }
  47.  
  48. public String getSummary() {
  49. return this.summary;
  50. }
  51.  
  52. public void setSummary(String summary) {
  53. this.summary = summary;
  54. }
  55.  
  56. }
添加repository接口
  1. package org.ouyushan.springboot.web.thymeleaf.repository;
  2.  
  3. import org.ouyushan.springboot.web.thymeleaf.entity.Message;
  4.  
  5. /**
  6. * @Description:
  7. * @Author: ouyushan
  8. * @Email: ouyushan@hotmail.com
  9. * @Date: 2020/4/29 14:35
  10. */
  11. public interface MessageRepository {
  12.  
  13. Iterable<Message> findAll();
  14.  
  15. Message save(Message message);
  16.  
  17. Message findMessage(Long id);
  18.  
  19. void deleteMessage(Long id);
  20.  
  21. }
添加repository实体类
  1. package org.ouyushan.springboot.web.thymeleaf.repository;
  2.  
  3. import org.ouyushan.springboot.web.thymeleaf.entity.Message;
  4.  
  5. import java.util.concurrent.ConcurrentHashMap;
  6. import java.util.concurrent.ConcurrentMap;
  7. import java.util.concurrent.atomic.AtomicLong;
  8.  
  9. /**
  10. * @Description:
  11. * @Author: ouyushan
  12. * @Email: ouyushan@hotmail.com
  13. * @Date: 2020/4/29 14:38
  14. */
  15. public class InMemoryMessageRepository implements MessageRepository{
  16. private static AtomicLong counter = new AtomicLong();
  17.  
  18. private final ConcurrentMap<Long, Message> messages = new ConcurrentHashMap<>();
  19.  
  20. @Override
  21. public Iterable<Message> findAll() {
  22. return this.messages.values();
  23. }
  24.  
  25. @Override
  26. public Message save(Message message) {
  27. Long id = message.getId();
  28. if (id == null) {
  29. id = counter.incrementAndGet();
  30. message.setId(id);
  31. }
  32. this.messages.put(id, message);
  33. return message;
  34. }
  35.  
  36. @Override
  37. public Message findMessage(Long id) {
  38. return this.messages.get(id);
  39. }
  40.  
  41. @Override
  42. public void deleteMessage(Long id) {
  43. this.messages.remove(id);
  44. }
  45. }
  1.  
添加controller类
  1. package org.ouyushan.springboot.web.thymeleaf.controller;
  2.  
  3. import org.ouyushan.springboot.web.thymeleaf.entity.Message;
  4. import org.ouyushan.springboot.web.thymeleaf.repository.MessageRepository;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.validation.BindingResult;
  7. import org.springframework.web.bind.annotation.*;
  8. import org.springframework.web.servlet.ModelAndView;
  9. import org.springframework.web.servlet.mvc.support.RedirectAttributes;
  10.  
  11. import javax.validation.Valid;
  12.  
  13. /**
  14. * @Description:
  15. * @Author: ouyushan
  16. * @Email: ouyushan@hotmail.com
  17. * @Date: 2020/4/29 14:42
  18. */
  19. @Controller
  20. @RequestMapping("/")
  21. public class MessageController {
  22.  
  23. private final MessageRepository messageRepository;
  24.  
  25. public MessageController(MessageRepository messageRepository) {
  26. this.messageRepository = messageRepository;
  27. }
  28.  
  29. @GetMapping
  30. public ModelAndView list() {
  31. Iterable<Message> messages = this.messageRepository.findAll();
  32. return new ModelAndView("messages/list", "messages", messages);
  33. }
  34.  
  35. @GetMapping("{id}")
  36. public ModelAndView view(@PathVariable("id") Message message) {
  37. return new ModelAndView("messages/view", "message", message);
  38. }
  39.  
  40. @GetMapping(params = "form")
  41. public String createForm(@ModelAttribute Message message) {
  42. return "messages/form";
  43. }
  44.  
  45. @PostMapping
  46. public ModelAndView create(@Valid Message message, BindingResult result, RedirectAttributes redirect) {
  47. if (result.hasErrors()) {
  48. return new ModelAndView("messages/form", "formErrors", result.getAllErrors());
  49. }
  50. message = this.messageRepository.save(message);
  51. redirect.addFlashAttribute("globalMessage", "view.success");
  52. return new ModelAndView("redirect:/{message.id}", "message.id", message.getId());
  53. }
  54.  
  55. @RequestMapping("foo")
  56. public String foo() {
  57. throw new RuntimeException("Expected exception in controller");
  58. }
  59.  
  60. @GetMapping("delete/{id}")
  61. public ModelAndView delete(@PathVariable("id") Long id) {
  62. this.messageRepository.deleteMessage(id);
  63. Iterable<Message> messages = this.messageRepository.findAll();
  64. return new ModelAndView("messages/list", "messages", messages);
  65. }
  66.  
  67. @GetMapping("modify/{id}")
  68. public ModelAndView modifyForm(@PathVariable("id") Message message) {
  69. return new ModelAndView("messages/form", "message", message);
  70. }
  71.  
  72. }
  1.  
启动程序类
  1. package org.ouyushan.springboot.web.thymeleaf;
  2.  
  3. import org.ouyushan.springboot.web.thymeleaf.entity.Message;
  4. import org.ouyushan.springboot.web.thymeleaf.repository.InMemoryMessageRepository;
  5. import org.ouyushan.springboot.web.thymeleaf.repository.MessageRepository;
  6. import org.springframework.boot.SpringApplication;
  7. import org.springframework.boot.autoconfigure.SpringBootApplication;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.core.convert.converter.Converter;
  10.  
  11. @SpringBootApplication
  12. public class SpringBootWebThymeleafApplication {
  13.  
  14. @Bean
  15. public MessageRepository messageRepository() {
  16. return new InMemoryMessageRepository();
  17. }
  18.  
  19. @Bean
  20. public Converter<String, Message> messageConverter() {
  21. return new Converter<String, Message>() {
  22. @Override
  23. public Message convert(String id) {
  24. return messageRepository().findMessage(Long.valueOf(id));
  25. }
  26. };
  27. }
  28.  
  29. public static void main(String[] args) {
  30. SpringApplication.run(SpringBootWebThymeleafApplication.class, args);
  31. }
  32.  
  33. }

五、接口测试

  1. 访问:
  2. http://localhost:8080/?form
  3. ### Controller
  4. * 使用了@PathVariable 从路径中获取参数,注入参数中必须有一属性名称与PathVariable变量名称相同
  5. * 使用params处理路径中请求参数
  6. * 使用@Valid校验参数,BindingResult 存储校验错误,RedirectAttributes 缓存上级页面参数
  7.  
  8. ### repository
  9.  
  10. * 利用ConcurrentHashMap模拟线程安全数据库
  11. private static AtomicLong counter = new AtomicLong();
  12. private final ConcurrentMap<Long,Message> messages = new ConcurrentHashMap<>();
  13.  
  14. ### application启动配置类
  15. * 定义了messageRepository bean以及messageConverter bean
  16. * @SpringBootApplication same as @Configuration @EnableAutoConfiguration @ComponentScan
  17.  
  18. post方式 create
  19. localhost:8080?id=1&text=text&summary=summary
  20.  
  21. get查询id=1
  22. http://localhost:8080/1
  23.  
  24. @GetMapping(params = "form")
  25. localhost:8080?form=&id=1
  26.  
  27. localhost:8080?form=&id=1&text=text&summary=summary
  28.  
  29. ```
  30. ${} 变量表达式(美元表达式,哈哈),用于访问容器上下文环境中的变量,功能同jstl中${}。
  31. *{} 选择表达式(星号表达式)。选择表达式与变量表达式有一个重要的区别:选择表达式计算的是选定的对象,而不是整个环境变量映射
  32. #{} 消息表达式(井号表达式,properties资源表达式)。通常与th:text属性一起使用,指明声明了th:text的标签的文本是#{}中的key所对应的value,而标签内的文本将不会显示
  33. @{} 超链接url表达式
  34. #maps 工具对象表达式。常用于日期、集合、数组对象的访问
  35. #dates
  36. #calendars
  37. #numbers
  38. #strings
  39. #objects
  40. #bools
  41. #arrays
  42. #lists
  43. #sets
  44.  
  45. ```

Spring boot Sample 009之spring-boot-web-thymeleaf的更多相关文章

  1. Spring Boot——2分钟构建spring web mvc REST风格HelloWorld

    之前有一篇<5分钟构建spring web mvc REST风格HelloWorld>介绍了普通方式开发spring web mvc web service.接下来看看使用spring b ...

  2. [转]Spring Boot——2分钟构建spring web mvc REST风格HelloWorld

    Spring Boot——2分钟构建spring web mvc REST风格HelloWorld http://projects.spring.io/spring-boot/ http://spri ...

  3. [转]通过Spring Boot三分钟创建Spring Web项目

    来源:https://www.tianmaying.com/tutorial/project-based-on-spring-boot Spring Boot简介 接下来我们所有的Spring代码实例 ...

  4. 跟我学Spring Boot(三)Spring Boot 的web开发

    1.Web开发中至关重要的一部分,Web开发的核心内容主要包括内嵌Servlet容器和SpringMVC spring boot  提供了spring-boot-starter-web 为web开发提 ...

  5. spring boot:创建一个简单的web(maven web project)

    1.新建一个maven web project; 2.在pom.xml文件中添加相应的依赖包: 3.新建一个HelloController请求控制类: 4.编写index.jsp页面: 5.编写启动类 ...

  6. 46. Spring Boot中使用AOP统一处理Web请求日志

    在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...

  7. Spring Boot (二):模版引擎 Thymeleaf 渲染 Web 页面

    Spring Boot (二):模版引擎 Thymeleaf 渲染 Web 页面 在<Spring Boot(一):快速开始>中介绍了如何使用 Spring Boot 构建一个工程,并且提 ...

  8. Spring Boot-初学01 -使用Spring Initializer快速创建Spring Boot项目 -@RestController+spEL -实现简单SpringBoot的Web页面

    1.IDEA:使用 Spring Initializer快速创建项目 IDE都支持使用Spring的项目创建向导快速创建一个Spring Boot项目: 选择我们需要的模块:向导会联网创建Spring ...

  9. Spring boot Sample 012之spring-boot-web-upload

    一.环境 1.1.Idea 2020.1 1.2.JDK 1.8 二.目的 spring boot 整合web实现文件上传下载 三.步骤 3.1.点击File -> New Project -& ...

随机推荐

  1. 【Hadoop离线基础总结】网站流量日志数据分析系统

    目录 点击流数据模型 概述 点击流模型 网站流量分析 网站流量模型分析 网站流量来源 网站流量多维度细分 网站内容及导航分析 网站转化及漏斗分析 流量常见分析角度和指标分类 指标概述 指标分类 分析角 ...

  2. STM32 基于 CubeMX配置GPIO点亮LED灯(超级详细+图文并茂)

    我是一个只会点灯的菜鸟: 相关文章 [STM32系列汇总]小白博主的STM32实战快速进阶之路(持续更新) 文章目录 相关文章 1 前言 2 理论分析 2.1 LED 原理 2.2 板载资料 2.3 ...

  3. 24款WordPress网站AI插件大盘点

    ------------恢复内容开始------------ 你想把AI(人工智能)技术和机器学习技术添加到自己的WordPress网站吗?本文中,我会分享24个利用AI技术和机器学习技术的WordP ...

  4. [hdu5316]线段树

    题意:给一个array,有两种操作,(1)修改某一个位置的值,(2)询问区间[L,R]内的最大子段和,其中子段需满足相邻两个数的位置的奇偶性不同 思路:假设对于询问操作没有奇偶性的限制,那么记录区间的 ...

  5. [hdu1023]递推

    http://acm.hdu.edu.cn/showproblem.php?pid=1023 如果把栈里面的元素个数表示成状态,每一步(共2 * n步)的状态构成的状态序列的种数就是答案,令dp[i] ...

  6. 关于jquery样式切换的一些想法

    前一阵子写了一些代码,都是关于一个按钮点击切换状态的按钮,当时没有想周到就用addClass removeClass来控制这个控件的状态,后来想想觉得不妥. <html> <head ...

  7. 1013 Battle Over Cities (25分) 图的连通分量+DFS

    题目 It is vitally important to have all the cities connected by highways in a war. If a city is occup ...

  8. codingame

    无聊登了一下condingame,通知说有本周谜题,正好刚撸完bfs,想尝试下. 题目链接:https://www.codingame.com/ide/17558874463b39b9ce6d4207 ...

  9. 5、打断点(bpu)

    前言 先给大家讲一则小故事,在我们很小的时候是没有手机的,那时候跟女神聊天都靠小纸条.某屌丝A男对隔壁小王的隔壁女神C倾慕已久,于是天天小纸条骚扰,无奈中间隔着一个小王,这样小王就负责传小纸条了.有一 ...

  10. node 之 ... 扩展运算符报错

    使用pm2的遇到的问题:(实际上是 node 版本不一致导致的问题) 描述:sudo 下的node版本和 全局下的node版本不一致导致...扩展运算符报错. 实例: { "apps&quo ...