Boss项目:登录+部门分页查询+退出系统(注销)(2.3)
由于代码过于琐碎,所以本篇只写出功能的实现思路和部分核心代码。
一、登录功能:
①login.html:
<script>
<!-- $(function(){}) 页面加载完成后,执行代码- window.load=function(){} -->
$(function () {
$(".submitBtn").click(function () {
axios.post("/loginUser",document.querySelector('#loginForm'),{
headers: {
'Content-Type': 'application/json'
}
}).then(function (res) {
if(res.data.success){
window.location.href = "/department/list";
}else{
alert(res.data.msg)
}
})
})
})
</script>
post请求发送json格式的登录数据到/loginUser路由,若成功则跳转到/department/list,若失败则弹出后端返回的错误信息。
②vo.UserVo类:
接收和封装前端传过来的用户名和密码。
③LoginController类:
@RestController = @Controller + @ResponseBody,告诉Spring该类当前类交给IOC容器控制,并且该类中所有方法的返回值为 JSON/XML格式。
@RestController
public class LoginController {
@Autowired
private EmployeeService employeeService;
@RequestMapping("/loginUser")
public Result login(@RequestBody UserVo userVo, HttpSession session) {
if(StringUtils.isEmpty(userVo.getUsername())){
return Result.fail("用户名不能为空");
}
if(StringUtils.isEmpty(userVo.getPassword())){
return Result.fail("密码不能为空");
}
try {
Employee employee = employeeService.login(userVo);
employee.setPassword("");
session.setAttribute("employee", employee);
return Result.success();
} catch (Exception e) {
e.printStackTrace();
return Result.fail(e.getMessage());
}
}
首先把employeeService取下来,定义/loginUser对应的方法,同时在方法参数中封装前端传来的数据到后端对应的userVo类中,并且获取session对象。
判断用户名不能为空和密码不能为空后,定义login()方法,传入userVo对象,返回值为从数据库中查出的employee对象。
将employee对象的密码设为空后,再把employee存到用户的Session中,避免重复验证。
若成功则返回成功信息,若try块中有任何异常则打印错误日志和返回简洁错误信息
④EmployeeService接口
↓
EmployeeServiceImpl中:
@Resource
private EmployeeMapper employeeMapper;
@Override
public Employee login(UserVo userVo) {
//1.根据用户名查询用户信息
Employee employee = employeeMapper.findByName(userVo.getUsername());
if(StringUtils.isEmpty(employee)){
throw new RuntimeException("用户不存在");
}
//2.对明文进行加密,判断密码是否正确
String pass = MD5Util.encode(userVo.getPassword());
if(!pass.equals(employee.getPassword())){
throw new RuntimeException("密码不正确");
}
//3.返回用户信息
return employee;
}
取出employeeMapper对象,根据userVo.getUsername()查询用户信息,返回employee对象,若为空则抛出"用户不存在"。对userVo.getPassword()加盐,与employee.getPassword()中存储的加密密码比较,若不一致则抛出"密码不正确"。
若都成功则返回employee。
⑤EmployeeMapper接口中:
@Select("select * from employee where name = #{username}")
@Results({
@Result(property = "id",column = "id",id = true),
@Result(property = "name",column = "name"),
@Result(property = "password",column = "password"),
@Result(property = "email",column = "email"),
@Result(property = "age",column = "age"),
@Result(property = "admin",column = "admin"),
@Result(property = "deptId",column = "dept_id")
})
Employee findByName(String username);
实现findByName()方法,select语句中username是userVo对象的属性,将查出来的employee对象与Employee实体类的属性名进行映射。
二、部门分页查询:
①util.QueryObject 工具类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QueryObject {
private Integer currentPage = 1;
private Integer pageSize = 4;
private String keyword;
}
②qo.DepartmentQo 类:
继承QueryObject类
@Data
public class DepartmentQo extends QueryObject {
}
③编写Department实体类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {
private Long id;
private String name;
private String sn;
}
④DepartmentController类:
@ModelAttribute("qo") 的作用:Post 请求的qo会被 SpringMVC 封装,且绑定到模型中,前端页面能回显查询条件(比如搜索框保留输入的关键词)。
@Controller
@RequestMapping("/department")
public class DepartmentController {
@Autowired
private DepartmentService departmentService;
@GetMapping(value = "/list")
public String listGet(Map<String,Object> map){
return getDepartmentListPage(null, map);
}
@PostMapping(value = "/list")
public String listPost(@ModelAttribute("qo") DepartmentQo qo, Map<String, Object> map){
return getDepartmentListPage(qo, map);
}
public String getDepartmentListPage(DepartmentQo qo, Map<String, Object> map){
if(qo == null){
qo = new DepartmentQo();
qo.setCurrentPage(1);//双重保险
}
try {
PageInfo<Department> departmentPageInfo =departmentService.finByPage(qo);
map.put("result",departmentPageInfo);
return "department/list";
} catch (Exception e) {
e.printStackTrace();
return "error/500";
}
}
}
把/department/list分成Get请求和Post请求两部分。Get请求只传map一个参数,Post请求要传一个qo对象和一个map对象,都是用
同一个方法getDepartmentListPage()。
对于getDepartmentListPage()方法,要求传两个参数,即qo和map。
首先第一次访问/department/list,走Get请求,无qo对象。而后进行判断,若qo为空,即创建一个qo对象,设当前页为1(不写也可以,子类会继承父类中的默认值1)。再调用departmentService的finByPage(qo);方法,传入qo对象。将查询到的结果赋值给PageInfodepartment/list。
若try块中抛出任何异常,则打印错误日志和返回简洁错误信息。
⑤DepartmentService
↓
DepartmentServiceImpl实现类:
@Service
public class DepartmentServiceImpl implements DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
@Override
public PageInfo<Department> findByPage(DepartmentQo qo) {
//1.设定分页参数
PageHelper.startPage(qo.getCurrentPage(),qo.getPageSize());
//2.条件查询
List<Department> departmentList= departmentMapper.queryAll();
//3.处理分页信息
PageInfo<Department> info= new PageInfo<>(departmentList);
return info;
}
}
先取出departmentMapper对象,使用 PageHelper.startPage()方法,传入当前页和页面大小。
PageHelper的拦截器会拦截startPage后的第一条查询语句,自动为原 sql 拼接分页语法;
queryAll()返回的List是(qo.getCurrentPage(),qo.getPageSize())的结果集,赋值给List对象。
PageHelper会通过上面的分页参数和查询结果,自动计算出总条数、总页数、上一页 / 下一页等信息,封装到 PageInfo 中
返回info对象
⑥DepartmentMapper接口:
public interface DepartmentMapper {
@Select("select * from department")
@Results({
@Result(property = "id",column = "id",id = true),
@Result(property = "name",column = "name"),
@Result(property = "sn",column = "sn")
})
List<Department> queryAll();
}
查询所有,PageHelper的拦截器自动为 sql 拼接分页语法。
三、退出系统(注销)
①navbar.ftl:
<li class="divider"></li>
<li>
<a href="#" id="logout">
<i class="fa fa-power-off"></i>
退出系统
</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</header>
<script>
$("#logout").click(function () {
//get请求
axios.get("/logout")
.then(function (res) {
window.location.href = "/login.html";
})
})
</script>
前端发送/logout的Get请求,请求成功后跳转到/login.html登录页面。
②LoginController类:
@GetMapping("/logout")
public Result logout(HttpSession session){
//使session失效,使session中的数据全部清空
session.invalidate();
return Result.success();
}
处理Get请求,定义logout()方法,传入参数HttpSession session。 session.setAttribute("employee", employee);,Session中有一个employee对象。使session失效,使session中的数据全部清空,返回成功信息。
浙公网安备 33010602011771号