springBoot学习(一):初学Thymeleaf
这一部分的代码是基于大神的代码,只是原本的代码是有错的,只自己记录一下自己更改之后的代码和自己的理解。
使用Spring Initzal创建项目,最后代码结构如下,我对Spring及其相关之事还是全然陌生的,只按自己理解的话,UserController处定义了浏览器接口,resposity文件夹中的两个文件定义了User类的增删查改,这些增删查改的操作又会被前端通过接口访问,这段代码对于想偷懒的我稍稍有点复杂,但是可以看出比较多的知识点:
使用Thymeleaf的过程:
1、写代码前的配置
在pom.xml中添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
在application.properties中添加对Thymeleaf的配置
#Thymeleaf #指定编码方式 spring.thymeleaf.encoding=UTF-8 #热部署静态文件。能够在浏览器中及时看到修改后的效果(开发) spring.thymeleaf.cache=false #使用html5标准 spring.thymeleaf.mode=html5
2、编写User类和reponsitory里的代码
User类:这里的成员变量id、name、age都是私有的,但其实我在前端界面直接调用实例的id、name、age好像都可以,并不报错
public class User { private Long id;//唯一标识 private String name; private Integer age; public User() {//无参默认构造器 } public User(Long id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } 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 Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
UserRepository接口
import com.example.demo.domain.User; import java.util.List; public interface UserRepository { User saveOrUpdateUser(User user); //新增或者修改用户 void deleteUsere(Long id); //删除用户 User getUserById(Long id); //根据用户id获取用户 List<User> userList (); //获取所有用户的列表 }
UserRepositoryImpl 类:这里增删查改只是模拟保存,没有涉及到真正的保存,重跑就会丢失数据
import com.example.demo.domain.User; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; @Repository//用于标识UserRepositoryimpl 类是一个可注入的bean 。 public class UserRepositoryImpl implements UserRepository { //用来生成一个递增的id ,作为用户的唯一编号。 private static AtomicLong counterId = new AtomicLong(); //模拟数据的存储, private final ConcurrentMap<Long , User> userConcurrentMap =new ConcurrentHashMap<Long,User>(); @Override public User saveOrUpdateUser(User user) { Long id =user.getId(); if (id==null){ id=counterId.incrementAndGet(); user.setId(id); } this.userConcurrentMap.put(id,user); return user; } @Override public void deleteUsere(Long id) { this.userConcurrentMap.remove(id); } @Override public User getUserById(Long id) { return this.userConcurrentMap.get(id); } @Override public List<User> userList() { return new ArrayList<User>(this.userConcurrentMap.values()); } }
3、前端界面代码
看这前端的代码数量就知道我为什么嫌弃复杂了,在这里面common文件夹下的明显是可公用的模块(像页眉、页脚这种存在),list是展示所有用户、form界面是新建和编辑用户的可编辑页面,view是进入某个用户的详情页。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>页脚</title> </head> <body> <div th:fragment="footer"> <a href="/helloworld">欢迎光临</a> </div> </body> </html>
common/footer.html:在这里定义了fragment="footer"的片段
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>页头</title> </head> <body> <div th:fragment="header"> <h1>DemoThymeleaf</h1> <a href="/user" th:href="@{~/user/userlist}">首页</a> </div> </body> </html>
common/header.html:在这里定义了fragment="header"的片段
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>用户列表</title> </head> <body> <div th:replace="~{common/header::header}"></div> <h4 th:text="${userModel.title}"> 渡西湖 </h4> <div> <a href="/user/form" th:href="@{/user/form}"> 新建用户 </a> </div> <table border="2"> <thead> <tr> <td>id</td> <td>名字</td> <td>年龄</td> <td>管理</td> </tr> </thead> <tbody> <tr th:if="${userModel.userList.size()} eq 0"> <td colspan="3">无数据!</td> </tr> <tr th:each="user:${userModel.userList}"> <td th:text="${user.getId()}"></td> <td><a th:href="@{'/user/'+${user.getId()}}" th:text="${user.getName()}"></a></td> <td th:text="${user.getAge()}"></td> <td><a th:href="@{'/user/delete/'+${user.getId()}}">删除</a></td> </tr> </tbody> </table> <div th:replace="~{common/footer::footer}"></div> </body> </html>
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout= "http://www.ultraq.net.nz/thymeleaf/layout"> <head> <meta charset="UTF-8"> <title>DemoThymeleaf</title> </head> <body> <div th:replace="~{common/header::header}"></div> <h4 th:text="${userModel.title}"></h4> <form action="/user" th:action="@{/user}" method="post" th:object="${userModel.user}"> <input type="hidden" name="id" th:value="*{id}"/> 名字<br/> <input type="text" name="name" th:value="*{name}"/> <br/> <input type="number" name="age" th:value="*{age}"/> <br/> <input type="submit" value="提交"> </form> <div th:replace="~{common/footer::footer}"></div> </body> </html>
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>用户详情</title> </head> <body> <div th:replace="~{common/header::header}"></div> <h4 th:text="${userModel.title}"></h4> <div> <p><strong>ID:</strong><span th:text="${userModel.user.id}"></span></p> <p><strong>名字:</strong><span th:text="${userModel.user.name}"></span></p> <p><strong>年龄:</strong><span th:text="${userModel.user.age}"></span></p> </div> <div> <a th:href="@{'/user/delete/'+${userModel.user.id}}">删除</a> <a th:href="@{'/user/edit/'+${userModel.user.id}}">修改</a> </div> <div th:replace="~{common/footer::footer}"></div> </body> </html>
4、controller的编写
import com.example.demo.domain.User; import com.example.demo.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; @RestController @RequestMapping("/user") public class UserController { @Autowired private UserRepository userRepository; //查词所有用户 @GetMapping("/userlist") public ModelAndView userList(Model model){ model.addAttribute("userList",userRepository.userList()); model.addAttribute("title","用户管理"); return new ModelAndView("user/list","userModel",model); } //根据id 查询用户 @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("user/view" ,"userModel",model); } //获取创建表单页面 @GetMapping("/form") public ModelAndView createForm(Model model){ model.addAttribute("user",new User()); model.addAttribute("title","创建用户"); return new ModelAndView("user/form","userModel",model); } //保存用户 @PostMapping public ModelAndView saveOrUpdateUser(User user){ user =userRepository.saveOrUpdateUser(user); return new ModelAndView("redirect:/user/userlist"); } //根据id删除用户 @GetMapping(value = "delete/{id}") public ModelAndView delete(@PathVariable("id") Long id){ userRepository.deleteUsere(id); return new ModelAndView("redirect:/user/userlist"); } //修改用户界面 @GetMapping(value = "edit/{id}") public ModelAndView editForm(@PathVariable("id") Long id, Model model){ User user =userRepository.getUserById(id); model.addAttribute("user",user); model.addAttribute("title","编辑用户"); return new ModelAndView("user/form" ,"userModel",model); } }
具体说说,无论是新增用户保存后还是删除用户后都应该跳转回用户列表展示界面,之前代码用的“redirect”,根据别人评论我改成了
"redirect:/user/userlist",但是也没有去验证之前的写法对不对
//保存用户 @PostMapping public ModelAndView saveOrUpdateUser(User user){ user =userRepository.saveOrUpdateUser(user); return new ModelAndView("redirect:/user/userlist"); } //根据id删除用户 @GetMapping(value = "delete/{id}") public ModelAndView delete(@PathVariable("id") Long id){ userRepository.deleteUsere(id); return new ModelAndView("redirect:/user/userlist"); }
运行:运行主程序DemoApplication.java,根据输出所示的端口访问界面,端口一般是8080,则访问http://127.0.0.1:8080/user/userlist