一、环境

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属性识别不同环境配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration> <include resource="org/springframework/boot/logging/logback/base.xml"/> <!-- logger name="org.springframework" level="DEBUG"/--> </configuration>
配置默认application.properties
# Allow Thymeleaf templates to be reloaded at dev time
spring.thymeleaf.cache: false
server.tomcat.access_log_enabled: true
server.tomcat.basedir: target/tomcat
 
配置message.properties
form.message=Message
form.messages=Messages
form.submit=Submit
form.summary=Summary
form.title=Messages : Create list.create=Create Message
list.table.created=Created
list.table.empty=No messages
list.table.id=Id
list.table.summary=Summary
list.title=Messages : View all navbar.messages=Messages
navbar.thymeleaf=Thymeleaf view.delete=delete
view.messages=Messages
view.modify=modify
view.success=Successfully created a new message
view.title=Messages : View

添加css样式文件
/static/css/bootstrap.min.css
添加页面文件
templates/fragments.html
templates/messages/form.html
templates/messages/list.html
templates/messages/view.html
添加实体类
package org.ouyushan.springboot.web.thymeleaf.entity;

import javax.validation.constraints.NotEmpty;
import java.util.Calendar; /**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/4/29 14:33
*/
public class Message { private Long id; @NotEmpty(message = "Text is required.")
private String text; @NotEmpty(message = "Summary is required.")
private String summary; private Calendar created = Calendar.getInstance(); public Long getId() {
return this.id;
} public void setId(Long id) {
this.id = id;
} public Calendar getCreated() {
return this.created;
} public void setCreated(Calendar created) {
this.created = created;
} public String getText() {
return this.text;
} public void setText(String text) {
this.text = text;
} public String getSummary() {
return this.summary;
} public void setSummary(String summary) {
this.summary = summary;
} }
添加repository接口
package org.ouyushan.springboot.web.thymeleaf.repository;

import org.ouyushan.springboot.web.thymeleaf.entity.Message;

/**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/4/29 14:35
*/
public interface MessageRepository { Iterable<Message> findAll(); Message save(Message message); Message findMessage(Long id); void deleteMessage(Long id); }
添加repository实体类
package org.ouyushan.springboot.web.thymeleaf.repository;

import org.ouyushan.springboot.web.thymeleaf.entity.Message;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong; /**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/4/29 14:38
*/
public class InMemoryMessageRepository implements MessageRepository{
private static AtomicLong counter = new AtomicLong(); private final ConcurrentMap<Long, Message> messages = new ConcurrentHashMap<>(); @Override
public Iterable<Message> findAll() {
return this.messages.values();
} @Override
public Message save(Message message) {
Long id = message.getId();
if (id == null) {
id = counter.incrementAndGet();
message.setId(id);
}
this.messages.put(id, message);
return message;
} @Override
public Message findMessage(Long id) {
return this.messages.get(id);
} @Override
public void deleteMessage(Long id) {
this.messages.remove(id);
}
}

添加controller类
package org.ouyushan.springboot.web.thymeleaf.controller;

import org.ouyushan.springboot.web.thymeleaf.entity.Message;
import org.ouyushan.springboot.web.thymeleaf.repository.MessageRepository;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.validation.Valid; /**
* @Description:
* @Author: ouyushan
* @Email: ouyushan@hotmail.com
* @Date: 2020/4/29 14:42
*/
@Controller
@RequestMapping("/")
public class MessageController { private final MessageRepository messageRepository; public MessageController(MessageRepository messageRepository) {
this.messageRepository = messageRepository;
} @GetMapping
public ModelAndView list() {
Iterable<Message> messages = this.messageRepository.findAll();
return new ModelAndView("messages/list", "messages", messages);
} @GetMapping("{id}")
public ModelAndView view(@PathVariable("id") Message message) {
return new ModelAndView("messages/view", "message", message);
} @GetMapping(params = "form")
public String createForm(@ModelAttribute Message message) {
return "messages/form";
} @PostMapping
public ModelAndView create(@Valid Message message, BindingResult result, RedirectAttributes redirect) {
if (result.hasErrors()) {
return new ModelAndView("messages/form", "formErrors", result.getAllErrors());
}
message = this.messageRepository.save(message);
redirect.addFlashAttribute("globalMessage", "view.success");
return new ModelAndView("redirect:/{message.id}", "message.id", message.getId());
} @RequestMapping("foo")
public String foo() {
throw new RuntimeException("Expected exception in controller");
} @GetMapping("delete/{id}")
public ModelAndView delete(@PathVariable("id") Long id) {
this.messageRepository.deleteMessage(id);
Iterable<Message> messages = this.messageRepository.findAll();
return new ModelAndView("messages/list", "messages", messages);
} @GetMapping("modify/{id}")
public ModelAndView modifyForm(@PathVariable("id") Message message) {
return new ModelAndView("messages/form", "message", message);
} }

