像睿智一样简单地使用 Shiro

2023-05-16

加我微信索要我正在使用的《 Apacher Shiro参考手册中文版学习.pdf》 我们一起学习吧~

Apache Shiro 中文文档 - Apache Shiro 教程 | Docs4devApache Shiro 是一个功能强大且易于使用的 Java 安全框架,它用于处理身份验证,授权,加密和会话管理。https://www.docs4dev.com/docs/zh/apache-shiro/1.5.3/reference/tutorial.html

目录

1 Configuration 编写一个配置文件

/resources/shiro.ini

精简的shiro.ini

 2 Ref Config 引用配置文件

[1] 建造工厂

[2]获取实例

[3] 实例注入运行环境

3 使用 shiro

3.1 subject

3.2 session

3.3 Authentication 用户验证

3.4Authentication验证异常

 3.5 其他

4 完整代码:

5 pom

6 shiro.ini


1 Configuration 编写一个配置文件

Shiro 通过基于文本的 INI 配置文件进行配置。其他配置格式也可以。 

/resources/shiro.ini

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
# =============================================================================
# Quickstart INI Realm configuration
#
# For those that might not understand the references in this file, the
# definitions are all based on the classic Mel Brooks' film "Spaceballs". ;)
# =============================================================================

# -----------------------------------------------------------------------------
# Users and their assigned roles
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc
# -----------------------------------------------------------------------------
[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz

# -----------------------------------------------------------------------------
# Roles with assigned permissions
# 
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5

精简的shiro.ini

井号是注释,精简版本如下

[users]
root = secret, admin
guest = guest, guest
presidentskroob = 12345, president
darkhelmet = ludicrousspeed, darklord, schwartz
lonestarr = vespa, goodguy, schwartz

[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5

idea中可以在插件中心下载ini 让ini配置文件有高亮,更好看

 2 Ref Config 引用配置文件

        使用 3 行代码开启Shiro。
   public static void main(String[] args)
    {

        //[1]解析 shiro.ini 文件
        Factory<SecurityManager> factory = new  IniSecurityManagerFactory("classpath:shiro.ini");
        //[2]通过 SecurityManager 工厂获得 SecurityManager 实例
        SecurityManager securityManager = factory.getInstance();
        //[3]把 SecurityManager 对象设置到运行环境中
        SecurityUtils.setSecurityManager(securityManager);

    }

[1] 建造工厂

new  IniSecurityManagerFactory("classpath:shiro.ini");
使用 Shiro IniSecurityManager 实现来提取我们的 shiro.ini 文件,作为实例工厂的建造材料。文件位于 classpath 的根目录。 classpath是这个:

[2]获取实例

factory.getInstance()
factory.getInstance() 方法被调用,它来解析 INI 文件并返回反映该配置的 SecurityManager 实例。

[3] 实例注入运行环境

org.apache.shiro.SecurityUtils.setSecurityManager(securityManager);
将securityManager通过工具类放到运行环境中,至此,一个具有shiro功能的的运行环境已经构建完成。(虽然肉眼什么也看不到)

3 使用 shiro

3.1 subject

shiro是一个安全框架,当考虑到一个程序的安全性时候,我们把我们的安全需求抽象成为以下两点:
1“当前用户是谁”
        Authentication——身份验证
2“当前用户是否被允许做XXX
        Authorization ——权限审查
因此,对于我们考虑应用程序安全的最自然的方式是基于当前用户。 Shiro API 使用它的 Subject 概念从根本上代表了“当前用户”的概念。
Subject 

Subject 是一个安全术语,它基本上的意思是“当前正在执行的用户的特定的安全视图”。

它并没有被称为"User"是因为"User"一词通常和人类相关联。

在安全界,术语"Subject"可以表示为人类,而且可是第三方进程,cron job,daemon account,或其他类似的东西。

它仅仅意味着“该事物目前正与软件交互”。对于大多数的意图和目的,你可以把 Subject 看成是 Shiro"User"概念。
几乎在所有的环境中,你可以通过下面的调用获取当前正在执行的用户:
 Subject subject = SecurityUtils.getSubject();

// 将变量名写成currentUser 会更便于理解

 Subject currentUser = SecurityUtils.getSubject();    

3.2 session

从一个subject中,当然可以获取到一个它所属于的session。

Session session = currentUser.getSession();

session.setAttribute("someKey", "aValue");
Session 是一个 Shiro 的特定实例,它提供了大部分你经常与 HttpSessoins 使用所一样的东西,但它却不需要一个 HTTP 环境!
如果在一个 Web 应用程序内部部署,默认的 Session 将会是基于 HttpSession 的。
在一个非 Web 环境中,像这个简单的教程应用程序, Shiro 将会默认自动地使用它的 Enterprise Session Management

3.3 Authentication 用户验证

因此,现在你能获取一个 Subject 以及他们的 Session。如果他们被允许做某些事,如对角色和权限的检查,像“检 查”真正有用的地方在哪呢?
嗯,我们只能为一个已知的用户做这些检查。我们上面的 Subject 实例代表了当前用户,但谁又是当前用户?呃, 他们是匿名的——也就是说,直到直到他们至少登录一次。那么,让我像下面这样做:
// 如果没验证

if (!currentUser.isAuthenticated()) {
//验证过程

    //用一组用户名和对应密码 --》 设置一个令牌
    //用户在shiro.ini中配置 
    //username = password, roleName1, roleName2, …, roleNameN
    //如:root = secret, admin
    //表示 用户是root,密码是secret 角色是admin 
   UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
    
    //设置记住我选项(没错,就是这么现代的一个功能)
   token.setRememberMe(true);

    //用设置好的令牌来进入当前的运行环境
   currentUser.login(token);

}

登录失败的各种情况,shiro已经通过抛出异常来提示,请为抛出的异常提供不同的解决方案吧。

 // let's login the current user so we can check against roles and permissions:
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);
            try {
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            }
        }

