springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现

前言:

在springboot的开发框架中,本来就推荐使用thymeleaf的前端框架,所以结合起来进行请后端的开发也是很方面的。下面就是我学习两者的一个实际用例笔记的额一个记录,方便回看关键的知识点

开发环境

  • Windows 10 10.0 amd64
  • eclipse Oxygen.3a Release (4.7.3a)
  • Gradle 4.9
  • JDK1.8.0_151

启动项目的快速搭建

  • 在前面的文章有写到如何利用gradle快速搭建一个springboot启动项目,这里就不再重复
  • https://www.jianshu.com/p/de72c26ec3b5

在eclipse开发环境中导入gradle项目

  • 在前面的文章中也有写到如何导入,在这里也不再详述
  • https://www.jianshu.com/p/3bdf834dcba6

用户管理实例的后台代码编写

  • 首先是整个项目的目录结构,如下


    springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第1张图片
    image.png
  • 然后就是实体类User.java 的编写,代码如下
package com.waylau.spring.boot.blog.domain;

/**   
 * @author: crj
 * @date: 2018年8月21日 上午10:42:13 
 */
public class User {
    private Long id;//实体类的唯一标志
    private String name;//名称
    private String email;//邮箱
    
    public User(){
        //无参的默认的构造函数
    }
    public User(Long id,String name,String email) {//有参的构造函数
        this.id = id;
        this.name = name;
        this.email = email;
    }
    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    
    

}
  • 然后就是借口UserRepository.java 的编写,代码如下:
package com.waylau.spring.boot.blog.repository;



import java.util.List;

import com.waylau.spring.boot.blog.domain.User;

/**   
 * user资源库
 * @author: crj
 * @date: 2018年8月21日 上午10:48:16 
 */
public interface UserRepository {
    /**
     * 创建或者修改用户
     * @author: crj
     * @param user
     * @return
     * @date:2018年8月21日 上午10:49:02
     */
    User saveOrUpdateUser(User user);
    /**
     * 删除用户
     * @author: crj
     * @param id
     * @date:2018年8月21日 上午10:50:06
     */
    void deleteUser(Long id);
    /**
     * 根据用户id查询用户
     * @author: crj
     * @param id
     * @return
     * @date:2018年8月21日 上午10:52:17
     */
    
    User getUserById(Long id);
    /**
     * 获取用户列表
     * @author: crj
     * @return
     * @date:2018年8月21日 上午10:52:01
     */
    
    List listUsers();
    

}
  • 然后就是编写UserRepositoryImpl.java实现上面的接口类,代码如下
package com.waylau.spring.boot.blog.repository.Impl;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

import org.springframework.stereotype.Repository;

import com.waylau.spring.boot.blog.domain.User;
import com.waylau.spring.boot.blog.repository.UserRepository;

/**   
 * UserRepository的实现类
 * @author: crj
 * @date: 2018年8月21日 上午11:01:26 
 */
@Repository 
public class UserRepositoryImpl implements UserRepository{
    //计数,每增加一个用户就递增一个,来生成每个用户的唯一id
    private static  AtomicLong counter= new AtomicLong();
    //模拟存储库,把数据存储在内存当中,需要用到ConcurrentMap来存储用户信息的容器
    private final ConcurrentMap userMap = new ConcurrentHashMap<>();

    
    @Override
    public User saveOrUpdateUser(User user) {
        Long id = user.getId();
        if(id == null) {//新建的
            id = counter.incrementAndGet();
            user.setId(id);
        }
        this.userMap.put(id, user);
        return user;
    }

    @Override
    public void deleteUser(Long id) {
        this.userMap.remove(id);
        
    }

    @Override
    public User getUserById(Long id) {
        
        return this.userMap.get(id);
    }
    /**
     * 说明:这里需要用到ArrayList去包装一下并以List方式返回
     */
    @Override
    public List listUsers() {
        
        return new ArrayList(this.userMap.values());
    }

}
  • 然后就是编写与前端进行交互的UserController.java类,代码如下:
package com.waylau.spring.boot.blog.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.waylau.spring.boot.blog.domain.User;
import com.waylau.spring.boot.blog.repository.UserRepository;

