Springboot整合SpringSecurity

2023-10-27

使用Basic认证模式

1、maven依赖

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencies>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- springboot整合freemarker -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

        <!-->spring-boot 整合security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

2、SecurityConfig 配置类

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 添加授权账户
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.inMemoryAuthentication().withUser("kaico_admin").password("kaico")
                .authorities("/");
        // 如果kaico_admin账户权限的情况 所有的接口都可以访问,如果kaico_add 只能访问addMember
        auth.inMemoryAuthentication().withUser("kaico_add").password("kaico")
                .authorities("/");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置httpBasic Http协议认证
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();

    }
    /**
     * There is no PasswordEncoder mapped for the id "null"
     * 原因:升级为Security5.0以上密码支持多中加密方式,恢复以前模式
     *
     * @return
     */
    @Bean
    public static NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}

3、测试controller接口

@Controller
public class IndexController {
    /**
     * 跳转到首页
     *
     * @return
     */
    @RequestMapping("/")
    public String index() {
        return "index";
    }

    @ResponseBody
    @RequestMapping("/addMember")
    public String addMember() {
        return "新增用户";
    }

    @ResponseBody
    @RequestMapping("/delMember")
    public String delMember() {
        return "删除用户";
    }

    @ResponseBody
    @RequestMapping("/updateMember")
    public String updateMember() {
        return "修改用户";
    }

    @ResponseBody
    @RequestMapping("/showMember")
    public String showMember() {
        return "查询用户";
    }
}

使用form表形式登录

在上面Basic认证模式的基础上修改SecurityConfig配置类,修改下面的方法

@Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置httpBasic Http协议认证
        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();

    }

springSecurity默认提供登录页面,如下图所示:
在这里插入图片描述
注意:使用表单登录之后,登录成功之后默认跳转首页,也就是请求路径/,没有该请求路径的话会报错。

实现权限控制

上面的案例只是实现了登录认证,但是还没有实现权限控制。

在上面的基础上修改
1、修改SecurityConfig配置类

 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.inMemoryAuthentication().withUser("kaico_admin").password("kaico")
                .authorities("addMember", "delMember", "updateMember", "showMember"
                );
        // 如果kaico_admin账户权限的情况 所有的接口都可以访问,如果kaico_add 只能访问addMember
        auth.inMemoryAuthentication().withUser("kaico_add").password("kaico")
                .authorities("addMember");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置权限
        http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/delMember").hasAnyAuthority("delMember")
                .antMatchers("/updateMember").hasAnyAuthority("updateMember")
                .antMatchers("/showMember").hasAnyAuthority("showMember")
                .antMatchers("/**").fullyAuthenticated().and().formLogin();


    }

没有权限报403错误
在这里插入图片描述

修改403权限不足页面
1、增加配置类

@Configuration
public class WebServerAutoConfiguration {
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
        ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401");
        ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
        ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
        ErrorPage errorPage415 = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/415");
        ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
        factory.addErrorPages(errorPage400, errorPage401, errorPage403, errorPage404, errorPage415, errorPage500);
        return factory;
    }
}

2、增加对应的错误请求路径

@RestController
public class ErrorController {

    @RequestMapping("/error/403")
    public String error403(){

        return "您当前访问的接口权限不足";
    }
}

在这里插入图片描述

自定义登录页面

1、登录页面准备

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
</head>
<body>

<h1>权限控制登陆系统</h1>
<form action="/login" method="post">
    <span>用户名称</span><input type="text" name="username"/> <br>
    <span>用户密码</span><input type="password" name="password"/> <br>
    <input type="submit" value="登陆">

</form>

<#if RequestParameters['error']??>
    用户名称或者密码错误
</#if>


</body>
</html>

2、修改SecurityConfig配置类

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置权限
        http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/delMember").hasAnyAuthority("delMember")
                .antMatchers("/updateMember").hasAnyAuthority("updateMember")
                .antMatchers("/showMember").hasAnyAuthority("showMember")
                .antMatchers("/login").permitAll() //放行登录请求页面
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin().loginPage("/login").and().csrf().disable();
    }

