前言
今天学习了如何搭建一个后台管理系统,因此打算记录并总结一下今天的学习内容。
该项目是一个非常好用的后台管理系统模板,代码比较简单,项目功能比较通用,总之就是很推荐初学者学习。
项目的大体项目框架是:SpringBoot+Vue+ElementUI
后台是由SpringBoot,SpringData Jpa构成
前台是基于Vue+ElementUI
项目介绍:
这个项目包含登录页面,用户管理的页面,个人信息的页面。
项目包含登录和注册功能,用户可以从登录界面跳转到管理页面。
登录:
注册:
用户管理:
在管理页面,用户可以跳转到个人信息页面,也可以退出用户,也可以回到主页。还可以在管理页面实现信息的增删改查,同时管理页面也基于ElementUI提供的分页工具实现了分页的功能。
修改用户:
项目架构:
common:保存一些通用的配置
controller:是后台接口
dao:数据库访问层,这个项目使用的是Spring JPA,在Spring Jpa中整合了很多对数据库进行增删改查的方法
entity:对应数据库的实体类
exception:全局异常处理,比如在接口层抛了异常会给前台返回错误信息
service:业务处理层
utils:代码生成工具
resource:包含static(管理前台配置文件)和application.yml(springboot配置,数据库配置)
pom.xml:管理下载依赖dependency
架构各个部分的详解:
首先是common包:
Authintercepter:鉴权,拦截器。用户需要登录才能有权限进行访问。
package com.example.common;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 拦截器
*/
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
Object user = request.getSession().getAttribute("user");
if (user != null) {
request.getSession().setAttribute("user", user);
return true;
}
response.sendRedirect("/login.html");
return false;
}
}
CorsConfig:跨域处理。当非本地用户访问时本地服务器时,需要在此处配置。
package com.example.common;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
// 当前跨域请求最大有效时长。这里默认1天
private static final long MAX_AGE = 24 * 60 * 60;
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
corsConfiguration.setMaxAge(MAX_AGE);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
result:封装结果类。统一返回接口数据,在controller层中,所有的的接口都会返回一个result对象,result会对所有请求的结果进行封装然后返回给前台。result类有三个属性:code,msg,data。code告诉前台访问是成功(1)还是失败(0)。如果失败了,会把错误信息放到msg返回给前台。data是查询数据的,将用户数据放到data中然后返回给前台,前台拿到data在页面进行渲染。
WebMvcConfig:拦截器。拦截或放开一些页面的请求
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/js/**", "/css/**", "/img/**", "/user/login", "/user/register", "/login.html", "/register.html");
}
}
controller层:定义项目所有的接口
包含:增删改查接口、登录注册接口,其他业务接口
controller会通过@resource引入service并请求service
package com.example.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.common.Result;
import com.example.entity.User;
import com.example.exception.CustomException;
import com.example.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
/**
* 登陆
*
* @param user
* @param request
* @return
*/
@PostMapping("/login")
public Result login(@RequestBody User user, HttpServletRequest request) {
User res = userService.login(user);
request.getSession().setAttribute("user", res);
return Result.success(res);
}
/**
* 注册
*
* @param user
* @param request
* @return
*/
@PostMapping("/register")
public Result register(@RequestBody User user, HttpServletRequest request) {
User dbUser = userService.findByUsername(user.getUsername());
if (dbUser != null) {
throw new CustomException("-1", "用户已注册");
}
if (user.getPassword() == null) {
user.setPassword("123456");
}
User res = userService.add(user);
request.getSession().setAttribute("user", res);
return Result.success(res);
}
@PostMapping
public Result save(@RequestBody User user) {
return Result.success(userService.save(user));
}
@PutMapping
public Result> update(@RequestBody User user) {
return Result.success(userService.save(user));
}
@DeleteMapping("/{id}")
public Result> delete(@PathVariable Long id) {
userService.delete(id);
return Result.success();
}
@GetMapping("/{id}")
public Result findById(@PathVariable Long id) {
return Result.success(userService.findById(id));
}
@GetMapping
public Result> findAll() {
return Result.success(userService.findAll());
}
@GetMapping("/page")
public Result> findPage(@RequestParam(required = false, defaultValue = "1") Integer pageNum,
@RequestParam(required = false, defaultValue = "10") Integer pageSize) {
return Result.success(userService.findPage(pageNum, pageSize));
}
@GetMapping("/export")
public void export(HttpServletResponse response) throws IOException {
List
service层:对数据库请求的数据进行逻辑处理。service会对项目的业务进行详细处理。
service会通过@Resource引入DAO来获取数据库数据
package com.example.service;
import com.example.dao.UserDao;
import com.example.entity.User;
import com.example.exception.CustomException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class UserService {
@Resource
private UserDao userDao;
public User save(User user) {
return userDao.save(user);
}
public void delete(Long id) {
userDao.deleteById(id);
}
public User findById(Long id) {
return userDao.findById(id).orElse(null);
}
public List findAll() {
return userDao.findAll();
}
public Page findPage(int pageNum, int pageSize) {
return userDao.findAll(PageRequest.of(pageNum - 1, pageSize));
}
public User login(User user) {
User res = userDao.findByUsernameAndPassword(user.getUsername(), user.getPassword());
if (res == null) {
throw new CustomException("-1", "账号或密码错误");
}
return res;
}
public User add(User user) {
return userDao.save(user);
}
public User findByUsername(String username) {
return userDao.findByUsername(username);
}
}
dao:从数据库查询数据的接口
dao是由jpa提供各种对数据库进行操作的方法的
package com.example.dao;
import com.example.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface UserDao extends JpaRepository, JpaSpecificationExecutor {
User findByUsernameAndPassword(String username, String password);
User findByUsername(String username);
}
entity:数据库实体类
实体类中的属性,与数据库表属性一一对应。
package com.example.entity;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "t_user")
public class User {
/**
* 主键
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 用户名
*/
@Column(name = "username")
private String username;
/**
* 密码
*/
@Column(name = "password")
private String password;
/**
* 邮箱
*/
@Column(name = "email")
private String email;
/**
* 电话
*/
@Column(name = "tel")
private String tel;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
}
总结:
这个项目仍然只学了一半,前端和部署还没有完成。剩下的内容,下次再分享吧。
结语:坚定目标,日日精进,必有所成。共勉! !