SpringBoot整合jsp,Druid数据监控,与Shiro

  • 一.在SpringBoot项目中, 如何能够使用并运行Jsp页面?
  • 1.添加相应jar包坐标
  • 2.配置视图解析器application.yml
  • 3.直接放在resource目录下或者webapp目录下
  • 二. 如何对spring boot项目配置druid数据源和数监控?
  • 1.添加坐标
  • 2.全局配置文件
  • 3.创建配置类(上面如果全写了下面配置类也就不需要了)
  • 4.开启Spring监控(配置切面)
  • 5.访问改地址(需要有Web启动器的支持)
  • 三. SpringBoot如何整合 Shrio?
  • 1.添加坐标
  • 2.配置类
  • 3.自定义身验证规则
  • 4.在controller的登陆方法使用
  • 5.在html页面通过使用`shiro:hasRole `标签进行角色判断
  • 4.如何快速为实体类添加get.set等一系列方法?


一.在SpringBoot项目中, 如何能够使用并运行Jsp页面?

1.添加相应jar包坐标

<!-- jstl -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<!-- jasper:SpringBoot对jsp的支持 -->
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>

2.配置视图解析器application.yml

spring:       #配置应用名,数据库连接参数
  mvc:
    view:               #视图解析器
        prefix: /WEB-INF/page/
        suffix: .jsp

3.直接放在resource目录下或者webapp目录下

监控ieda的springboot项目内存 druid监控页面嵌入springboot监控_spring

二. 如何对spring boot项目配置druid数据源和数监控?

1.添加坐标

<!--Alibaba DataBase Connection Pool -->
			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>druid</artifactId>
				<version>1.0.23</version>
			</dependency>
			<!--MyBatis And Spring Integration Starter :令@MapperScan生效 -->
			<dependency>
				<groupId>org.mybatis.spring.boot</groupId>
				<artifactId>mybatis-spring-boot-starter</artifactId>
				<version>2.0.1</version>
			</dependency>

2.全局配置文件

spring:       
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/my_exam_test?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
    # 初始化时建立物理连接连接的个数
    initialSize: 5
    # 最小连接池数量
    minIdle: 5
    # 最大连接池数量
    maxActive: 20
    # 获取连接时最大等待时间(ms),即60s
    maxWait: 60000
    # 1.Destroy线程会检测连接的间隔时间;2.testWhileIdle的判断依据
    timeBetweenEvictionRunsMillis: 60000
    # 最小生存时间ms
    minEvictableIdleTimeMillis: 600000
    maxEvictableIdleTimeMillis: 900000
    # 用来检测连接是否有效的sql
    validationQuery: SELECT 1 FROM DUAL
    # 申请连接时执行validationQuery检测连接是否有效,启用会降低性能
    testOnBorrow: false
    # 归还连接时执行validationQuery检测连接是否有效,启用会降低性能
    testOnReturn: false
    # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,
    # 执行validationQuery检测连接是否有效,不会降低性能
    testWhileIdle: true
    # 是否缓存preparedStatement,mysql建议关闭
    poolPreparedStatements: false
    #过滤并统计SQL语句
    filters: stat,wall,log4j  
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true

更多参数配置

#配置数据源
spring.datasource.url=jdbc:mysql://106.14.xx.xx:3306/test
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.username=123456
spring.datasource.druid.password=123456

 1 # 下面为连接池的补充设置,应用到上面所有数据源中
 2 # 初始化大小,最小,最大
 3 spring.datasource.druid.initial-size=5
 4 spring.datasource.druid.min-idle=5
 5 spring.datasource.druid.max-active=20
 6 # 配置获取连接等待超时的时间
 7 spring.datasource.druid.max-wait=60000
 8 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
 9 spring.datasource.druid.time-between-eviction-runs-millis=60000
