Shiro整合Springboot+themleaf

Shiro整合Springboot+themleaf6 1 整合思路 6 2 配置环境创建项目引入依赖 引入 shiro 整合 Springboot 依赖 dependency groupId org apache shiro groupId artifactId shiro spring boot starter artifactId version 1 5 3 version dependency

6.1 整合思路

image-20200525185630463

6.2 配置环境

  1. 创建项目
  2. 引入依赖
    <!--引入shiro整合Springboot依赖--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.5.3</version> </dependency> <!--引入扩展依赖--> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency> 
  3. 页面中引入命名空间
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> ...... 
  4. 常见权限控制标签使用
    <!-- 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。 --> <p shiro:guest="">Please <a href="login.html">login</a></p> <!-- 认证通过或已记住的用户。 --> <p shiro:user=""> Welcome back John! Not John? Click <a href="login.html">here</a> to login. </p> <!-- 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。 --> <p shiro:authenticated=""> Hello, <span shiro:principal=""></span>, how are you today? </p> <a shiro:authenticated="" href="updateAccount.html">Update your contact information</a> <!-- 输出当前用户信息,通常为登录帐号信息。 --> <p>Hello, <shiro:principal/>, how are you today?</p> <!-- 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。 --> <p shiro:notAuthenticated=""> Please <a href="login.html">login</a> in order to update your credit card information. </p> <!-- 验证当前用户是否属于该角色。 --> <a shiro:hasRole="admin" href="admin.html">Administer the system</a><!-- 拥有该角色 --> <!-- 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。 --> <p shiro:lacksRole="developer"><!-- 没有该角色 --> Sorry, you are not allowed to developer the system. </p> <!-- 验证当前用户是否属于以下所有角色。 --> <p shiro:hasAllRoles="developer, 2"><!-- 角色与判断 --> You are a developer and a admin. </p> <!-- 验证当前用户是否属于以下任意一个角色。 --> <p shiro:hasAnyRoles="admin, vip, developer,1"><!-- 角色或判断 --> You are a admin, vip, or developer. </p> <!--验证当前用户是否拥有指定权限。 --> <a shiro:hasPermission="userInfo:add" href="createUser.html">添加用户</a><!-- 拥有权限 --> <!-- 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。 --> <p shiro:lacksPermission="userInfo:del"><!-- 没有权限 --> Sorry, you are not allowed to delete user accounts. </p> <!-- 验证当前用户是否拥有以下所有角色。 --> <p shiro:hasAllPermissions="userInfo:view, userInfo:add"><!-- 权限与判断 --> You can see or add users. </p> <!-- 验证当前用户是否拥有以下任意一个权限。 --> <p shiro:hasAnyPermissions="userInfo:view, userInfo:del"><!-- 权限或判断 --> You can see or delete users. </p> <a shiro:hasPermission="pp" href="createUser.html">Create a new User</a> 
  5. 加入shrio方言配置

    页面标签不起作用一定要记住加入方言处理

    @Bean(name = "shiroDialect") public ShiroDialect shiroDialect(){ 
          return new ShiroDialect(); } 

6.3 整合配置类

用来整合shiro框架相关的配置类

