springboot中的组件学习
注意springboot中的改变
- 首页配置:注意点,所有页面的静态资源都需要使用thymeleaf接管;@{}
- 页面国际化:
- 我们需要配置i18n文件
- 我们如果需要在项目中进行按钮切换,我们需要自定义一个组件LocalResolver
- 记得将自己写的组件配置到spring容器 @bean
- #{} 去除自定义的message
thymeleaf魔板引擎
首先静态资源在项目中的存储位置

在网页文件中,首先的引入thymeleaf的声明:
<html lang="en" xmlns:th=http://www.thymeleaf.org>
之后利用thymeleaf的语法对模板中的部分组件进行改写,并对应好静态资源路径,使用适合其语法。

thymeleaf语法总结:链接: thymeleaf语法总结.
如果遇到thymeleaf不起作用,可以试着清理浏览器缓存,也可以在application.properties中,定义关闭thymeleaf缓存并重启服务
#关闭魔板引擎缓存
spring.thymeleaf.cache=false
# 访问的资源路径前进行自动的拼接
server.servlet.context-path=/chaoxi
国际化
即根据需求,我们可以对网页中的语言进行切换。

首先,我们得对页面中得中文部分和英文部分,分别设置对应得properties,

针对需要更改得语言部分,进行对应得翻译。可以随意起名字。
根据springboot底层代码,有一个Localresolver的区域解析器,那么我们可以在自己的config文件中,继承他,并重写她的方法。
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
/**
*
* @create 2022-04-06 18:15
*/
//自定义自己的语言请求解析
public class MyLocaleResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
String language = request.getParameter("l");
Locale locale = Locale.getDefault(); //如果没有就使用默认的
//如果请求的链接带了国际化参数
if (!StringUtils.isEmpty(language)){
//zh_CN
String[] split = language.split("_");
//国家,地区
locale=new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
记住,我们自定义好解析器后,一定要将其注册并托管到springboot
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//自定义的视图转发器
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
//自定义国际化语言解析器
@Bean //******
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
网页中,需要带有语言选项的请求参数。通过后端解析,来随时切换语言。当然,我们还需要在application.properties中配置国际化配置,


登录功能的实现+拦截器
前端传递用户名和密码的时候需要用name标签进行传递
<input type="email" id="inputEmail" name="username" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<input type="password" id="inputPassword" name="password" class="form-control" th:placeholder="#{login.password}" required="">
首先定义登录的路由(Controller),针对业务对传递的用户名和密码进行判断。当然这里的路由需要和网页中设置的action必须一致:
<form class="form-signin" th:action="@{/user/login}">
设置,登录后反馈的消息,展示在前端,注意thymeleaf的语法
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
import org.springframework.boot.autoconfigure.cassandra.CassandraProperties;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpSession;
/**
* @author chaoxi
* @create 2022-04-06 20:13
*/
@Controller
public class loginController {
@RequestMapping("/user/login")
//@ResponseBody //这个注解的意思是将返回的字符串视为字符串,不在视为视图
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model, HttpSession session){
//之后就是验证的业务
//System.out.println(username);
if(!StringUtils.isEmpty(username) && "123456".equals(password)){
session.setAttribute("loginUser",username); //登录成功后,携带session信息去验证拦截器
return "redirect:/main.html"; //登录成功后,重定向
}else {
model.addAttribute("msg","用户名或者密码错误");
return "index";
}
}
}
为了避免在浏览器的url中暴露用户的用户名和密码,我们需要设置视图映射:
registry.addViewController("/main.html").setViewName("dashboard"); //地址映射,这样才可以避免url显示用户名和密码
拦截器设置(我们的业务需求是必须要用户登录才能访问我们的内部系统,那么再未登录前需要对请求进行检测)
自定义拦截器,需要继承HandlerInterceptor类,并重写三个方法。但是由于我们只需要在登陆前检测,所以只需要重写第一个方法。利用登陆后,用户的session进行判断
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author chaoxi
* @create 2022-04-06 20:57
*/
public class LoginHandlerIntercepter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功后,应该有用户的session
Object loginUser = request.getSession().getAttribute("loginUser");
if (loginUser==null){
request.setAttribute("msg","没有权限,请先登录"); //设置一个消息返回给前端
request.getRequestDispatcher("/index.html").forward(request,response); //将request重新定向到index.html,并携带请求
return false;
}else {
return true;
}
}
//这两个可以不用实现,因为我们要做的是在登录前的验证
// @Override
// public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//
// }
//
// @Override
// public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//
// }
}
重写完自定义的拦截器后,我们需要将其注册到WebMvcConfigurer中令其生效。静态资源其实也是通过request请求得到的,需要对其放行。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author chaoxi
* @create 2022-04-05 16:25
*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//自定义的视图转发器
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard"); //地址映射,这样才可以避免url显示用户名和密码
}
//自定义国际化语言解析器
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
//addPathPatterns匹配拦截的请求,excludePathPatterns排除一些请求
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerIntercepter()).
addPathPatterns("/**").excludePathPatterns("/index.html","/","/user/login","/css/*","/img/**","/js/**");
}
}
跳转页面后,显示用户名。
我们会对登录的用户利用session进行存储用户的信息,那么前端也可以通过调用session,进行数据回显。
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">[[${session.loginUser}]]</a>
这样,登录后,跳转的页面中如果有需要显示用户名的地方,就可以直接显示出来。
员工页面展示
- 即我们需要从后台将数据查询出来,展示到对应的网页上面。