10 # 配置一个连接在池中最小生存的时间,单位是毫秒
11 spring.datasource.druid.min-evictable-idle-time-millis=300000
12 spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
13 spring.datasource.druid.test-while-idle=true
14 spring.datasource.druid.test-on-borrow=false
15 spring.datasource.druid.test-on-return=false
16 # 打开PSCache,并且指定每个连接上PSCache的大小
17 spring.datasource.druid.pool-prepared-statements=true
18 spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
19 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
20 #spring.datasource.druid.filter-class-names=com.alibaba.druid.filter.stat.StatFilter
21 #spring.datasource.druid.filter-class-names=com.alibaba.druid.wall.WallFilter
22 #spring.datasource.druid.filter-class-names=com.alibaba.druid.filter.logging.Log4jFilter,com.alibaba.druid.filter.stat.StatFilter,com.alibaba.druid.wall.WallFilter
23 # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
24 #spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
25 #spring.datasource.druid.connect-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
26 # 合并多个DruidDataSource的监控数据
27 #spring.datasource.useGlobalDataSourceStat=true
28 
29 # WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
30 #是否开启web-jdbc监控 默认是false
31 spring.datasource.druid.web-stat.enabled=true
32 #是否开启session统计 默认false
33 spring.datasource.druid.web-stat.session-stat-enable=true
34 #设置session统计的最大值 默认是1000
35 spring.datasource.druid.web-stat.session-stat-max-count=1000
36 #是否开启单个监控url调用的sql列表 默认开启
37 spring.datasource.druid.web-stat.profile-enable=true
38 #过滤器url的映射规则
39 spring.datasource.druid.web-stat.url-patterns=/*
40 #过滤器url的排除规则
41 spring.datasource.druid.web-stat.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
42         
43 # StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
44 #是否开启druid的数据统计界面 默认false
45 spring.datasource.druid.stat-view-servlet.enabled= true
46 #servlet映射规则,默认访问http:/**xxx/druid/
47 spring.datasource.druid.stat-view-servlet.url-mappings=/druid/*
48 #是否允许清空统计数据 默认false
49 spring.datasource.druid.stat-view-servlet.reset-enable= false
50 #设置登录名
51 spring.datasource.druid.stat-view-servlet.login-username= admin
52 #设置密码
53 spring.datasource.druid.stat-view-servlet.login-password= admin
54 #设置白名单
55 spring.datasource.druid.stat-view-servlet.allow= 127.0.0.1
56 #访问黑名单
57 #spring.datasource.druid.stat-view-servlet.deny= 192.168.32.139

3.创建配置类(上面如果全写了下面配置类也就不需要了)

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;



/**
 * Druid数据监控配置类,哪里配置了Druid数据库监控,哪里就需要添加这个类
 * @author chy
 *
 */
@Configuration
public class DruidConfig {

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean(destroyMethod="close", initMethod = "init")
    public DataSource druid(){
        return new DruidDataSource();
    }

