zoukankan      html  css  js  c++  java
  • Spring Boot Sample 009之spring-boot-web-thymeleaf

    一、环境

    • Idea 2020.1
    • JDK 1.8
    • maven

    二、目的

    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
    
    ```
  • 相关阅读:
    Java与Andriod的区别和关系
    .window.onload()函数和jQuery中的document.ready()有什么区别?
    jquery中$.get()提交和$.post()提交有区别吗?
    Predicate-谓语
    Lambda 表达式
    .什么是JDBC的最佳实践?
    MVC的各个部分都有那些技术来实现?如何实现?
    如何从CDN加载jQuery?
    什么是CDN?哪些是流行的jQuery CDN?使用CDN有什么好处?
    JS 中 == 和 === 区别是什么?
  • 原文地址:https://www.cnblogs.com/ouyushan/p/13025409.html
Copyright © 2011-2022 走看看