package com.chif.shiro.config; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import com.chif.shiro.config.cache.RedisCacheManager; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 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 java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { 
    @Bean(name = "shiroDialect") public ShiroDialect shiroDialect(){ 
    return new ShiroDialect(); } //1.创建shiroFilter 负责拦截所有请求 //ShiroFilterFactoryBean 3 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("SecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ 
    ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 (自动配置) bean.setSecurityManager(defaultWebSecurityManager); //配置系统受限资源 /* anon:无需认证就可以访问 outhc:必须认证了才能访问 user:必须拥有记住我功能才能使用 perms:拥有对某个资源的权限才能访问 role:拥有某个角色权限才能访问 */ Map<String, String> filterMap = new LinkedHashMap<>(); //授权,正常的情况下,没有授权会跳转到未授权的页面 filterMap.put("/user/add","perms[user:add]"); filterMap.put("/user/*","authc");//authc 请求这个资源需要认证和授权 // filterMap.put("/*","authc");//authc 请求这个资源需要认证和授权 filterMap.put("/login","anon");//anon 设置为公共资源 filterMap.put("/getImage","anon");//验证码 设置为公共资源 filterMap.put("/register","anon");//anon 设置为公共资源 //添加shiro的内置过滤器 bean.setFilterChainDefinitionMap(filterMap); //配置系统公共资源 //设置默认认证界面 //默认认证界面路径就是 login.xxx bean.setLoginUrl("/toLogin"); //设置未授权页面 bean.setUnauthorizedUrl("/noauth"); return bean; } //2.创建安全管理器 //DefaultWebSecurityManager 2 @Bean(name = "SecurityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ 
    DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //给安全管理器关联UserRealm securityManager.setRealm(userRealm); return securityManager; } //创建 realm 对象 ,需要自定义类 1 @Bean(name = "userRealm") public UserRealm userRealm(){ 
    UserRealm userRealm = new UserRealm(); //修改凭证校验匹配器 HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); //设置加密算法为md5 hashedCredentialsMatcher.setHashAlgorithmName("Md5"); //设置散列的次数 hashedCredentialsMatcher.setHashIterations(1024); userRealm.setCredentialsMatcher(hashedCredentialsMatcher); //开启缓存管理 userRealm.setCacheManager(new RedisCacheManager()); userRealm.setCachingEnabled(true);//开启全局缓存 userRealm.setAuthenticationCachingEnabled(true);//开启认证缓存 userRealm.setAuthenticationCacheName("authenticationCache"); userRealm.setAuthorizationCachingEnabled(true);//开启授权缓存 userRealm.setAuthorizationCacheName("authorizationCache"); return userRealm; } } 

6.4 常见过滤器

6.5 自定义Realm

package com.chif.shiro.config; import com.chif.shiro.config.salt.MyByteSource; import com.chif.shiro.pojo.Perms; import com.chif.shiro.pojo.User; import com.chif.shiro.service.UserService; import org.apache.shiro.authc.*; 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.util.ByteSource; import org.apache.shiro.util.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; //自定义的 USerRealm public class UserRealm extends AuthorizingRealm { 
    @Autowired UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 
    //获取身份信息 String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal(); System.out.println("调用授权验证"+primaryPrincipal); //根据主身份信息获取角色 和 权限信息 User user = userService.findRolesByUsername(primaryPrincipal); //授权角色信息 if (!CollectionUtils.isEmpty(user.getRoles())){ 
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); user.getRoles().forEach(role -> { 
    simpleAuthorizationInfo.addRole(role.getName()); //授予权限信息 List<Perms> perms = userService.findPermsByRoleId(role.getId()); if (!CollectionUtils.isEmpty(perms) && perms.get(0)!=null){ 
    / * 注意:如果你创建了一个用户,并为这个用户授予了一个角色,但这个角色并未关联任何的 授权字符串, * 那么调用数据库获得的结果是 List<Perms> perms=[null], * 此时 perms已经被初始化,里面只有一个属性null,使用判空的方法无法判别, * 此时继续遍历会报出空指针异常,此时应当添加判断条件 perms.get(0)!=null */ perms.forEach(perm -> { 
    simpleAuthorizationInfo.addStringPermission(perm.getName()); }); } }); return simpleAuthorizationInfo; } return null; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 
    System.out.println("执行了认证"); //用户名 密码 数据库中取 //String name="root"; //String password=""; //用户token String principal= (String) token.getPrincipal(); //连接真实的数据库 User user = userService.queryUserByName(principal); System.out.println(user); if (user==null){ 
   //没有这个人 return null;//抛出异常 未知用户名 } //参数1:返回数据库中正确的用户名 //参数2:返回数据库中正确密码 //参数3:注册时的随机盐 //参数4:提供当前realm的名字 return new SimpleAuthenticationInfo( user.getUsername(), user.getPassword(), new MyByteSource(user.getSalt()), this.getName()); } } 

6.6 认证和退出的实现

Controller层实现

@RequestMapping("/login") public String login(String username,String password,String code,Model model,HttpSession session){ 
    //比较验证码 String codes = (String) session.getAttribute("code"); try { 
    if (codes.equalsIgnoreCase(code)){ 
    //获取当前的用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登录数据 UsernamePasswordToken token = new UsernamePasswordToken(username,password); subject.login(token);//执行登陆方法,如果没有异常就说明OK return "index"; }else { 
    throw new RuntimeException("验证码错误"); } }catch (UnknownAccountException e){ 
   //用户不存在 model.addAttribute("msg","用户名不存在"); return "login"; }catch (IncorrectCredentialsException e){ 
   //密码错误 model.addAttribute("msg","密码错误"); return "login"; }catch (Exception e){ 
    e.printStackTrace(); System.out.println(e.getMessage()); } return "login"; } @RequestMapping("/noauth") public String unauthorized(){ 
    return "未经授权无法访问次页面"; } @RequestMapping("/logout") public String logout(){ 
    Subject subject = SecurityUtils.getSubject(); subject.logout();//退出用户 return "login"; } 

生成salt的工具类

package com.chif.shiro.utils; import java.util.Random; public class SaltUtils { 
    / * 生成salt的静态方法 * @param n * @return */ public static String getSalt(int n){ 
    char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0!@#$%^&*()".toCharArray(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < n; i++) { 
    char aChar = chars[new Random().nextInt(chars.length)]; sb.append(aChar); } return sb.toString(); } public static void main(String[] args) { 
    String salt=getSalt(4); System.out.println(salt); } } 