    /**
     *  配置监控服务器
     **/
    @Bean
   
// @WebInitParam(name="allow",value="192.168.246.1,127.0.0.1")// IP白名单 (没有配置或者为空,则允许所有访问)
//      @WebInitParam(name="deny",value="192.168.16.111"),// IP黑名单 (存在共同时,deny优先于allow)
    public ServletRegistrationBean<StatViewServlet> statViewServlet(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<StatViewServlet>(
            new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();
        
        //设置白名单 (没有配置或者为空,则允许所有访问)
        initParams.put("allow", "192.168.246.1,127.0.0.1,localhost");
        //设置黑名单(存在共同时,deny优先于allow)
        initParams.put("deny", "192.168.16.111");
        // druid后台管理员用户
        initParams.put("loginUsername","test");
        initParams.put("loginPassword","1");
        // 是否能够重置数据
        initParams.put("resetEnable", "false");

        bean.setInitParameters(initParams);
        return bean;
    }

    /**
     *  配置web监控的过滤器
     **/
    @Bean
    public FilterRegistrationBean<WebStatFilter> webStatFilter(){
        FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<WebStatFilter>( new WebStatFilter());
        // 添加过滤规则
        bean.addUrlPatterns("/*");
        Map<String,String> initParams = new HashMap<>();
        // 忽略过滤格式
        initParams.put("exclusions","/static/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        bean.setInitParameters(initParams);
        return  bean;
    }
}

4.开启Spring监控(配置切面)

import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
/**
 * 开启Druid数据库监控的Spring监控
 * @author 曹海洋
 *
 */
@Configuration
public class SpringDaoMethodAspect {

    @Bean
    public DruidStatInterceptor druidStatInterceptor() {
        DruidStatInterceptor dsInterceptor = new DruidStatInterceptor();
        return dsInterceptor;
    }

    @Bean
    @Scope("prototype")
    public JdkRegexpMethodPointcut druidStatPointcut() {
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        pointcut.setPattern("ah.szxy.springcloud.mapper.*");
        return pointcut;
    }

    @Bean
    public DefaultPointcutAdvisor druidStatAdvisor(DruidStatInterceptor druidStatInterceptor, JdkRegexpMethodPointcut druidStatPointcut) {
        DefaultPointcutAdvisor defaultPointAdvisor = new DefaultPointcutAdvisor();
        defaultPointAdvisor.setPointcut(druidStatPointcut);
        defaultPointAdvisor.setAdvice(druidStatInterceptor);
        return defaultPointAdvisor;
    }
}

5.访问改地址(需要有Web启动器的支持)

http://localhost:配置druid项目的端口号/druid/index

登录页(不需要自己创建,阿里为我们提供)

监控ieda的springboot项目内存 druid监控页面嵌入springboot监控_bc_02


密码在Druid的数据监控的配置类中

监控ieda的springboot项目内存 druid监控页面嵌入springboot监控_bc_03


首页

监控ieda的springboot项目内存 druid监控页面嵌入springboot监控_spring_04

监控ieda的springboot项目内存 druid监控页面嵌入springboot监控_mysql_05

三. SpringBoot如何整合 Shrio?

1.添加坐标

<!-- Shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

2.配置类

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;


import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import ah.szxy.backend.exam.system.shiro.UserRealm;

/**
 * Shiro配置类
 * @author chy
 *
 */
@Configuration
public class ShiroConfig {

	@Bean("hashedCredentialsMatcher")
	public HashedCredentialsMatcher hashedCredentialsMatcher() {
		HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
		// 指定加密方式为MD5
		credentialsMatcher.setHashAlgorithmName("MD5");
		// 加密次数
		credentialsMatcher.setHashIterations(1);
		// credentialsMatcher.setStoredCredentialsHexEncoded(true);
		return credentialsMatcher;
	}

	@Bean("userRealm")
	public UserRealm userRealm(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher matcher) {

		UserRealm userRealm = new UserRealm();
		userRealm.setCredentialsMatcher(matcher);

		return userRealm;
	}

	/**
	 * 注入 securityManager
	 */
	@Bean(name = "securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager(HashedCredentialsMatcher hashedCredentialsMatcher) {
		DefaultWebSecurityManager securityManager
							= new DefaultWebSecurityManager();
		// 关联realm.
		securityManager.setRealm(userRealm(hashedCredentialsMatcher));
		return securityManager;
	}

	@Bean
	public ShiroFilterFactoryBean shirFilter(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {

		ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
		// 设置 SecurityManager
		bean.setSecurityManager(securityManager);
		// 设置登录跳转Url
		bean.setLoginUrl("/login");
		//bean.setLoginUrl("http://localhost:9999/backend_exam_system/login");//这里将登陆的url修改成网关的url了
		bean.setSuccessUrl("/main");
		// 设置未授权提示Url
		bean.setUnauthorizedUrl("/unauthorized.jsp");
		
		
		
		
		/**
		 * anon:匿名用户可访问 authc:认证用户可访问 user:使用rememberMe可访问 perms:对应权限可访问 role:对应角色权限可访问
		 **/
		Map<String, String> filterMap = new LinkedHashMap<>();
		// 对静态资源设置允许匿名访问
		filterMap.put("/static/**", "anon");
		filterMap.put("static/**", "anon");
		filterMap.put("/genCaptcha", "anon");
		
		filterMap.put("/login", "anon");
		// 退出,会调用Subject的logout方法,此方法	会将session清空
		filterMap.put("/logout", "logout");
		// 剩余其他路径,必须认证通过才可以访问
		filterMap.put("/**", "authc");

		bean.setFilterChainDefinitionMap(filterMap);
		return bean;
	}

//    @Bean
//    public CookieRememberMeManager cookieRememberMeManager() {
//        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
//        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//        simpleCookie.setMaxAge(259200000);
//        cookieRememberMeManager.setCookie(simpleCookie);
//        cookieRememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA=="));
//        return cookieRememberMeManager;
//    }

}

3.自定义身验证规则

package ah.szxy.backend.exam.system.shiro;

import java.io.Serializable;

import javax.annotation.PostConstruct;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import ah.szxy.backend.exam.system.service.SysUserService;
import ah.szxy.exam.system.entity.SysUser;
import ah.szxy.exam.system.utils.Constants;
import ah.szxy.exam.system.utils.Encodes;
import lombok.Data;

/**
 * 自定义UserRealm
 * 
 * @author chy
 *
 */
public class UserRealm extends AuthorizingRealm {
	@Autowired
	SysUserService sysUserService;

	/**
	 * 授权
	 *
	 * @param principalCollection
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
		String userType = shiroUser.getUserType();
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		if ("1".equals(userType)) {
			info.addRole("admin");
		} else if ("2".equals(userType)) {
			info.addRole("teacher");
		} else if ("3".equals(userType)) {
			info.addRole("student");
		}
		return info;
	}

	/**
	 * 认证
	 *
	 * @param authenticationToken
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
			throws AuthenticationException {
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;

		String username = (String) usernamePasswordToken.getPrincipal();
		SysUser userDB = sysUserService.findSysUserByLoginName(username);
		// 未找到账号
		if (userDB == null) {
			throw new UnknownAccountException();
		}
		if (Boolean.TRUE.equals(userDB.getLocked())) {
			throw new LockedAccountException(); // 帐号锁定
		}
		byte[] salt = Encodes.decodeHex(userDB.getSalt());
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
				new ShiroUser(userDB.getId(), userDB.getLoginName(), userDB.getNickName(), userDB.getIcon(),
						userDB.getUserType()),
				userDB.getPassword(), // 密码
				ByteSource.Util.bytes(salt), getName() // realm name
		);
		return authenticationInfo;
	}

	/**
	 * 设定Password校验的Hash算法与迭代次数.
	 */
	@PostConstruct
	public void initCredentialsMatcher() {
		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Constants.HASH_ALGORITHM);
		matcher.setHashIterations(Constants.HASH_INTERATIONS);
		setCredentialsMatcher(matcher);
	}

	/**
	 * 清理缓存权限
	 */
	public void clearCachedAuthorizationInfo() {
		this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
	}

	public void removeUserAuthorizationInfoCache(String username) {
		SimplePrincipalCollection pc = new SimplePrincipalCollection();
		pc.add(username, super.getName());
		super.clearCachedAuthorizationInfo(pc);
	}

	/**
	 * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息.
	 */
	@Data
	@JsonIgnoreProperties(ignoreUnknown = true)    //忽略值为空的情况,方便在redis中进行json格式的数据传送
	public static class ShiroUser implements Serializable {
		private static final long serialVersionUID = -1373760761780840081L;
		public Integer id;
		public String loginName;
		public String nickName;
		public String icon;
		public String userType;

		public ShiroUser(Integer id, String loginName, String nickName, String icon, String userType) {
			this.id = id;
			this.loginName = loginName;
			this.nickName = nickName;
			this.icon = icon;
			this.userType = userType;
		}
	}
}

4.在controller的登陆方法使用

最重要的部分

//shiro
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password, Boolean.valueOf(rememberMe));
            try {
                subject.login(usernamePasswordToken);
                if (subject.isAuthenticated()) {
                    map.put("url", "index");
                }
                session.setAttribute("user", sysUserService.findSysUserByLoginName(username));
                }

全部代码

/**
     * 处理登录请求
     */
    @PostMapping("/login")
    @ResponseBody
    @Log("登录系统")
    public RestResponse login(String password, String username, String rememberMe, HttpServletRequest request) {
        //获取验证码
        String code = request.getParameter("code");
        if (StringUtils.isBlank(code)) {
            return RestResponse.failure("验证码不能为空");
        }//username="" username =null
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            return RestResponse.failure("用户名或者密码不能为空");
        }
        if (StringUtils.isBlank(rememberMe)) {
            return RestResponse.failure("记住我不能为空");
        }