一个网页项目,必然存在着大量的重复的组件,我们可以将这些组件提取出来,单独放在一个文件中,让其余模板文件,直接引用,便可以大幅度减少代码量,也方便维护。比如上述页面,顶部和侧边栏都可以提取出来进行复用。这也是thymeleaf的功能。
<!DOCTYPE html>
<html lang="en" xmlns:th=http://www.thymeleaf.org>
<!--头部导航栏-->
<!--顶部导航栏-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" th:href="@{/user/logout}">注销</a>
</li>
</ul>
</nav>
<!--侧边栏-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="siderbar"> <!--将重复的侧边栏,定义标签。重复页面引用即可-->
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<!--thymeleaf可以利用这种三元运算符进行选择性激活属性-->
<a th:class="${active=='main.html'?'nav-link active':'nav-link'}" th:href="@{/index.html}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
首页 <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
Orders
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
Products
</a>
</li>
<li class="nav-item">
<a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}"> <!--定义员工管理页面的controller-->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
员工管理
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bar-chart-2"><line x1="18" y1="20" x2="18" y2="10"></line><line x1="12" y1="20" x2="12" y2="4"></line><line x1="6" y1="20" x2="6" y2="14"></line></svg>
Reports
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layers"><polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
Integrations
</a>
</li>
</ul>
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
<span>Saved reports</span>
<a class="d-flex align-items-center text-muted" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg>
</a>
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
Current month
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
Last quarter
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
Social engagement
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://getbootstrap.com/docs/4.0/examples/dashboard/#dashboard.html">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
Year-end sale
</a>
</li>
</ul>
</div>
</nav>
</html>
通过,thymeleaf语法进行组件标记:th:fragment=“topbar”。并在一个commons中存储:

之后定义Controller来访问后台数据:(我今天才明白,当model封装数据的并命名,然后转发到对应的网页,网页中中只要这个msg对应了后台中model取得名字,就可以取数据了。以对象的方式取数据。)取数据的方式,参照thymeleaf的语法。
@RequestMapping("/emps")
public String listEmplyees(Model model){
Collection<Employee> employees = employeeDao.getAll();
model.addAttribute("emps",employees);
return "emp/list";
}
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"><div class="chartjs-size-monitor" style="position: absolute; inset: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;"><div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div></div>
<!--增加添加员工的按钮-->
<h2><a class="btn btn-sm btn-success" th:href="@{/emp}">添加员工</a></h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>department</th>
<th>birth</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="emp:${emps}">
<td th:text="${emp.getId()}"></td>
<td>[[${emp.getLastName()}]]</td>
<td th:text="${emp.getEmail()}"></td>
<td th:text="${emp.getGender()==0?'女':'男'}"></td>
<td th:text="${emp.getDepartment().getDepartmentName()}"></td>
<td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}"></td>
<td>
<!--对编辑功能进行完善 ${emp.getId()拼接在链接后的参数-->
<a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.getId()}">编辑</a>
<a class="btn btn-sm btn-danger" th:href="@{/delete/}+${emp.getId()}">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
</main>
员工管理系统的CRUD
开发,现在网页组件中,定义好路由,之后编写Controller。员工系统,对员工的增加和修改都需要跳转到对应的页面才能进行。
增加员工页面
首先,我们会在总的展示页面组件中,定义一个可以跳转到添加页面的路由
<h2><a class="btn btn-sm btn-success" th:href="@{/emp}">添加员工</a></h2>
编写对应的Controller:
//前端点击,get请求到添加员工页面
@GetMapping("/emp")
public String toAddpage(Model model){
Collection<Department> department = departmentDao.getDepartment();
model.addAttribute("departments",department);
return "emp/add";
}
跳转到add界面:
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"><div class="chartjs-size-monitor" style="position: absolute; inset: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;"><div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div></div>
<!--添加员工的表单-->
<form th:action="@{/emp}" method="post">
<div class="form-group">
<label>LastName</label>
<input type="text" name="lastName" class="form-control" placeholder="chaoxi">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" placeholder="admin@qq.com">
</div>
<div class="form-group">
<label>Gender</label>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="0">
<label class="form-check-label">女</label>
</div>
<div class="form-group">
<label>department</label>
<select class="form-control" name="department.id">
<!--这里需要从后台查询已存在的部门放到这里来进行显示-->
<!--注意,我们再Controller接收的是一个employee,所以我们需要提交的是其中的一个属性-->
<option th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input type="text" name="birth" class="form-control" placeholder="chaoxi">
</div>
<button type="submit" class="btn btn-primary">添加</button>
</div>
</form>
</main>
通过页面中的组件,取出数据展示。