3、增加登录页面请求controller

@Controller
public class LoginController {

    @RequestMapping("/login")
    public String login(){

        return "login";
    }
}

在这里插入图片描述

结合数据库实现RBAC权限模型权限控制

环境准备

数据库

RBAC模型相关数据库表关系图
在这里插入图片描述

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(10) NOT NULL,
  `permName` varchar(50) DEFAULT NULL,
  `permTag` varchar(50) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL COMMENT '请求url',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT INTO `sys_permission` VALUES ('1', '查询用户', 'showMember', '/showMember');
INSERT INTO `sys_permission` VALUES ('2', '添加用户', 'addMember', '/addMember');
INSERT INTO `sys_permission` VALUES ('3', '修改用户', 'updateMember', '/updateMember');
INSERT INTO `sys_permission` VALUES ('4', '删除用户', 'delMember', '/delMember');

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(10) NOT NULL,
  `roleName` varchar(50) DEFAULT NULL,
  `roleDesc` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('1', 'admin', '管理员');
INSERT INTO `sys_role` VALUES ('2', 'add_user', '添加管理员');

-- ----------------------------
-- Table structure for sys_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
  `role_id` int(10) DEFAULT NULL,
  `perm_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_3` (`role_id`),
  KEY `FK_Reference_4` (`perm_id`),
  CONSTRAINT `FK_Reference_4` FOREIGN KEY (`perm_id`) REFERENCES `sys_permission` (`id`),
  CONSTRAINT `FK_Reference_3` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` VALUES ('1', '2');
INSERT INTO `sys_role_permission` VALUES ('1', '3');
INSERT INTO `sys_role_permission` VALUES ('1', '4');
INSERT INTO `sys_role_permission` VALUES ('2', '2');

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(10) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `realname` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `createDate` date DEFAULT NULL,
  `lastLoginTime` date DEFAULT NULL,
  `enabled` int(5) DEFAULT NULL,
  `accountNonExpired` int(5) DEFAULT NULL,
  `accountNonLocked` int(5) DEFAULT NULL,
  `credentialsNonExpired` int(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', 'kaico_admin', '张三', 'c2c92733a75333a4bac673632ff7519a', '2018-11-13', '2018-11-13', '1', '1', '1', '1');
INSERT INTO `sys_user` VALUES ('2', 'kaico_add', '小余', 'c2c92733a75333a4bac673632ff7519a', '2018-11-13', '2018-11-13', '1', '1', '1', '1');

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `user_id` int(10) DEFAULT NULL,
  `role_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_1` (`user_id`),
  KEY `FK_Reference_2` (`role_id`),
  CONSTRAINT `FK_Reference_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`),
  CONSTRAINT `FK_Reference_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ('1', '1');
INSERT INTO `sys_user_role` VALUES ('2', '2');
maven依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencies>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- springboot整合freemarker -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

        <!-->spring-boot 整合security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
       
        <!-- springboot 整合mybatis框架 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- alibaba的druid数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