3.4Authentication验证异常

如下

怎么解决这些异常呢?官方这么说:

 3.5 其他

4 完整代码

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Simple Quickstart application showing how to use Shiro's API.
 *
 * @since 0.9 RC2
 */
public class Quickstart {

    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);


    public static void main(String[] args) {

        // The easiest way to create a Shiro SecurityManager with configured
        // realms, users, roles and permissions is to use the simple INI config.
        // We'll do that by using a factory that can ingest a .ini file and
        // return a SecurityManager instance:

        // Use the shiro.ini file at the root of the classpath
        // (file: and url: prefixes load from files and urls respectively):
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();

        // for this simple example quickstart, make the SecurityManager
        // accessible as a JVM singleton.  Most applications wouldn't do this
        // and instead rely on their container configuration or web.xml for
        // webapps.  That is outside the scope of this simple quickstart, so
        // we'll just do the bare minimum so you can continue to get a feel
        // for things.
        SecurityUtils.setSecurityManager(securityManager);

        // Now that a simple Shiro environment is set up, let's see what you can do:

        // get the currently executing user:
        Subject currentUser = SecurityUtils.getSubject();

        // Do some stuff with a Session (no need for a web or EJB container!!!)
        Session session = currentUser.getSession();
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("Retrieved the correct value! [" + value + "]");
        }

        // let's login the current user so we can check against roles and permissions:
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);
            try {
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            }
        }

        //say who they are:
        //print their identifying principal (in this case, a username):
        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

        //test a role:
        if (currentUser.hasRole("schwartz")) {
            log.info("May the Schwartz be with you!");
        } else {
            log.info("Hello, mere mortal.");
        }

        //test a typed permission (not instance-level)
        if (currentUser.isPermitted("lightsaber:wield")) {
            log.info("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info("Sorry, lightsaber rings are for schwartz masters only.");
        }

        //a (very powerful) Instance Level permission:
        if (currentUser.isPermitted("winnebago:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }

        //all done - log out!
        currentUser.logout();

        System.exit(0);
    }
}

5 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.apache.shiro.tutorials</groupId>
    <artifactId>shiro-tutorial</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>First Apache Shiro Application</name>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <!-- This plugin is only to test run our little application. It is not
             needed in most Shiro-enabled applications: -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <classpathScope>test</classpathScope>
                    <mainClass>Tutorial</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.1.0</version>
        </dependency>
        <!-- Shiro use SLF4J for logging. We'll use the 'simple' binding
         in this example app. See http://ww.slf4j.org for more info. -->
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.2</version>
        </dependency>
    </dependencies>


</project>

6 shiro.ini

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
# =============================================================================
# Quickstart INI Realm configuration
#
# For those that might not understand the references in this file, the
# definitions are all based on the classic Mel Brooks' film "Spaceballs". ;)
# =============================================================================

# -----------------------------------------------------------------------------
# Users and their assigned roles
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc
# -----------------------------------------------------------------------------
[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz

# -----------------------------------------------------------------------------
# Roles with assigned permissions
# 
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

像睿智一样简单地使用 Shiro 的相关文章

  • 2 anchor-base和anchor_free两者的优缺点

    anchor base和anchor free两者的优缺点 anchor base和anchor free两者的优缺点 一 什么是anchor二 anchor base和anchor free的区别三 anchor free和single
  • 面试题测试

    1 如何在springboot启动时 xff0c 获取 data 目录下的所有文件名 您可以使用Java的File类来获取指定目录下的所有文件名 以下是一种在Spring Boot应用程序启动时获取指定目录下所有文件名的方法 xff1a 在
  • Ubuntu16.04安装caffe非常细致教程(历经两周的血泪史)

    我这两周安装了很多次caffe xff0c 一直都是按照网上的教程 xff0c 资料很多 xff0c 但是说的感觉都不太全面 xff0c 对于我这一个首次接触Ubuntu系统的小白而言 xff0c 每一步操作都是感觉如临深渊 所以想写一篇教
  • 源码安装gcc

    安装 contrib download prerequisites configure prefix 61 usr local gcc enable bootstrap enable checking 61 release enable l
  • 数据库详细思维导图,期末考试、复试必备

    数据库 一 xff1a 数据库绪论数据 xff08 Data xff09 数据库 xff08 Database xff0c 简称DB xff09 数据库管理系统 xff08 DBMS xff09 数据冗余度 xff1a 数据的安全性 xff
  • 目标检测中删除不一致的xml和jpg文件

    34 34 34 删除image和xml不对应的文件 34 34 34 import os import shutil file name 1 61 r 34 10 11Image img 34 图片文件存放地址 file name 2 6
  • 使用cas-overlay-template 6.2服务部署到整合cas-client

    1 什么sso是单点登录 单点登录 xff08 Single Sign On xff09 xff0c 简称为 SSO xff0c 是比较流行的企业业务整合的解决方案之一 SSO的定义是在多个应用系统中 xff0c 用户只需要登录一次就可以访
  • 单例模式-双重锁

    public class Singleton private static volatile Singleton singleton volatile 相当于防止下面两个 61 61 null 判断不被打乱 private Singleto
  • 基于STM32的12864液晶理解

    前言 字符型液晶显示模块是一种专门用于显示字母 数字 符号等点阵式 LCD xff0c 目前常用 161 xff0c 162 xff0c 202 和 402 行等的模块 上面指的是以字符为单位 xff0c 如161 xff0c 也就是1行1
  • Django rest-framework类视图大全

    视图分类 视图类 GenericAPIView xff1a 包含两大视图类 xff08 APIView GenericAPIView xff09 视图工具类 mixins xff1a 包含五大工具类 xff0c 六大工具方法工具视图类 ge
  • JS中? ?和??=和?.和 ||的区别

    undefined和null是两个比较特殊的数据类型 是不能用点操作符去访问属性的 xff0c 否则将会报错 let a console log a name undefined console log a name 报错 let obj
  • 几款好用的串口和网络调试助手

    和嵌入式厮混在一起总得用几个趁手的调试助手 xff0c 这里介绍几个用过的串口和网络调试助手 xff0c 各有千秋 这也只是我自己使用过的 xff0c 如果又更好 xff0c 也请大家分享一下 xff1a 1 丁丁串口调试助手 这是我最常用
  • 软件设计工程——结构化分析与设计

    结构化分析方法 数据流图 便于用户理解 分析系统数据流程的图形工具 基本图形元素 数据流 xff1a 由固定成分的数据组成 xff0c 表示数据的流向 xff1b 加工 xff1a 描述输入数据流到输出数据流之间的变换 xff1b 数据存储
  • Java面试:接口(Interface)与抽象类(Abstract Class)的区别?

    什么是抽象类 xff1f 包含抽象方法的类 xff0c 是对一系列看上去不同 xff0c 但是本质上相同的具体概念的抽象 抽象类的作用 xff1f 用于拓展对象的行为功能 xff0c 一个抽象类可以有任意个可能的具体实现方式 抽象方法是一种
  • 解决Win10/11有线网(包括校园网)频繁掉线问题

    我连的是校园有线网 xff0c 但以下方法应该能够同时解决wifi出现频繁断连 默认网关不可用的问题 从去年开始我的电脑就有校园网断开的问题 xff0c 但不频繁 xff0c 当时没太在意 xff0c 但今年开学这个问题忽然严重 xff0c
  • python数据分析-Mysql8.0版本用sqlyog连接1251错误解决

    用sqlyog连接8 0 23版本的mysql发生1251错误 下载8 0版本的mysql时候发现最好直接下载 msi的安装文件 xff0c 方便许多 xff0c 好 xff0c 接下来说问题 因为之前装的是5 5版本的 xff0c 但是t
  • 怎么在android中创建raw文件

    怎么在android中创建raw文件 标题 1 2 3 这样即可以
  • form表单中把星号*去掉

    只需要把required true去掉就好了 关于表单验证中会有许多的细节问题需要注意 写法有很多种 注意格式 还有一点 xff0c 如果验证方法是写在行内 xff0c 那么他的方法需要在methods种写
  • 移动端开发的vconsole插件

    vConsole A lightweight extendable front end developer tool for mobile web page 一个轻量级 可扩展的移动网页前端开发工具 是腾讯的一个开源工具 功能 xff1a
  • vite打包工具的介绍

    vite Vite是Vue的作者尤雨溪开发的Web开发构建工具 xff0c 它是一个基于浏览器原生ES模块导入的开发服务器 xff0c 在开发环境下 xff0c 利用浏览器去解析import xff0c 在服务器端按需编译返回 xff0c

随机推荐

  • 初步了解win32界面库DuiLib

    DuiLib是一个开源win32界面库 xff1b 下载地址 xff1a https github com duilib duilib 可以做类似一些杀毒软件的界面 xff1b 效果还是比较好 xff1b 先下载一个demo看一下 xff1
  • this指向 js作用域链

    this 指向 xff5c 作用域与闭包 实战是检验真理的唯一标准深入理解 this作用域闭包到底是什么 this 问题总结 这里将以实战为引子 xff0c 带领大家一起总结出 this 指向问题的规律 默认绑定 xff08 函数直接调用
  • css中zoom和scale

    css中我们常用来缩放的样式元素是transform scale xff1b 也还有我们不熟悉的zoom xff0c 在实际的应用场景中 xff0c 我们需要根据自身项目的需要 xff0c 结合不同的解决方案的优缺点来选择适合我们项目解决方
  • 客户端存储和http缓存

    通过本文学习 xff0c 将获得以下知识 xff1a 1 web 端存储有哪些方式 2 不同存储之间的区别 xff0c 以及使用场景 3 http缓存有哪些策略 web 存储的由来 为什么需要 web 存储呢 xff0c 也就是客户端存储
  • 将React 类组件转换成 函数式组件

    将React 类组件转换成 函数式组件 步骤 xff1a 将class 类定义的React 元素转换成 变量或者函数class 中的 render 函数 直接去掉 xff0c 直接return html 元素将 state 变量使用 use
  • IndexedDB 数据库的使用

    前端的存储方式 前端的存储 xff0c 可以使得页面交互更加友好 xff0c 特别是在保存草稿 xff0c 网络差的情况下对用户来说是很有用的 前端的存储方式有多种 xff0c 像 Local storage Session storage
  • typedef的使用

    typedef的使用 1 为基本数据类型定义新的类型名 typedef double MYDBL 2 为自定义类型 xff08 结构体 共用体和枚举 xff09 起别名 简化类型名关键字 span class token keyword t
  • 解决Vscode每次连接ssh登入需要输入密码问题(免密登入)

    提示 xff1a 解决Vscode每次连接ssh登入需要输入密码问题 xff08 免密登入 xff09 文章目录 问题一 解决方案二 使用步骤1 win10操作 参考文献 问题 可以看到每次登入 xff0c 或者切换的时候都需要输入密码 x
  • 《Bottom-Up and Top-Down Attention for Image Captioning and Visual Question Answering》——2018 CVPR论文笔记

    这是一篇2018 年的 CVPR 的论文 xff0c 使用自下而上和自上而下相结合的注意力机制实现了image captioning和 VQA xff0c 作者使用这个注意力模型在image captioning上取得了非常好的效果 xff
  • Arduino Esp8266 UDP通信

    使用2个WeMos D1mini通过UDP通信实现传输字符串类 WeMos D1 Mini 基于Esp8266的开发板 用Arduino Ide 43 安卓线即可实现程序编译烧录 非常适合于物联网 通信等方面 UDP通信 UDP通信很近似于
  • ROS学习笔记#4 ros节点介绍&常见的rosnode命令

    ros节点 xff1a 是运行计算的过程 xff0c 所有的节点都包含在一张图中 xff08 rqt graph可以查看 xff09 xff0c 通过话题流 xff0c RPC服务和参数服务器彼此进行通信 xff0c 1个机器人控制系统包含
  • MFC CArray类的基本使用

    CArray 类 支持类似于 C 数组的数组 xff0c 但可以根据需要动态减小和增大 语法 template lt class TYPE class ARG TYPE 61 const TYPE amp gt class CArray p
  • 树莓派4B上手教程 2.SSH安装及相关设置

    SSH简介 SSH是一种网络协议 xff0c 用于计算机之间的加密登录 如果一个用户从本地计算机 xff0c 使用SSH协议登录另一台远程计算机 xff0c 我们就可以认为 xff0c 这种登录是安全的 xff0c 即使被中途截获 xff0
  • Ubuntu4B上手教程 3.5如何关闭虚拟桌面

    暑假马上要完事了 树莓派也跟着我要换网络环境 现在的树莓派 虽说插上电就能用 但是也得是同一局域网下 到学校wifi就换了 不知道怎么在ssh和vnc都用不了的情况下让树莓派连接新的WiFi 于是今天想着把虚拟桌面先关掉它 学校起码有显示器
  • 树莓派4B上手教程 4.ROS2不换源安装

    安装ROS对于大多数人来说是一个比较不好的回忆 再难受也得一步一步来啊 不多说了 分享一下我安装ROS2的一些经验 安装环境 我的安装环境是树莓派4B 烧的Ubuntu22 04LTS桌面版镜像 对应的ROS版本是ros2 humble 安
  • 苹果输入法自动合并两个短横线/减号的解决方法

    最近在学MD的时候学到了表格 xff0c 怎么打都打不出来 仔细一看发现在连着打两个横线的时候 xff0c 他合到了一起了 解决方法 设置 通用 键盘 智能标点 Off 问题解决
  • (一篇绝杀)考研英语二阅读题型与技巧总结

    目录 题型一 xff1a 词汇 短语 句子题 xff08 indicate xff09 题型二 xff1a 推断题 xff08 inferred implicit indicate xff09 题型三 xff1a 判断题 xff08 EXC
  • Cache 和 Buffer 都是缓存,主要区别是什么?

    提到这个问题 xff0c 可能意味着你意识到了两者的相关性 的确 xff0c 他们确实有那么一些联系 首先cache是缓存 xff0c buffer是缓冲 xff0c 虽然翻译有那么一个字的不同 xff0c 但这不是重点 个人认为他们最直观
  • C++课后练习

    题目需求 xff1a 编写一个程序 xff0c 它要求用户首先输入其名 xff0c 再输入其姓 然后程序使用一个逗号和空格组合起来 xff0c 并存储和显示组合结果 请使用char数组和头文件cstring 中的函数 xff0c 下面是该程
  • 像睿智一样简单地使用 Shiro

    加我微信索要我正在使用的 Apacher Shiro参考手册中文版学习 pdf 我们一起学习吧 Apache Shiro 中文文档 Apache Shiro 教程 Docs4dev Apache Shiro 是一个功能强大且易于使用的 Ja