架构实战篇(四):Spring Boot整合 Thymeleaf

前言

Thymeleaf 是一种模板语言。那模板语言或模板引擎是什么?常见的模板语言都包含以下几个概念:数据(Data)、模板(Template)、模板引擎(Template Engine)和结果文档(Result Documents)。

Spring boot 支持多种模板语言(Thymeleaf 、Freemarker、Mustache、Groovy Templates)
Thymeleaf 跟大部分的模板语言类似,上手容易,使用简单

我们先看下已经完成的项目结构图

架构实战篇(四):Spring Boot整合 Thymeleaf_第1张图片
项目结构

最终运行结果

架构实战篇(四):Spring Boot整合 Thymeleaf_第2张图片
最终运行结果

下面开始一步一步的编写代码了

增加Spring boot的maven 依赖

在原有基础的pom结构中追加Swagger2的依赖



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        1.5.10.RELEASE
    
    com.example
    spring-boot-web-thymeleaf
    1.0-SNAPSHOT

    
        1.8
    

    
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

增加一个消息类

package sample.web.ui;
import java.util.Calendar;
import org.hibernate.validator.constraints.NotEmpty;

public class Message {

    private Long id;

    // 编写不能为空的提示语
    @NotEmpty(message = "Message is required.")
    private String text;

    // 编写不能为空的提示语
    @NotEmpty(message = "Summary is required.")
    private String summary;

    private Calendar created = Calendar.getInstance();

        // get set
}

保存消息的接口

package sample.web.ui;

public interface MessageRepository {
    Iterable findAll();
    Message save(Message message);
    Message findMessage(Long id);
    void deleteMessage(Long id);
}

使用内存保存消息

package sample.web.ui;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

public class InMemoryMessageRepository implements MessageRepository {

    // 用来模拟主键自增
    private static AtomicLong counter = new AtomicLong();

    // 用来存储消息
    private final ConcurrentMap messages = new ConcurrentHashMap();

    @Override
    public Iterable findAll() {
        return this.messages.values();
    }

    @Override
    public Message save(Message message) {
        Long id = message.getId();
        if (id == null) {
            // 生成一个ID
            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);
    }
}

编写控制层代码

package sample.web.ui.mvc;
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 sample.web.ui.Message;
import sample.web.ui.MessageRepository;
import javax.validation.Valid;

@Controller
@RequestMapping("/messages")
public class MessageController {

    private final MessageRepository messageRepository;

    public MessageController(MessageRepository messageRepository) {
        this.messageRepository = messageRepository;
    }

    // 进入消息列表页面
    @GetMapping
    public ModelAndView list() {
        Iterable 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", "Successfully created a new message");
        return new ModelAndView("redirect:/messages/{message.id}", "message.id", message.getId());
    }

    // 删除消息
    @GetMapping(value = "delete/{id}")
    public ModelAndView delete(@PathVariable("id") Long id) {
        this.messageRepository.deleteMessage(id);
        Iterable messages = this.messageRepository.findAll();
        return new ModelAndView("messages/list", "messages", messages);
    }

    // 进入修改消息页面
    @GetMapping(value = "modify/{id}")
    public ModelAndView modifyForm(@PathVariable("id") Message message) {
        return new ModelAndView("messages/form", "message", message);
    }
}

程序入口main

package sample.web.ui;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@SpringBootApplication
public class SampleWebUiApplication {

    // 在Spring 容器中加入内存管理消息实例
    @Bean
    public MessageRepository messageRepository() {
        return new InMemoryMessageRepository();
    }

    // 自定义类型转换,Controller 入参字符串转换为 Message 类型
    @Bean
    public Converter messageConverter() {
        return new Converter() {
            @Override
            public Message convert(String id) {
                return messageRepository().findMessage(Long.valueOf(id));
            }
        };
    }

    // 跳转到消息列表
    @GetMapping("/")
    public ModelAndView index(){
        return new ModelAndView("redirect:/messages");
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleWebUiApplication.class, args);
    }
}

编写布局页面




Layout

    


    

Layout

Fake content

编写列表页面




Messages : View all


    

Messages : View all

ID Created Summary
No messages
1 July 11, 2012 2:17:16 PM CDT The summary

编写增加页面




Messages : Create


    

Messages : Create

Validation error

编写详情页面



Messages : View




    

Messages : Create

Some Success message
ID
123
Date
July 11, 2012 2:17:16 PM CDT
Summary
A short summary...
Message
A detailed message that is longer than the summary.

Spring 设置 application.properties

spring.thymeleaf.cache=false
server.tomcat.basedir=target/tomcat
server.tomcat.accesslog.enabled=true

编写日志文件 logback.xml



    

bootstrap v2.0 请到官网下载

到这里所有的类都编写完了,让我们来用用看吧

让我们打开浏览器地址栏访问
http://localhost:8080/

演示

你的运行结果对了吗?

更多精彩内容

架构实战篇(一):Spring Boot 整合MyBatis
架构实战篇(二):Spring Boot 整合Swagger2
架构实战篇(三):Spring Boot 整合MyBatis(二)
架构实战篇(四):Spring Boot 整合 Thymeleaf
架构实战篇(五):Spring Boot 表单验证和异常处理
架构实战篇(六):Spring Boot RestTemplate的使用

关注我们

如果需要源码可以关注“IT实战联盟”公众号并留言(源码名称+邮箱),小萌看到后会联系作者发送到邮箱,也可以加入交流群和作者互撩哦~~~!

架构实战篇(四):Spring Boot整合 Thymeleaf_第3张图片

你可能感兴趣的:(架构实战篇(四):Spring Boot整合 Thymeleaf)