一、环境

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. 学习vue第六节,v-if和v-show

    vue 中的v-if和v-show <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  2. HTML data-* 属性的含义和使用

      data-*自定义数据属性 首先讲一下语法格式: data-* =“值” data-* 属性包括两部分: 属性名不应该包含任何大写字母,并且在前缀 "data-" 之后必须有至 ...

  3. 这是一篇每个人都能读懂的最小生成树文章(Kruskal)

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法和数据结构专题的第19篇文章,我们一起来看看最小生成树. 我们先不讲算法的原理,也不讲一些七七八八的概念,因为对于初学者来说,看到 ...

  4. iOS开发--性能调优记录

    CPU VS GPU 关于绘图和动画有两种处理的方式:CPU(中央处理器)和GPU(图形处理器).但是由于历史原因,我们可以说CPU所做的工作都在软件层面,而GPU在硬件层面 对于图像处理,通常用硬件 ...

  5. xml(4)

    schema约束 dtd语法:<!ELEMENT 元素名称 约束> schema符合xml的语法,xml语句 一个xml中可以有多个schema,多个schema用名称空间区分(类似jav ...

  6. [NBUT 1458 Teemo]区间第k大问题,划分树

    裸的区间第k大问题,划分树搞起. #pragma comment(linker, "/STACK:10240000") #include <map> #include ...

  7. 内网穿透访问Vue项目的时候出现Invalid Host header解决办法

    适用场景: 在本地的Vue-cli3项目, 需要其他人浏览. 如果没有外网的服务器, 可以把自己的电脑当做服务器. 这时候需要外网的人能访问到自己的电脑. Mac内网穿透工具:natapp Inval ...

  8. webpack3 项目升级 webpack4

    由于 vue-cli 2 构建的项目是基于 webpack3,所以只能自己动手改动,至于升级 webpack4之后提升的编译速度以及各种插件自己去体验. 修改配置 1.替换插件 extract-tex ...

  9. Apache Poi实现excel解析

    一.说明 1.本文通过使用 poi 工具解析 excel 表格数据,实现导入导出 2.excel目前有两种格式 2003版本的 excel.xls 与 2007版本的 excel.xlsx ,注意两种 ...

  10. Web_php_include-攻防世界

    0x00 简介 记录这个题纯粹是为了记录以下有关strstr()函数的相关知识. 0x01 题目 <?php show_source(__FILE__); echo $_GET['hello'] ...