点击添加后。form以post请求去传递数据,保存给后台。并重定向到list的主页面。
//填写完信息后,提交到后台并定向到list页面
@PostMapping("/emp")
public String addEmp(Employee employee){
//前端穿过来的对象
employeeDao.add(employee);
return "redirect:/emps";
}
修改员工信息
在list的页面中,点击编辑,跳转到update页面
<a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.getId()}">编辑</a>
由于编辑某个员工的信息,跳转页面后应该直接加载那个员工的信息,所以需要取出她的id一起传递。由于bug原因,“+”连接符,可能会爆红,但是不影响运行。
定义路由:
//去员工的修改页面,链接形式都是getmapping
@GetMapping("/emp/{id}")
public String toUpdatePage(@PathVariable("id")int id,Model model){
//点击编辑按钮,需要将对应的员工信息加载到修改页面.通过前端穿过来的参数取id
Employee employee = employeeDao.getEmployeeById(id);
//让更新页面去取值
model.addAttribute("emp",employee);
Collection<Department> department = departmentDao.getDepartment();
model.addAttribute("departments",department);
return "/emp/update";
}
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"><div class="chartjs-size-monitor" style="position: absolute; inset: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;"><div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div></div>
<!--添加员工的表单-->
<form th:action="@{/update}" method="post">
<input type="hidden" name="id" th:value="${emp.getId()}"> <!--这样就可以把员工id拿过来,封装成对象返回后台,后台对比id,就不会增加员工了-->
<div class="form-group">
<label>LastName</label>
<input th:value="${emp.getLastName()}" type="text" name="lastName" class="form-control" placeholder="chaoxi">
</div>
<div class="form-group">
<label>Email</label>
<input th:value="${emp.getEmail()}" type="email" name="email" class="form-control" placeholder="admin@qq.com">
</div>
<div class="form-group">
<label>Gender</label>
<div class="form-check form-check-inline">
<input th:checked="${emp.getGender()==1}" class="form-check-input" type="radio" name="gender" value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input th:checked="${emp.getGender()==0}" class="form-check-input" type="radio" name="gender" value="0">
<label class="form-check-label">女</label>
</div>
<div class="form-group">
<label>department</label>
<select class="form-control" name="department.id">
<!--这里需要从后台查询已存在的部门放到这里来进行显示-->
<!--注意,我们再Controller接收的是一个employee,所以我们需要提交的是其中的一个属性-->
<option th:selected="${dept.getId()==emp.getDepartment().getId()}" th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input th:value="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}" type="text" name="birth" class="form-control" placeholder="chaoxi">
</div>
<button type="submit" class="btn btn-primary" th:href="@{/update}">提交修改</button>
</div>
</form>
</main>
注意定义隐藏域:
<input type="hidden" name="id" th:value="${emp.getId()}">
这样才能将信息修改后与id绑定,封装成对象传给后台,避免重复生成。
修改完成后,跳转到主页:
<button type="submit" class="btn btn-primary" th:href="@{/update}">提交修改</button>
//修改完成后,跳回员工主页
@PostMapping("/update")
public String UpdateEmp(Employee employee){
employeeDao.add(employee);
return "redirect:/emps";
}
员工的删除(最简单)
定义路由
<a class="btn btn-sm btn-danger" th:href="@{/delete/}+${emp.getId()}">删除</a>
编写controller:
@GetMapping("/delete/{id}")
public String deleteEmp(@PathVariable("id")int id){
employeeDao.delEmployee(id);
return "redirect:/emps";
}
自定义404页面
springboot中,直接在templates中建立一个error文件夹,将我们定义好的404模板文件放进去就行了。
当我们在url输错的时候,就会自动跳转到404页面。不需要写任何代码。
如图:

总结
其实一个网页应该有的功能都基本可以实现了。对数据的增删改查。其实对于后端开发人员来说,需要有一个自己的前端框架。后面就不断地在这个框架中添加分布式,数据库,消息队列等等。
3万+



被折叠的 条评论
为什么被折叠?