/**   
 * User控制器
 * @author: crj
 * @date: 2018年8月20日 下午4:19:24 
 */
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserRepository userRepository;
    /**
     * 查询用户
     * @author: crj
     * @param model
     * @return
     * @date:2018年8月21日 上午11:27:11
     */
    @GetMapping
    public ModelAndView list(Model model) {
        model.addAttribute("userList",userRepository.listUsers());
        model.addAttribute("title", "用户管理");
        return new ModelAndView("users/list","userModel",model);
    }
    /**
     * 根据用户id查看用户
     * @author: crj
     * @param id
     * @param model
     * @return
     * @date:2018年8月21日 上午11:30:43
     */
    @GetMapping("{id}")
    public ModelAndView view(@PathVariable("id") Long id,Model model) {
        User user = userRepository.getUserById(id);
        model.addAttribute("user",user);
        model.addAttribute("title", "查看用户");
        return new ModelAndView("users/view","userModel",model);
    }
    
    /**
     * 获取创建表单页面
     * @author: crj
     * @param model
     * @return
     * @date:2018年8月21日 上午11:34:57
     */
    @GetMapping("/form")
    public ModelAndView createForm(Model model) {
        model.addAttribute("user",new User());
        model.addAttribute("title", "创建用户");
        return new ModelAndView("users/form","userModel",model);
    }
    /**
     * 保存或者更新用户,并返回用户列表
     * @author: crj
     * @param user
     * @return
     * @date:2018年8月21日 上午11:43:07
     */
    @PostMapping
    public ModelAndView saveOrUpdateUser(User user) {
        user = userRepository.saveOrUpdateUser(user);
        return new ModelAndView("redirect:/users");//重定向到list页面
    }
    /**
     * s删除用户,并返回用户列表
     * @author: crj
     * @param id
     * @return
     * @date:2018年8月22日 上午9:27:49
     */
    @GetMapping("/delete/{id}")
    public ModelAndView deleteUser(@PathVariable("id") Long id) {
        userRepository.deleteUser(id);
        return new ModelAndView("redirect:/users");//重定向到list页面
    }
    /**
     * 修改用户跳转页面
     * @author: crj
     * @param model
     * @return
     * @date:2018年8月22日 上午9:27:31
     */
    @GetMapping("/modify/{id}")
    public ModelAndView modifyUser(@PathVariable("id") Long id,Model model) {
        model.addAttribute("user",userRepository.getUserById(id));
        model.addAttribute("title", "修改用户");
        return new ModelAndView("users/modify","userModel",model);
    }

}

用户管理实例的前端页面代码编写

  • 这里写了两个thymeleaf的页面引用模板片段,分别是header.html和footer.html分别如下:
  • header




Thymeleaf in action


Thymeleaf in action

首页
  • footer.html




Thymeleaf in action





  • 另外分别是增删改查的页面
    • list.html




Thymeleaf in action


ID Email Name 操作
没有用户信息!
删除 修改
  • form.html




Thymeleaf in action


名称:

邮箱:
  • view.html




Thymeleaf in action


ID:

Name:

Email:

  • modify.html




Thymeleaf in action


名称:

邮箱:

项目运行之后,测试页面效果展示

  • 展示用户列表


    springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第2张图片
    image.png
  • 用户信息展示


    springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第3张图片
    image.png
  • 用户信息修改


    springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第4张图片
    image.png

修改后自动跳转到用户列表页面


springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第5张图片
image.png
  • 用户删除,删除后自动跳转回用户列表页面


    springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第6张图片
    image.png

后记

  • 以上没有用到存储数据库,仅仅是在内存中进行了简单的数据操作模拟,后续会有与存储数据库进行交互

  • 以上的代码,仅仅供给自己学习回顾记录所用

  • 在这个实例编写的过程中,会遇到各种小问题,bug,我在这个过程中遇到的一个坑就是忘了导入Thymeleaf依赖,所以当测试编写的路径的时候,没有跳转到指定的前端页面,一直报下面的这个错误:
    2018-08-22 12:05:09.500 WARN 13856 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "list"


    springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第7张图片
    image.png
  • 原因是:如下图所记录的,

springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第8张图片
image.png
  • 当我把thymeleaf的依赖加上,在重新右键项目名称,
    选择Gradle的Refresh Gradle Project更新时候,就能正常跳转到具体的页面了


    springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现_第9张图片
    image.png
  • 因为工程是用gradle创建的,所以不熟悉的朋友需要自行学习一下gradle构建项目相关知识。网上也有很多相关的gradle的开源项目,当拿过来学习的时候,也是需要用到gradle的,这个相当于maven的作用

  • 项目的相关依赖是通过gradle的build.gradle 文件注入的,详细的过程以往的文章也有写到的。

  • 在eclipse中,如果更改了gradle相关的配置,如增加相关依赖,需要选择Gradle的Refresh Gradle Project重新更新一下,再启动项目

你可能感兴趣的:(springboot集成Thymeleaf实现一个用户的增删改查功能,包括前后端代码实现)