6.7 连接mtbatis数据库

  1. 设计数据库表

    image-20200527204839080

  2. 创建数据库表
    /* Navicat Premium Data Transfer Source Server : localhost_3306 Source Server Type : MySQL Source Server Version : 80015 Source Host : localhost:3306 Source Schema : db_history Target Server Type : MySQL Target Server Version : 80015 File Encoding : 65001 Date: 25/07/2021 09:17:33 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for t_perms -- ---------------------------- DROP TABLE IF EXISTS `t_perms`; CREATE TABLE `t_perms` ( `id` int(6) NOT NULL AUTO_INCREMENT, `name` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for t_role -- ---------------------------- DROP TABLE IF EXISTS `t_role`; CREATE TABLE `t_role` ( `id` int(6) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for t_role_perms -- ---------------------------- DROP TABLE IF EXISTS `t_role_perms`; CREATE TABLE `t_role_perms` ( `id` int(11) NOT NULL AUTO_INCREMENT, `roleid` int(11) NULL DEFAULT NULL, `permsid` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for t_user_role -- ---------------------------- DROP TABLE IF EXISTS `t_user_role`; CREATE TABLE `t_user_role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` int(11) NULL DEFAULT NULL, `roleid` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `perms` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `salt` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; 
  3. 创建实体类

    User

    @Data @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { 
          private String id; private String username; private String password; private String salt; //定义角色集合 private List<Role> roles; } 

    Role

    @Data @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor public class Role implements Serializable { 
          private String id; private String name; //定义权限的集合 private List<Perms> perms; } 

    Perms

    @Data @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor public class Perms implements Serializable { 
          private String id; private String name; private String url; } 
  4. 创建dao方法
    //根据用户名查询所有角色 User findRolesByUserName(String username); //根据角色id查询权限集合 List<Perms> findPermsByRoleId(String id); 
  5. mapper实现
    <resultMap id="userMap" type="User"> <id column="uid" property="id"/> <result column="username" property="username"/> <!--角色信息--> <collection property="roles" javaType="list" ofType="Role"> <id column="id" property="id"/> <result column="rname" property="name"/> </collection> </resultMap> <select id="findRolesByUserName" parameterType="String" resultMap="userMap"> SELECT u.id uid,u.username,r.id,r.NAME rname FROM t_user u LEFT JOIN t_user_role ur ON u.id=ur.userid LEFT JOIN t_role r ON ur.roleid=r.id WHERE u.username=#{username} </select> <select id="findPermsByRoleId" parameterType="String" resultType="Perms"> SELECT p.id,p.NAME,p.url,r.NAME FROM t_role r LEFT JOIN t_role_perms rp ON r.id=rp.roleid LEFT JOIN t_perms p ON rp.permsid=p.id WHERE r.id=#{id} </select> 

    service等等…

  6. 数据库添加(权限角色)信息
    /* Navicat Premium Data Transfer Source Server : localhost_3306 Source Server Type : MySQL Source Server Version : 80015 Source Host : localhost:3306 Source Schema : db_history Target Server Type : MySQL Target Server Version : 80015 File Encoding : 65001 Date: 25/07/2021 09:27:58 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for t_perms -- ---------------------------- DROP TABLE IF EXISTS `t_perms`; CREATE TABLE `t_perms` ( `id` int(6) NOT NULL AUTO_INCREMENT, `name` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_perms -- ---------------------------- INSERT INTO `t_perms` VALUES (1, 'user:*:*', NULL); INSERT INTO `t_perms` VALUES (2, 'user:add:02', NULL); INSERT INTO `t_perms` VALUES (3, 'user:update:*', NULL); -- ---------------------------- -- Table structure for t_role -- ---------------------------- DROP TABLE IF EXISTS `t_role`; CREATE TABLE `t_role` ( `id` int(6) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_role -- ---------------------------- INSERT INTO `t_role` VALUES (1, 'admin'); INSERT INTO `t_role` VALUES (2, 'user'); INSERT INTO `t_role` VALUES (3, 'product'); -- ---------------------------- -- Table structure for t_role_perms -- ---------------------------- DROP TABLE IF EXISTS `t_role_perms`; CREATE TABLE `t_role_perms` ( `id` int(11) NOT NULL AUTO_INCREMENT, `roleid` int(11) NULL DEFAULT NULL, `permsid` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_role_perms -- ---------------------------- INSERT INTO `t_role_perms` VALUES (1, 1, 1); INSERT INTO `t_role_perms` VALUES (2, 1, 2); INSERT INTO `t_role_perms` VALUES (3, 2, 3); -- ---------------------------- -- Table structure for t_user_role -- ---------------------------- DROP TABLE IF EXISTS `t_user_role`; CREATE TABLE `t_user_role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` int(11) NULL DEFAULT NULL, `roleid` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_user_role -- ---------------------------- INSERT INTO `t_user_role` VALUES (1, 1, 1); INSERT INTO `t_user_role` VALUES (2, 2, 2); INSERT INTO `t_user_role` VALUES (3, 3, 3); -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `perms` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `salt` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'admin', '18010d23f6bd4d702e35c849a6790af9', 'user:*:01', 'b%pLB!*q'); INSERT INTO `user` VALUES (2, 'chif', 'd4feed7e70ce0269f5d85135a34f0d6d', 'user:*:02', 'HpR*B(pk'); INSERT INTO `user` VALUES (5, 'liu', 'd4feed7e70ce0269f5d85135a34f0d6d', 'user:*:05', 'HpR*B(pk'); INSERT INTO `user` VALUES (16, '', '18010d23f6bd4d702e35c849a6790af9', NULL, 'b%pLB!*q'); INSERT INTO `user` VALUES (17, 'ww', 'd4feed7e70ce0269f5d85135a34f0d6d', NULL, 'HpR*B(pk'); SET FOREIGN_KEY_CHECKS = 1; 

6.8 使用缓存Cachemanager

6.8.1 Cache 作用
  • Cache 缓存: 计算机内存中一段数据
  • 作用: 用来减轻DB的访问压力,从而提高系统的查询效率
  • 流程:

image-20200530090656417

6.8.2 使用shiro中默认EhCache实现缓存

1.引入依赖

<!--引入shiro和ehcache--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.5.3</version> </dependency> 

2.开启缓存

//3.创建自定义realm @Bean public Realm getRealm(){ 
    CustomerRealm customerRealm = new CustomerRealm(); //修改凭证校验匹配器 HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); //设置加密算法为md5 credentialsMatcher.setHashAlgorithmName("MD5"); //设置散列次数 credentialsMatcher.setHashIterations(1024); customerRealm.setCredentialsMatcher(credentialsMatcher); //开启缓存管理器 customerRealm.setCachingEnabled(true); customerRealm.setAuthorizationCachingEnabled(true); customerRealm.setAuthorizationCachingEnabled(true); customerRealm.setCacheManager(new EhCacheManager()); return customerRealm; } 

3.启动刷新页面进行测试

  • 注意:如果控制台没有任何sql展示说明缓存已经开启
    # 开启控制台SQL日志注解 logging.level.com.chif.shiro.mapper=debug 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231226.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • javauuid怎么获取_java uri类

    javauuid怎么获取_java uri类2.UUID工具类importjava.util.UUID;publicclassUUIDGenerator{publicUUIDGenerator(){}publicstaticStringgetUUID(){returnUUID.randomUUID().toString();}/***获得一个UUID**@returnStringUUID*/public…

    2022年8月10日
    7
  • 8年经验面试官详解 Java 面试秘诀

    8年经验面试官详解 Java 面试秘诀作者|胡书敏责编|刘静出品|CSDN(ID:CSDNnews)本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。Java程序员准备和投递简历的实…

    2022年5月26日
    39
  • 分析函数 ExecuteSQL

    分析函数 ExecuteSQL
    在学生管理系统中,执行sql语句时,我们用到这个函数,当时有几点不明,现在说说我的理解。
     
    PublicFunctionExecuteSQL(ByValSQLAsString,MsgStringAsString)AsRecordset
      ……
      sTokens=Split(SQL)
    ‘Split返回一个下标从0开始的一维数组,包含指定数目的子字符串。”Select”+”*”+”from”+”user_Info”+

    2022年5月11日
    45
  • python开两个守护线程_hdfs守护线程

    python开两个守护线程_hdfs守护线程**守护线程**是区别于用户线程哈,**用户线程**即我们手动创建的线程,而守护线程是程序运行的时候在后台提供一种**通用服务的线程**。垃圾回收线程就是典型的守护线程。

    2022年10月15日
    6
  • stm32 带通滤波器_带通滤波器详解_带通滤波器工作原理_带通滤波器原理图

    stm32 带通滤波器_带通滤波器详解_带通滤波器工作原理_带通滤波器原理图带通滤波器(band-passfilter)是一个国家允许使用特定频段的波通过发展同时进行屏蔽其他频段的设备。比如RLC振荡回路问题就是这样一个可以模拟带通滤波器。带通滤波器是一种滤波器,它可以在一定的频率范围内通过频率分量,但将其他范围内的频率分量衰减到非常低的水平,与带阻滤波器的概念形成对比。模拟带通滤波器的一个例子是电阻电感电容电路(RLC电路)。这些滤波器也可以通过将低通滤波器与高通…

    2022年5月2日
    34
  • SpringMVC笔记(2)

    SpringMVC笔记(2)

    2021年11月12日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号