yml配置
# 配置freemarker
spring:
  freemarker:
    # 设置模板后缀名
    suffix: .ftl
    # 设置文档类型
    content-type: text/html
    # 设置页面编码格式
    charset: UTF-8
    # 设置页面缓存
    cache: false
    # 设置ftl文件路径
    template-loader-path:
      - classpath:/templates
  # 设置静态文件路径,js,css等
  mvc:
    static-path-pattern: /static/**
  datasource:
    name: test
    url: jdbc:mysql://www.kaicostudy.com:3306/study_springSecurity
    username: root
    password: 123456
    # druid 连接池
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver

java代码

实体类

// 用户信息表
@Data
public class UserEntity implements UserDetails {

	private Integer id;
	private String username;
	private String realname;
	private String password;
	private Date createDate;
	private Date lastLoginTime;
	private boolean enabled;
	private boolean accountNonExpired;
	private boolean accountNonLocked;
	private boolean credentialsNonExpired;
	// 用户所有权限
	private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

	public Collection<? extends GrantedAuthority> getAuthorities() {

		return authorities;
	}
}
// 角色信息表
@Data
public class RoleEntity {
	private Integer id;
	private String roleName;
	private String roleDesc;
}
@Data
public class PermissionEntity {
	private Integer id;
	// 权限名称
	private String permName;
	// 权限标识
	private String permTag;
	// 请求url
	private String url;
}

mapper类

@Mapper
public interface PermissionMapper {
    @Select(" select * from sys_permission ")
    List<PermissionEntity> findAllPermission();
}
@Mapper
public interface UserMapper {
    /**
     * 根据用户名称查询
     *
     * @param userName
     * @return
     */
    @Select(" select * from sys_user where username = #{userName}")
    UserEntity findByUsername(@Param("userName") String userName);

    /**
     * 查询用户的权限根据用户查询权限
     *
     * @param userName
     * @return
     */
    @Select(" select permission.* from sys_user user" + " inner join sys_user_role user_role"
            + " on user.id = user_role.user_id inner join "
            + "sys_role_permission role_permission on user_role.role_id = role_permission.role_id "
            + " inner join sys_permission permission on role_permission.perm_id = permission.id where user.username = #{userName};")
    List<PermissionEntity> findPermissionByUsername(@Param("userName") String userName);
}

实现springSecurity的接口UserDetailsService

@Component
@Slf4j
public class MemberUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    /**
     * loadUserByUserName
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.根据该用户名称查询在数据库中是否存在
        UserEntity userEntity = userMapper.findByUsername(username);
        if (userEntity == null) {
            return null;
        }
        // 2.查询对应的用户权限
        List<PermissionEntity> listPermission = userMapper.findPermissionByUsername(username);
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        listPermission.forEach(user -> {
            authorities.add(new SimpleGrantedAuthority(user.getPermTag()));
        });
        log.info(">>>authorities:{}<<<", authorities);
        // 3.将该权限添加到security
        userEntity.setAuthorities(authorities);
        return userEntity;
    }
}

密码加密工具类

public class MD5Util {

	private static final String SALT = "kaico";

	public static String encode(String password) {
		password = password + SALT;
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		char[] charArray = password.toCharArray();
		byte[] byteArray = new byte[charArray.length];

		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16) {
				hexValue.append("0");
			}

			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}
}

SecurityConfig配置类

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MemberUserDetailsService memberUserDetailsService;


    /**
     * 添加授权账户
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() {
            @Override
            public String encode(CharSequence rawPassword) {
                //对密码做加密
                return MD5Util.encode((String) rawPassword);
            }

            /**
             *
             * @param charSequence 用户输入的密码
             * @param s 数据库字段中加密好的密码
             * @return
             */
            @Override
            public boolean matches(CharSequence charSequence, String s) {
                String rawPass = MD5Util.encode((String) charSequence);
                boolean result = rawPass.equals(s);
                return result;
            }
        });
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置权限
        http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/delMember").hasAnyAuthority("delMember")
                .antMatchers("/updateMember").hasAnyAuthority("updateMember")
                .antMatchers("/showMember").hasAnyAuthority("showMember")
                .antMatchers("/login").permitAll() //放行登录请求页面
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin().loginPage("/login").and().csrf().disable();

    }
}

整合完成,开始测试。

动态绑定数据库所有权限

在上面代码的基础上实现,上面是在代码中配置请求路径和权限标识的绑定,现在改成在数据库中动态配置。

SecurityConfig配置类