        //获取正确的验证码
        HttpSession session = request.getSession();
        if (session == null) {
            return RestResponse.failure("session 超时");
        }
        String trueCode = (String) session.getAttribute(Constants.VALIDATE_CODE);
        if (StringUtils.isBlank(trueCode)) {
            return RestResponse.failure("获取验证码超时");
        }
        String errorMsg = "";
        HashMap map = new HashMap();
        //验证码不对
        if (StringUtils.isBlank(code) || !trueCode.toLowerCase().equals(code.toLowerCase())) {
            errorMsg = "验证码错误";
        } else {
            //shiro
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password, Boolean.valueOf(rememberMe));
            try {
                subject.login(usernamePasswordToken);
                if (subject.isAuthenticated()) {
                    map.put("url", "index");
                }
                session.setAttribute("user", sysUserService.findSysUserByLoginName(username));
            } catch (IncorrectCredentialsException e) {
                errorMsg = "登录密码错误.";
            } catch (ExcessiveAttemptsException e) {
                errorMsg = "登录失败次数过多";
            } catch (LockedAccountException e) {
                errorMsg = "帐号已被锁定.";
            } catch (DisabledAccountException e) {
                errorMsg = "帐号已被禁用.";
            } catch (ExpiredCredentialsException e) {
                errorMsg = "帐号已过期.";
            } catch (UnknownAccountException e) {
                errorMsg = "帐号不存在";
            } catch (UnauthorizedException e) {
                errorMsg = "您没有得到相应的授权!";
            }
        }

        if (StringUtils.isBlank(errorMsg)) {
            return RestResponse.success("登录成功").setData(map);
        } else {
            return RestResponse.failure(errorMsg);
        }
    }

