一、环境

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. Java 面向对象和封装

    目录 面向对象思想的概述 类和对象的关系 什么是类 什么是对象 类和对象的关系 局部变量和成员变量的区别 this关键字 构造方法 一个标准的类 面向对象思想的概述 面向过程:当需要实现一个功能的时候 ...

  2. 使用 Minikube 安装 Kubernetes

    概述: 单机低配置主机也可以玩转kubernetes集群.该文章是将介绍使用Minikube安装Kubernetes集群(一般用于本地/开发环境). 配置环境: 硬件:CPU 至少2个核心,至少2.5 ...

  3. SpringMVC源码学习:容器初始化+MVC初始化+请求分发处理+参数解析+返回值解析+视图解析

    目录 一.前言 二.初始化 1. 容器初始化 根容器查找的方法 容器创建的方法 加载配置文件信息 2. MVC的初始化 文件上传解析器 区域信息解析器 handler映射信息解析 3. Handler ...

  4. 3、Hive-sql优化,数据倾斜处理

    一.Hive-sql优化 #增加reducer任务数量(拉取数量分流) ; #在同一个sql中的不同的job是否可以同时运行,默认为false set hive.exec.parallel=true; ...

  5. 【Hadoop离线基础总结】Hive的安装部署以及使用方式

    Hive的安装部署以及使用方式 安装部署 Derby版hive直接使用 cd /export/softwares 将上传的hive软件包解压:tar -zxvf hive-1.1.0-cdh5.14. ...

  6. 基于 groovy 实现公式库

    formula 基于 groovy 实现的公式库 项目地址 Github 语法 公式名(参数) 比如: ECHO(大侠王波波) 支持公式嵌套: 公式名1(公式名2(参数), 参数) 比如: ECHO( ...

  7. python语法学习第十天--类与对象相关的BIF、魔法方法

    一些相关的BIF: issubclass(class,classInfo)#判断是否为子类,classInfo可以为多个类的元组,其中一个是,返回true,一个类也被认为是自己的子类,object是所 ...

  8. 设计模式之GOF23代理模式01

    代理模式 核心作用: -通过代理,控制对对象的访问 -可以详细控制机制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做 后置处理(AOP的微观实现) 应用场景 -安全代理:屏蔽 ...

  9. js移动端复制到剪贴板

    // 复制到剪切板 function copy(str){ var save = function (e){ e.clipboardData.setData('text/plain',str);//c ...

  10. go 数组 字符串 切片

    数组 数组定义方式 var a [3]int // 定义长度为3的int型数组, 元素全部为0 var b = [...]int{1, 2, 3} // 定义长度为3的int型数组, 元素为 1, 2 ...