@Override
protected void configure(HttpSecurity http) throws Exception {
    //配置权限
    List<PermissionEntity> allPermission = permissionMapper.findAllPermission();
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
            expressionInterceptUrlRegistry = http.authorizeRequests();
    allPermission.forEach((permission) -> {
        expressionInterceptUrlRegistry.antMatchers(permission.getUrl()).
                hasAnyAuthority(permission.getPermTag());

    });
    expressionInterceptUrlRegistry.antMatchers("/login").permitAll()
            .antMatchers("/**").fullyAuthenticated()
            .and().formLogin().loginPage("/login").and().csrf().disable();

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

Springboot整合SpringSecurity 的相关文章

  • manifest.mf 文件的附加内容的约定?

    Java JAR 中的 MANIFEST MF 文件是否有任何超出 MANIFEST MF 约定的约定 JAR规范 http download oracle com javase 1 4 2 docs guide jar jar html
  • JNI 不满意链接错误

    我想创建一个简单的 JNI 层 我使用Visual studio 2008创建了一个dll Win 32控制台应用程序项目类型 带有DLL作为选项 当我调用本机方法时 出现此异常 Exception occurred during even
  • ExceptionConverter:java.io.IOException:文档没有页面。我正在使用 iText

    当我执行下面的代码时 File f new File c sample pdf PdfWriter getInstance document new FileOutputStream f document open System out p
  • java.io.IOException: %1 不是有效的 Win32 应用程序

    我正在尝试对 XML 文档进行数字签名 为此我有两个选择 有一个由爱沙尼亚认证中心为程序员创建的库 还有一个由银行制作的运行 Java 代码的脚本 如果使用官方 认证中心 库 那么一切都会像魅力一样进行一些调整 但是当涉及到银行脚本时 它会
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • 一种使用 Java Robot API 和 Selenium WebDriver by Java 进行文件上传的解决方案

    我看到很多人在使用 Selenium WebDriver 的测试环境中上传文件时遇到问题 我使用 selenium WebDriver 和 java 也遇到了同样的问题 我终于找到了解决方案 所以我将其发布在这里希望对其他人有所帮助 当我需
  • hibernate总是自己删除表中的所有数据

    您好 我正在开发一个 spring mvc 应用程序 它使用 hibernate 连接到存储文件的 mysql 数据库 我有两个方法 一个方法添加我选择的特定文件路径中的所有文件 另一种方法调用查询以返回从 mysql 存储的文件列表 问题
  • Microsoft Graph 身份验证 - 委派权限

    我可以使用 Microsoft Graph 访问资源无需用户即可访问 https developer microsoft com en us graph docs concepts auth v2 service 但是 此方法不允许我访问需
  • Prim 的迷宫生成算法:获取相邻单元格

    我基于 Prim 算法编写了一个迷宫生成器程序 该算法是 Prim 算法的随机版本 从充满墙壁的网格开始 选择一个单元格 将其标记为迷宫的一部分 将单元格的墙壁添加到墙壁列表中 While there are walls in the li
  • Clip 在 Java 中播放 WAV 文件时出现严重延迟

    我编写了一段代码来读取 WAV 文件 大小约为 80 mb 并播放该文件 问题是声音播放效果很差 极度滞后 你能告诉我有什么问题吗 这是我的代码 我称之为doPlayJframe 构造函数内的函数 private void doPlay f
  • Java中接口作为方法参数

    前几天去面试 被问到了这样的问题 问 反转链表 给出以下代码 public class ReverseList interface NodeList int getItem NodeList nextNode void reverse No
  • Spring Data 与 Spring Data JPA 与 JdbcTemplate

    我有信心Spring Data and Spring Data JPA指的是相同的 但后来我在 youtube 上观看了一个关于他正在使用JdbcTemplate在那篇教程中 所以我在那里感到困惑 我想澄清一下两者之间有什么区别Spring
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 如何在 JFreeChart TimeSeries 图表上显示降雨指数和温度?

    目前 我的 TimeSeries 图表每 2 秒显示一个位置的温度 现在 如果我想每2秒显示一次降雨指数和温度 我该如何实现呢 这是我的代码 import testWeatherService TestWeatherTimeLapseSer
  • Java直接内存:在自定义类中使用sun.misc.Cleaner

    在 Java 中 NIO 直接缓冲区分配的内存通过以下方式释放 sun misc Cleaner实例 一些比对象终结更有效的特殊幻像引用 这种清洁器机制是否仅针对直接缓冲区子类硬编码在 JVM 中 或者是否也可以在自定义组件中使用清洁器 例
  • 查看Jasper报告执行的SQL

    运行 Jasper 报表 其中 SQL 嵌入到报表文件 jrxml 中 时 是否可以看到执行的 SQL 理想情况下 我还想查看替换每个 P 占位符的值 Cheers Don JasperReports 使用 Jakarta Commons
  • 在 Spring Boot 应用程序中自动装配 ObjectMapper

    我需要在 Spring boot 应用程序中使用默认的 ObjectMapper 作为单例实例 我可以简单地在我的应用程序中 autowire ObjectMapper 在Spring boot应用程序中默认创建的实例 而不创建 Bean
  • 将2-3-4树转换为红黑树

    我正在尝试将 2 3 4 树转换为 java 中的红黑树 但我无法弄清楚它 我将这两个基本类编写如下 以使问题简单明了 但不知道从这里到哪里去 public class TwoThreeFour
  • com.jcraft.jsch.JSchException:身份验证失败

    当我从本地磁盘上传文件到远程服务器时 出现这样的异常 com jcraft jsch JSchException Auth fail at org apache tools ant taskdefs optional ssh Scp exe
  • JAVA - 如何从扫描仪读取文件中检测到“\n”字符

    第一次海报 我在读取文本文件的扫描仪中读取返回字符时遇到问题 正在读取的文本文件如下所示 test txt start 2 0 30 30 1 1 90 30 0 test txt end 第一行 2 表示两个点 第二行 位置索引 0 xp

随机推荐

  • 图像对比度,亮度

    很多时候 一张图像被过度曝光 显得很白 或者光线不足显得很暗 这个时候可以通过调节图像的这两个基本属性 亮度与对比度 来获得整体效果的提升 从而获得质量更高的图片 1 算子operator 首先我们给出算子的概念 一般的图像处理算子都是一个
  • 电源学习总结(五)——开关电源基本原理

    前面讲了一些线性稳压的原理和设计的基本方法 事实上 除了一些功率较大或者对精度要求较高的电源设计 使用集成的线性稳压芯片很少出现 翻车 事故 一般只需关注输入输出范围即可 此外 需注意由于集成的开关电源芯片 尤其是贴片封装的 如SOT 22
  • 【CUDA】初步了解PageLocked host memory的mapped memory功能使用

    导言 大家都知道CUDA 中PageLocked memory 相比portable memory 有着多种优势 在有front side bus的系统中 pagelocked memory 所提供的host 与device之间的数据传送速
  • 硬盘突然提示没有初始化_分享一下固态硬盘不认盘的修复方法

    写在开头 固态硬盘比较害怕突然停电 如果里面有重要数据 请勿用此方法尝试修复 即便可以成功 里面的数据也已经被抹除 需要恢复数据的话 还是需要找专业的数据恢复公司来做 切勿自己折腾 进入正题 前段时间淘了一块威刚的SP550 120G SA
  • 常用脚本(九)Unity_Input

    1 输出鼠标位置 在Update方法中 Debug Log Input mouseposition 2 判断鼠标是否点击 返回 True 和 false 每帧都输出 在Update方法中 Debug Log Input anykey 3 I
  • run()方法和start()方法的区别

    run 方法和start 方法的区别 文章目录 run 方法和start 方法的区别 一 start 是什么 二 run 是什么 三 具体代码实例 四 start 和run 方法的区别 参考 一 start 是什么 用 start方法来启动
  • 安全并正确地重启Elasticsearch集群

    文章目录 前言 问题原因其本质 提前准备 准备重启集群 更新集群 前言 elasticsearch本身具有高可用性 可以做到停机不停服务 在重启elasticsearch后可能存在数据丢失 或者是 启动ES后 怎么一直有大量的数据在迁移 问
  • 快速创建一个spring boot项目

    写了两年还在创建spring boot 项目 最近想自己尝试开发一个项目 所以随便记录一下吧 平常 工作都是现成的项目开发 在项目上加新功能之类的 除了工作平常回去也没琢磨 现在想多思考 为了国庆之后辞职 找工作做一个铺垫 分割线 选择一些
  • linux内核vmlinux生成过程简要分析

    最近工作不太忙 研究了一下Linux内核的编译过程 在此简要记录一下 obj zImage obj compressed vmlinux FORCE call if changed objcopy linux的内核 zImage 的生成依赖
  • 第二天(七)osg::Object* readObjectFile_const std::string& filename_const ReaderWriter::Options* options

    目前流程是 osgViewer viewBase frame viewerInit 创建帧事件 并将漫游器与事件和视口相关联 gt osgViewer Viewer ViewerInit gt osgViewer View Init gt
  • 电脑老是安装一些来路不明的软件(如何解决)?

    目录 先解决自身可能出现的问题 上四大方法 先解决自身可能出现的问题 1 自行百度下载软件 没有到官网那去下载 进入一些假官网下载软件会附带一些流氓软件 看好官网地址再下载或者用安全软件那去下载 2 电脑的浏览器被劫持了 浏览器会有小广告
  • 智能指针与引用计数详解(二)

    在智能指针与引用计数详解 一 当中讲了智能指针还有改进的地方 下面具体问题具体分析 一 智能指针的赋值方法改进 上一章的赋值方法中只要是赋值都是右操作数引用计数加一 左操作数引用计数减一 没有考虑过引用计数对象自赋值的情况 比如按照上一章代
  • Windows键盘对应苹果的Option键

    用mini mac的用户 如果用的是windows的键盘 那么开发时功能键或多或少会有一些不适应 特别是在xCode4中 我就一直没有找到option对应的windows键 苹果有介绍 http support apple com kb H
  • Matlab学习——求解微分方程(组)

    介绍 1 在 Matlab 中 用大写字母 D 表示导数 Dy 表示 y 关于自变量的一阶导数 D2y 表示 y 关于自变量的二阶导数 依此类推 函数 dsolve 用来解决常微分方程 组 的求解问题 调用格式为 X dsolve eqn1
  • 自定义指令 v-loading

    1 在src下创建directive文件夹 2 在directive文件夹下创建loading文件夹 3 loading文件夹内创建index js和loading vue 目录图 4 index js src directive load
  • QtCreator 快捷键问题记录

    我目前用的QtCreator Mac版8 0 0 具体信息如下 一般来说QtCreator的快捷键和设置项在windows下也是一样的 在QtCreator gt Options gt Environment gt Keyboard中可以找
  • SpringBoot整合office转换与预览

    文章目录 一 介绍 1 简介 2 aspose简介 3 jodconverter简介 二 springboot整合aspose实战 1 前期依赖准备 1 1 介绍 1 2 项目直接引入jar包 1 3 maven添加本地包 2 office
  • 使用Retrofit上传实体类到服务端(笔记)

    一 服务端 1 需要对参数用 RequestBody这个注解进行修饰 SpringBoot会自动将前端传过来的JSON数据反序列化成Java对象 登录 param requestVo return PostMapping value log
  • DOTA数据集标签txt文件转为xml文件

    文章目录 1 txt文件格式 2 xml文件格式 3 一般的txt到xml的转换思路 4 最终使用的txt到xml转换的脚本 5 之后可能用到的xml转换到txt的脚本 1 txt文件格式 DOTA数据集的txt文件格式如下 其中 每一行的
  • Springboot整合SpringSecurity

    使用Basic认证模式 1 maven依赖