5.在html页面通过使用shiro:hasRole标签进行角色判断

<shiro:hasRole name="student">
                            <dd class="layui-this" data-menu="contentManagement">
                                <a href="javascript:;"><i class="layui-icon" data-icon=""></i>
                                    <cite>在线考试</cite>
                                </a>
                            </dd>
                        </shiro:hasRole>
                        <shiro:hasAnyRoles name="admin,teacher">
                            <dd data-menu="memberCenter">
                                <a href="javascript:;">
                                    <i class="seraph icon-icon10" data-icon="icon-icon10"></i>
                                    <cite>考试管理</cite>
                                </a>
                            </dd>
                        </shiro:hasAnyRoles>
                        <shiro:hasRole name="admin">
                            <dd data-menu="systemeSttings">
                                <a href="javascript:;"><i class="layui-icon" data-icon=""></i>
                                    <cite>系统管理</cite>
                                </a>
                            </dd>
                        </shiro:hasRole>
                     
                    </dl>
                </li>
            </ul>

            <ul class="layui-nav topLevelMenus" pc>
                <shiro:hasRole name="student">
                    <li class="layui-nav-item layui-this" data-menu="contentManagement">
                        <a href="javascript:;"><i class="layui-icon" data-icon=""></i>
                            <cite>在线考试</cite>
                        </a>
                    </li>
                </shiro:hasRole>
                <shiro:hasAnyRoles name="admin,teacher">
                    <li class="layui-nav-item" data-menu="memberCenter" pc>
                        <a href="javascript:;">
                            <i class="seraph icon-icon10" data-icon="icon-icon10"></i>
                            <cite>考试管理</cite>
                        </a>
                    </li>
                </shiro:hasAnyRoles>
                <shiro:hasRole name="admin">
                    <li class="layui-nav-item" data-menu="systemeSttings" pc>
                        <a href="javascript:;">
                            <i class="layui-icon" data-icon=""></i>
                            <cite>系统设置</cite>
                        </a>
                    </li>
                </shiro:hasRole>

4.如何快速为实体类添加get.set等一系列方法?

1.添加坐标

<!--lombok,使用@Data注解所需要的jar包 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

2.在实体类上添加注解

import lombok.Data;

@Data
public class Emp {
	private Integer empId;
	private String empName;
	private Integer age;
	private Long phone;
	private String deptartment;
}

注解描述

监控ieda的springboot项目内存 druid监控页面嵌入springboot监控_mysql_06


百度翻译

监控ieda的springboot项目内存 druid监控页面嵌入springboot监控_mysql_07