启动程序类
package org.ouyushan.springboot.web.thymeleaf;

import org.ouyushan.springboot.web.thymeleaf.entity.Message;
import org.ouyushan.springboot.web.thymeleaf.repository.InMemoryMessageRepository;
import org.ouyushan.springboot.web.thymeleaf.repository.MessageRepository;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.convert.converter.Converter; @SpringBootApplication
public class SpringBootWebThymeleafApplication { @Bean
public MessageRepository messageRepository() {
return new InMemoryMessageRepository();
} @Bean
public Converter<String, Message> messageConverter() {
return new Converter<String, Message>() {
@Override
public Message convert(String id) {
return messageRepository().findMessage(Long.valueOf(id));
}
};
} public static void main(String[] args) {
SpringApplication.run(SpringBootWebThymeleafApplication.class, args);
} }

五、接口测试

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

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. [计算机视觉]从零开始构建一个微软how-old.net服务/面部属性识别

    大概两三年前微软发布了一个基于Cognitive Service API的how-old.net网站,用户可以上传一张包含人脸的照片,后台通过调用深度学习算法可以预测照片中的人脸.年龄以及性别,然后将 ...

  2. Oracle条件判断

    一. if/else 语法:if 条件表达式 then语句块:if 条件表达式 then 语句块end if;elsif 条件表达式 then语句块:...else语句块:end if;举例:输入一个 ...

  3. Anaconda 常用命令大全

    帮助目录 检查conda版本 升级当前版本的conda 创建一个新环境 激活新环境 Linux,Mac: Windows: 列出所有的环境 切换环境(activate/deactivate) Linu ...

  4. React Native超简单完整示例-tabs、页面导航、热更新、用户行为分析

    初学React Native,如果没有人指引,会发现好多东西无从下手,但当有人指引后,会发现其实很简单.这也是本人写这篇博客的主要原因,希望能帮到初学者. 本文不会介绍如何搭建开发环境,如果你还没有搭 ...

  5. lambda表达式入门详解

    转自 2018-03-02 Sevenvidia 码农翻身 1.什么是Lambda? 我们知道,对于一个Java变量,我们可以赋给其一个"值".   如果你想把"一块代码 ...

  6. Python Serial 串口基本操作(收发数据)

    1.需要模块以及测试工具 模块名:pyserial 使用命令下载:python -m pip install pyserial 串口调试工具:sscom5.13.1.exe 2.导入模块 import ...

  7. Android 8.1 关机充电动画(一)模式选择

    system:Android 8.1 platform:RK3326/PX30 uboot kernel Android 8.1 关机充电动画(一)模式选择 Android 8.1 关机充电动画(二) ...

  8. Git使用教程之新手也能看懂(一)

    首先我写这篇文章的初衷是因为 有一段时间没用Git了,现在突然用起来,很多命令都忘记了,导致去上网查了各种资料和文档(其中廖雪峰老师的文章给我的帮助很大,非常感谢!),花费了大量的时间,等于是又重新学 ...

  9. Android将库导入到build.gradle

    如图

  10. jsp 中文乱码????解决

    中文乱码是个非常蛋疼的问题,在页面表单提交的时候后台获取数据变成了????,解决方案如下: 1:确认编码都是一致的如页面和后台都设置为utf-8 2:String str = new String(r ...