springboot-4-CRUD开发实战
流程:
创建项目,勾选基本的几个开发工具还有webstarter
再创建包(service,control,config,dao,pojo)
再前往https://www.webjars.org/,选择bootstrap和jquery的依赖导入
注意:在导入jquery和bootstrap中如何导入我们的对应文件
<script type="text/javascript" src="webjars/jquery/3.6.0/jquery.js"></script> <script type="text/javascript" src="webjars/bootstrap/5.0.1/js/bootstrap.js"></script> <link rel="stylesheet" type="text/css" href="webjars/bootstrap/5.0.1/css/bootstrap.min.css">
导入thmeleaf依赖,并配置(不导入这个依赖,在templates文件中加载的html模板是找不到的)
尝试写一个index.html
<body class="text-center">
<form class="form-sigin">
<img class="mb-4 img-thumbnail" src="https://exploit-typora.oss-cn-shenzhen.aliyuncs.com/img/IMG_20210410_100617.png" alt="" width="200" height="200">
<h1 class="h3 mb-3 font-weight-normal">please login in</h1>
<label for="user-name" class="sr-only">username</label>
<!--注意:一定要用label标签把input标签包含起来,不然就导致input标签不居中-->
<label>
<input id="user-name" type="text" name="username" class="form-control" required="" autofocus="">
</label>
<label for="password" class="sr-only">password</label>
<label>
<input id="password" type="password" name="password" class="form-control" required="" autofocus="">
</label>
<br>
<div class="check-box mb-3">
<label>
<input type="checkbox" value="remember-me">remember
</label>
</div>
<button type="submit" class="btn btn-lg btn-primary btn-block">login</button>
<p class="mt-5 mb-3 text-muted">© 2020-2034</p>
<p class="btn btn-sm">中文</p>
<a class="btn btn-sm">English</a>
</form>
</body>
写一个配置类,把“/”和"/index"和"/index.html"都对应到index主页
@Configuration
public class ViewResolver implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
添加thmeleaf命名空间,和form的提交url
<html lang="en" xmlns:th=http://www.thymeleaf.org
xmlns:sec=http://www.thymeleaf.org/extras/spring-security
xmlns:shiro=http://www.pollix.at/thymeleaf/shiro >
<!--注意:url在thmeleaf中需要用@开头-->
<form class="form-sigin" th:action="@{/test}" method="post">
测试编写对应的登录控制器
@PostMapping("/test")
@ResponseBody
public String test(@RequestParam("username")String username,
@RequestParam("password")String password){
System.out.println(username+password);
return "OK!!";
}
添加功能:判断用户密码是否正确
- 控制器:
@PostMapping("login")
public String login(@RequestParam("username")String username,
@RequestParam("password")String password,
Model model,
HttpSession session){
//判断用户密码是否正确,成功了,登录状态码为200且在session中会有用户名,否则登录状态码为200
if (username.equals("admin") && password.equals("123456")){
session.setAttribute("loginStatus",200);
session.setAttribute("username",username);
//成功了直接重定向到list去获取用户数据
return "redirect:list";
}else{
session.setAttribute("loginStatus",400);
//失败了加上session状态码,然后继续返回到index页面
return "index";
}
}
@GetMapping("list")
public String list(){
return "list";
}
- 模板:
<!--只有当if里面的条件成立了才会显示这段语句-->
<div th:if="${session.loginStatus==400}">
<div class="alert alert-danger" role="alert">用户名或密码错误!!!</div>
</div>
添加功能:当没有登录的时候进入其他页面会自动跳转到登录页面
这是一个拦截器功能,需要创建一个HandleInterceptor类,还有一个配置类
- HandleInterceptor类
//注意这个配置类必须要放置到IOC容器中去
@Component
public class LoginHandleInterceptor implements HandlerInterceptor {
//把三个方法全部重写,主要是第一个方法,后面的方法可删去
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginStatus = request.getSession().getAttribute("loginStatus");
if (loginStatus==null){
//未登录状态
response.sendRedirect("/");
return false;
}else{
if ((Integer) loginStatus == 400){
//登录失败状态
response.sendRedirect("/");
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 {
}
}
- 配置类
@Configuration
public class MyConfig implements WebMvcConfigurer {
//视图控制
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandleInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/index","/index.html","/login");
}
}
首页到此为止
下面开始处理list员工列表
先把对应的url想好
-
list-input:(GET) /input (不带参数)
-
input-list: (POST) /saveEmployee(带了name,gender,email,departmentId参数)
-
list-delete: (GET)/delete (带一个对应的employee的id的参数)
-
list-update:(GET) /update(带一个对应的employee的id的参数)
-
update-list:(POST) /updateEmployee(带了email和departmentId的参数)
然后就是直接实现即可
注意:
关键是更新怎么实现:
list界面到input界面-带入对应的员工id的参数,在控制器处加入updateStatus状态码和对应的这个employee的对象,到了input界面则根据updateStatus状态码判断进入update部分用对应的这个employee对象进行手动回显,并且将name和gender设为disabled(隐藏提交id,name,gender),然后在控制器处new一个新对象,把这个新对象用save方法加入到employeeDao中去
get方法怎么携带参数?
两种方式:
-
/employee/1001
<a th:href="@{/employee/{id}(id=1001)}"></a> 或者 <a th:href="@{/employee/{id}(id=${employee.id})}"></a>
-
/employee?id=1001
<a th:href="@{/employee(id=1001)}"></a> 或者 <a th:href="@{/employee(id=${employee.id})}"></a>
怎么让表单不能被使用但又可以提交?
两种方式:
-
readonly:只读模式
在最后面加上readonly属性即可,但是只有input才有效,seletor没用<input class="form-control" type="text" placeholder="Readonly input here…" readonly>
-
disabled:禁用模式
在最后面加上disabled属性即可,但是会把要提交的信息也给禁用了,需要另外隐藏提交相关信息<input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>
展示最终thmeleaf页面为:
- list界面
<body class="text-center">
<div class="contaniner">
<div class="row">
<div class="col-md-4">
<h4>【[[${session.username}]]】 sir</h4>
</div>
</div>
<div class="row">
<div class="col-md-4">
<a th:href="@{/input}"><button class="bnt btn-primary">Add Employee</button></a>
</div>
</div>
<div class="row">
<div class="col-md-offset-2 col-md-10">
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>name</th>
<th>gender</th>
<th>email</th>
<th>departmentId</th>
<th>departmentName</th>
<th>handle</th>
</tr>
</thead>
<tbody>
<tr th:each="employee:${employees}">
<th th:text="${employee.getId()}"></th>
<th th:text="${employee.getLastName()}"></th>
<div th:if="${employee.getGender()==1}">
<th>男</th>
</div>
<div th:if="${employee.getGender()==0}">
<th>女</th>
</div>
<th th:text="${employee.getEmail()}"></th>
<th th:text="${employee.getDepartment().getDepartmentId()}"></th>
<th th:text="${employee.getDepartment().getDepartmentName()}"></th>
<th>
<a th:href="@{/update(id=${employee.getId()})}"><button class="btn btn-danger">alter</button></a>
<!--这个携带参数是用?携带参数,还有一种是比如:/employee/1001携带参数-->
<!---->
<a th:href="@{/delete(id=${employee.getId()})}"><button class="btn btn-primary">delete</button></a>
</th>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
- input界面
<body>
<div class="container">
<!--添加员工界面-->
<div th:if="${updateStatus==null}">
<form class="form-horizontal" th:action="@{/saveEmployee}" method="post">
<h3>添加员工</h3>
<!--name-->
<div class="form-group">
<label for="name" class="col-sm-4 control-label"><strong>Name</strong></label>
<div class="col-sm-4">
<input type="text" name="name" class="form-control" id="name" placeholder="name">
</div>
</div>
<!--gender-->
<div class="form-group">
<label class="col-sm-4 "><strong>Gender</strong></label>
<div class="col-sm-4">
<select name="gender" class="form-control">
<option value="1">男</option>
<option value="0">女</option>
</select>
</div>
</div>
<!--email-->
<div class="form-group">
<label for="email" class="col-sm-4 control-label"><strong>Email</strong></label>
<div class="col-sm-4">
<input type="email" name="email" class="form-control" id="email" placeholder="email">
</div>
</div>
<!--department-->
`<div class="form-group">
<label class="col-sm-4 control-label"><strong>Department</strong></label>
<div class="col-sm-4">
<select class="form-control" name="departmentId">
<div th:each="department:${departments}">
<option th:text="${department.getDepartmentId()}"></option>
</div>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success btn-sm">CONFIRM ADD</button>
</div>
</div>
</form>
</div>
<!--修改员工界面-->
<div th:if="${updateStatus=='update'}">
<form class="form-horizontal" th:action="@{/updateEmployee}" method="post">
<h3>修改员工</h3>
<input type="hidden" th:value="${updateEmployee.getId()}" name="employeeId">
<input type="hidden" th:value="${updateEmployee.getLastName()}" name="name">
<input type="hidden" th:value="${updateEmployee.getGender()}" name="gender">
<!--name-->
<div class="form-group" readonly>
<label for="updateName" class="col-sm-4 control-label"><strong>Name</strong></label>
<div class="col-sm-4">
<input th:value="${updateEmployee.getLastName()}" type="text" name="name" class="form-control" id="updateName" placeholder="name" disabled>
</div>
</div>
<!--gender-->
<div class="form-group">
<label class="col-sm-4 "><strong>Gender</strong></label>
<div class="col-sm-4">
<div th:if="${updateEmployee.getGender()==1}">
<select th:value="${updateEmployee.getGender()}" name="gender" class="form-control" disabled>
<option value="1">男</option>
<option value="0">女</option>
</select>
</div>
<div th:if="${updateEmployee.getGender()==0}">
<select id="disableInput" th:value="${updateEmployee.getGender()}" name="gender" class="form-control" disabled>
<option value="0">女</option>
<option value="1">男</option>
</select>
</div>
</div>
</div>
<!--email-->
<div class="form-group">
<label for="updateEmail" class="col-sm-4 control-label"><strong>Email</strong></label>
<div class="col-sm-4">
<input th:value="${updateEmployee.getEmail()}" type="email" name="email" class="form-control" id="updateEmail" placeholder="email">
</div>
</div>
<!--department-->
<div class="form-group">
<label class="col-sm-4 control-label"><strong>Department<span style="color: #c0392b;font-weight: 700">(NOW:[[${updateEmployee.getDepartment().getDepartmentId()+"."+updateEmployee.getDepartment().getDepartmentName()}]])</span></strong></label>
<div class="col-sm-4">
<select class="form-control" name="departmentId">
<div th:each="department:${departments}">
<option th:text="${department.getDepartmentId()}"></option>
</div>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success btn-sm">CONFIRM UPDATE</button>
</div>
</div>
</form>
</div>
</div>
</body>