一、环境

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. LTE基站开局流程脚本的具体含义

    1.全局参数配置MOD ENODEB(修改基站): ENODEBID=2015(基站标识2015), NAME="安职-1"(基站名称), ENBTYPE=DBS3900_LTE( ...

  2. Go语言入门教程系列——函数、循环与分支

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Golang专题的第四篇,这一篇文章将会介绍golang当中的函数.循环以及选择判断的具体用法. 函数 在之前的文章当中其实我们已经接 ...

  3. 【HBase】通过Bulkload批量加载数据到Hbase表中

    目录 需求 步骤 一.开发MapReduce 二.打成Jar包放到linux执行 三.有两种办法将HFile文件加载到HBase表中 开发代码 Hadoop命令运行 需求 将hdfs上面的这个路径 / ...

  4. [UVA Live 12931 Common Area]扫描线

    题意:判断两个多边形是否有面积大于0的公共部分 思路:扫描线基础. #pragma comment(linker, "/STACK:10240000") #include < ...

  5. JUC(3)---CountDownLatch、CyclicBarrier和AQS

    CountDownLatch可以让一个线程等待其他线程完成了各自的工作之后再执行.比如说一个切菜,一个人切肉,都准备完毕之后才能炒肉. 构造方法: public CountDownLatch(int ...

  6. UEFI Shell --常用命令解释

    UEFI Shell解释 UEFI Shell 是一个提供用户和UEFI系统之间的接口,进入UEFI Shell可以对计算机系统进行配置 命令解释: 单独的help就可以输出所有指令,不做特殊说明,内 ...

  7. ScrollView 内嵌百度地图问题解决

    在ScrollView上内嵌百度地图遇到两个问题 事件冲突,移动地图的时候屏幕滚动了 移动ScrollView的时候,百度地图出现黑边 问题1的处理就有各种办法了,核心都是拦截事件,我使用的办法是加一 ...

  8. 数据结构----二叉树Tree和排序二叉树

    二叉树 节点定义 class Node(object): def __init__(self, item): self.item = item self.left = None self.right ...

  9. servlet--http接口简单的创建及调用

    很久没有用servlet的交互技术,生疏的遭不住.现在简单的说说servlet中http接口的创建及调用,便于大家理解,使用. 先说说服务端,就是提供服务方的代码: pom.xml <depen ...

  10. vue打包时semver.js版本报错

    如图,报错semver.js版本不正确,解决思路是在node_modules/semver.js内,忽略版本检查 ''' // if ANY of the sets match ALL of its ...