layui是一个专门为后台而设计的一个前端框架,功能强大,特别适合后端开发人员,本文以一个demo把登录模块和权限模块基本原理说明,详细的内容可以参考layui的官方文档,git地址
搭建项目
项目架构是springboot+thymeleaf+layui,结构如下图,文件有点多,分成两张图
其中resources资源文件里的layui文件夹下就是layui的所有文件,内容需要到官网下载,解压后全部复制即可
pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.2.RELEASE
com.haijunyin
layuidemo-permission
0.0.1-SNAPSHOT
layuidemo-permission
Demo project for Spring Boot
war
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
javax.servlet
javax.servlet-api
4.0.0
provided
org.thymeleaf
thymeleaf
3.0.11.RELEASE
org.thymeleaf
thymeleaf-spring4
3.0.11.RELEASE
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
application.properties
#thymelea模板配置
xspring.thymeleaf.prefi=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
#热部署文件,页面不产生缓存,及时更新
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
LayuidemoPermissionApplication.java
package com.haijunyin.layuidemo.permission;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 继承SpringBootServletInitializer,因为继承SpringBootServletInitializer是继承WebApplicationInitializer的,而servlet容器启动的时候
* 会将WebApplicationInitializer相关的所有子类实例化(这也是servlet3.0以上的版本提供支持),所以我们还需要在pom.xml
* 文件中导入servlet3.0及以上的版本
*/
@ComponentScan(value = "com.haijunyin.layuidemo.permission")
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableAsync
public class LayuidemoPermissionApplication extends SpringBootServletInitializer{
@Override
public SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(LayuidemoPermissionApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(LayuidemoPermissionApplication.class, args);
}
}
admin_user_list.html
layui在线调试
- 演示说明
- 日期
- 分页
- 上传
- 滑块
在这里,你将以最直观的形式体验 layui!
在编辑器中可以执行 layui 相关的一切代码
你也可以点击左侧导航针对性地试验我们提供的示例
如果最左侧的导航的高度超出了你的屏幕
你可以将鼠标移入导航区域,然后滑动鼠标滚轮即可
点击上传,或将文件拖拽到此处
layui {{ layui.v }} 提供强力驱动
index.html,此文件是显示菜单的主要文件
XXX后台管理系统
login.html,登录页
XXX后台登录
欢迎访问后台管理系统
layui下的所有文件都是官网下载然后解压的
DefineAdapter.java,拦截器配置
package com.haijunyin.layuidemo.permission.config;
import com.haijunyin.layuidemo.permission.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class DefineAdapter implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
//登录拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//排除不被拦截的资源
List excludePaths = new ArrayList<>();
//layui的静态文件
excludePaths.add("/layui/**");
//静态页面
excludePaths.add("/**/*.html");
//登录
excludePaths.add("/");
excludePaths.add("/login");
// excludePaths.add("/error");
registry.addInterceptor(loginInterceptor).
addPathPatterns("/**").excludePathPatterns(excludePaths);
}
}
AdminController.java
package com.haijunyin.layuidemo.permission.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "admin")
public class AdminController {
@RequestMapping(value = "list",method = RequestMethod.GET)
public String list(){
return "权限List测试";
}
}
LoginController.java
package com.haijunyin.layuidemo.permission.controller;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import com.haijunyin.layuidemo.permission.services.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@Autowired
private AdminUserService adminUserService;
/**
* 设置默认打开地址http://localhost:8020的跳转(需要在拦截器中排除)
* 1.已登录,跳转到index.html,把adminUserInfo返回前端渲染
* 2.未登录,跳转到登录页
*/
@RequestMapping(value = "/",method = RequestMethod.GET)
public String index(HttpServletRequest request, ModelMap modelMap){
HttpSession session = request.getSession();
AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
if(null != adminUserInfo){
modelMap.addAttribute("adminUserInfo",adminUserInfo);
return "index";
}else{
return "login";
}
}
/**
* 登录(需要在拦截器中排除)
* 1.已登录,跳转到index.html,把adminUserInfo返回前端渲染
* 2.未登录,验证密码,如果密码正确,跳转到index.html, 则把用户信息放入session,并把adminUserInfo返回前端渲染
* 如果密码错误,跳转到login.html
*/
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(@RequestParam(value = "userName", required = false) String userName,
@RequestParam(value = "userPwd", required = false) String userPwd,
@RequestParam(value = "verifyCode", required = false) String verifyCode,
HttpServletRequest request,
ModelMap modelMap){
//先验证session,再验证密码
HttpSession session = request.getSession();
AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
if(null != adminUserInfo){
modelMap.addAttribute("adminUserInfo",adminUserInfo);
return "index";
}else{
//验证密码
AdminUserInfo adminUserInfo0 = adminUserService.findByUserName(userName);
System.out.println("验证登录...userName="+userName+"userPwd="+userPwd+"verifyCode="+verifyCode);
if(adminUserInfo0.getUserPwd().equals(userPwd)){
//用户信息放入session
System.out.println("登录...成功..." + "用户名:" + userName);
request.getSession().setAttribute("adminUserInfo", adminUserInfo0);
modelMap.addAttribute("adminUserInfo",adminUserInfo0);
return "index";
}else{
System.out.println("登录...密码输入错误..." + "用户名:" + userName);
return "login";
}
}
}
}
LoginInterceptor.java,登录拦截器,用于拦截处理登录和为登录状态下的ajax请求
package com.haijunyin.layuidemo.permission.interceptor;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Service
public class LoginInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
//未登录去登录
if(null == adminUserInfo){
//注意:这里需要写上"/login",而不是"login",否则重定向的地址只会替换最后一个"/"后面的字符串
response.sendRedirect("/login");
}
return true;
}
}
AdminMenuInfo.java,子菜单信息,权限需要真正控制的信息
package com.haijunyin.layuidemo.permission.module;
public class AdminMenuInfo {
/** 子菜单唯一ID,在页面上面会以它做唯一区分的,对应到相应子窗口的lay-id属性 */
private String filterId;
/** 子菜单名,对应子窗口的title */
private String menuName;
/** 子菜单URL,对应子窗口的链接html,点击子菜单后,会打开一个iframe并链接到此url */
private String menuUrl;
public AdminMenuInfo(){
}
public AdminMenuInfo(String filterId, String menuName, String menuUrl){
this.filterId = filterId;
this.menuName = menuName;
this.menuUrl = menuUrl;
}
public String getFilterId() {
return filterId;
}
public void setFilterId(String filterId) {
this.filterId = filterId;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public String getMenuUrl() {
return menuUrl;
}
public void setMenuUrl(String menuUrl) {
this.menuUrl = menuUrl;
}
}
AdminParentInfo.java,父菜单信息
package com.haijunyin.layuidemo.permission.module;
import java.util.List;
public class AdminParentMenuInfo {
private String parentMenuName;
private List adminMenuInfos;
public AdminParentMenuInfo(){
}
public AdminParentMenuInfo(String parentMenuName, List adminMenuInfos){
this.parentMenuName = parentMenuName;
this.adminMenuInfos = adminMenuInfos;
}
public String getParentMenuName() {
return parentMenuName;
}
public void setParentMenuName(String parentMenuName) {
this.parentMenuName = parentMenuName;
}
public List getAdminMenuInfos() {
return adminMenuInfos;
}
public void setAdminMenuInfos(List adminMenuInfos) {
this.adminMenuInfos = adminMenuInfos;
}
}
AdminUserInfo.java,用户信息,用户登陆后会放入session
package com.haijunyin.layuidemo.permission.module;
import java.util.List;
public class AdminUserInfo {
private long id;
private String userName;
private String userPwd;
private List adminParentMenuInfos;
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 getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public List getAdminParentMenuInfos() {
return adminParentMenuInfos;
}
public void setAdminParentMenuInfos(List adminParentMenuInfos) {
this.adminParentMenuInfos = adminParentMenuInfos;
}
}
AdminUserService.java
package com.haijunyin.layuidemo.permission.services;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
public interface AdminUserService {
AdminUserInfo findByUserName(String userName);
}
AdminUserServiceImpl.java,用户登陆信息加载,实际开发过程中,信息都是从数据库中读取的,设计用户-角色-资源的模型结构,本文不做叙述,
package com.haijunyin.layuidemo.permission.services.impl;
import com.haijunyin.layuidemo.permission.module.AdminMenuInfo;
import com.haijunyin.layuidemo.permission.module.AdminParentMenuInfo;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import com.haijunyin.layuidemo.permission.services.AdminUserService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class AdminUserServiceImpl implements AdminUserService {
@Override
public AdminUserInfo findByUserName(String userName) {
AdminUserInfo userInfo = new AdminUserInfo();
userInfo.setId(1);
userInfo.setUserName("yhj");
userInfo.setUserPwd("123456");
List adminParentMenuInfos = new ArrayList<>();
//权限管理
List adminMenuInfos1 = new ArrayList<>();
AdminMenuInfo adminMenuInfo1 = new AdminMenuInfo("filter1","用户","admin/admin_user_list.html");
adminMenuInfos1.add(adminMenuInfo1);
AdminMenuInfo adminMenuInfo2 = new AdminMenuInfo("filter2", "角色","admin/admin_role_list.html");
adminMenuInfos1.add(adminMenuInfo2);
AdminParentMenuInfo adminParentMenuInfo1 = new AdminParentMenuInfo("权限管理",adminMenuInfos1);
adminParentMenuInfos.add(adminParentMenuInfo1);
//订单管理
List adminMenuInfos2 = new ArrayList<>();
AdminMenuInfo adminMenuInfo11 = new AdminMenuInfo("filter3", "订单列表","order/order_list.html");
adminMenuInfos2.add(adminMenuInfo11);
AdminMenuInfo adminMenuInfo22 = new AdminMenuInfo("filter4", "订单推送","order/order_send.html");
adminMenuInfos2.add(adminMenuInfo22);
AdminParentMenuInfo adminParentMenuInfo2 = new AdminParentMenuInfo("订单管理",adminMenuInfos2);
adminParentMenuInfos.add(adminParentMenuInfo2);
userInfo.setAdminParentMenuInfos(adminParentMenuInfos);
return userInfo;
}
}
运行结果
浏览器中输入地址
http://localhost:8020/
弹出登陆页面
输入用户名,密码(123456),出现首页
点击权限管理或订单管理,出现子窗口信息
总结
到此,Demo结束,可以看出一个完整的登陆和权限也是不简单的,本文只是把主干完成了,细节的东西没用去设计,比如登陆页的校验、验证码,还有权限的表设计,等等,不过这些都不是问题了,后续只需要慢慢完善即可,我们通过这个Demo,已经成功地开启了layui的大门