SpringBoot用slf4j日志 及其 项目配置、MVC支持

2023-11-12

一、Slf4j日志的使用

 我一直以来用的都是最传统的System.out.println()来打印一些错误信息时,其实我也面临过一些问题。这样做的话,错误信息和别的输出结果混在一起,我一直都很难从结果里面找到我调试出来的问题。而且我用这种传统的没有明确的标识和格式,也总是花太多时间。

控制台打印日志的话,就比如像下面这样:

而且我也知道,实际开发肯定会有很多的输出信息,所以接下来最近的学习我就专门从一些优秀博客中了解到了slf4j日志,发现别人这样用效率真的很高,我也得知,SpringBoot提供了一套日志系统,最好的就是那个,logback。

1.1  外观模式

 作为一种设计模式,当然是我应该了解的一个重点,我还是接着看了许多博客,看完大概十来篇吧,也是基本都已经了解了。

它的核心思想就是将子系统的复杂性进行抽象和封装,客户端就能通过一个简单的接口,来访问子系统,不需要了解子系统的具体实现细节。

我理解就是:

外观模式可以想象成一个房子的门面,门面是整个房子的外观,我光通过门面来访问房子,而不需要了解房子内部的具体实现和结构。门面向外提供了一个简单的接口,我只用知道如何使用这个接口访问房子内部。

它的编码实现如下:

  • 先是产品接口
interface Shape {
    public void draw();
}
  • 实现代码是下面这个
class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("绘制一个圆形");
    }
}

class Square implements Shape{

    @Override
    public void draw() {
        System.out.println("绘制一个正方形");
    }
}
  • 下面就是定义了子系统的门面(外观),这个子系统有多个产品组件
class ShapeFacade{
    private Circle circle;
    private Square square;
    public ShapeFacade(){
        circle = new Circle();
        square = new Square();
    }
    public void drawCircle(){
        circle.draw();
    }
    public void drawSquare(){
        square.hashCode();
    }
    public void drawCircleAndSquare(){
        circle.draw();
        square.draw();
    }
}

再比如说, 电脑的例子其实更能理解一点,

电脑整机是CPU、内存、硬盘的外观。有了外观以后,启动电脑和关闭电脑都简化了。直接new一个电脑。在new电脑的同时把cpu、内存、硬盘都初始化好并且接好线。对外暴露方法(启动电脑,关闭电脑)。

启动电脑(按一下电源键):启动CPU、启动内存、启动硬盘

关闭电脑(按一下电源键):关闭硬盘、关闭内存、关闭CPU

1.2  slf4j简介

 SLF4J查了一下单词,他是Simple Logging Facade for Java)其实我觉得每次有专有名词,就查一下完整的英文,更能帮助我理解并且记住这个新知识。

它是一个简单的Java日志门面框架,提供通用的接口,用于访问不同的日志实现,有Log4j、Logback、JCL等。SLF4J的目标是为不同的日志实现提供一个统一的接口,这样我以后就可以在不同的日志实现之间进行无缝切换了。

还有个Log4j,博客我看了一些,还是选择再多看看视频,虽然知道这个是在干啥,但是我习惯了传统的输出方式,对于这个点再多学一下就可以懂的,他说是Log4j可以将日志信息输出到控制台、而且它还支持很多不同的日志格式,像什么HTML、XML、JSON这些。

下面这句话是我看到的大佬总结:在项目中使用了slf4j记录日志,并且绑定了log4j,即导入相应的依赖,则日志会以log4j的风格输出;后期需要改为以logback的风格输出日志,只需要将log4j替换成logback即可,不用修改项目中的代码。

但是不止查到了它的知识,我还发现网上有人说之前log4j2在大概2021年出现过一件大事,特别大的漏洞,也有很多大佬对这个漏洞做了分析。因为这个漏洞太严重,很多厂商都发布了安全公告,提醒用户立刻去升级别的版本。

1.3  通过slf调用log4j

        1.3.1  添加依赖

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>2.0.7</version>
        </dependency>

        1.3.2  创建log4j.properties

 在我那个resources目录里面创建log4j的配置文件log4j.properties。

然后我来分析一下这个配置信息吧

//根日志记录器,参数1为需要输出的日志等级,参数2为日志输出的目标地名称stuout
log4j.rootLogger=DEBUG,stdout,logFile 
//设置stdout是控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
//配置日志输出的格式
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/logs/log.log4j
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

 Log4j输出的目的地

org.apache.log4j.ConsoleAppender(控制台)

org.apache.log4j.FileAppender(文件)

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

        1.3.3  输出日志信息

 下面这两行一定要注意,很容易导错包,因为我自己犯这个错误了,所以还是必须记下来,当时也是不够细心了。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package com.xu.action;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/tests")
public class TestController {
    private static final Logger logger = LoggerFactory.getLogger(TestController.class);

    @RequestMapping("/logs")
    public String log(){
        logger.debug("=====测试日志debug级别打印======");
        logger.info("=====测试日志info级别打印======");
        logger.error("=====测试日志error级别打印======");
        logger.warn("=====测试日志warn级别打印======");
        System.out.println("logs...");
        String str1 = "blog.xu.com";
        String str2 = "blog.csdn.net/xxxx";
        logger.info("=====徐苗苗的个人博客:{}; 徐苗苗的CSDN博客:{}",str1,str2);
        return "success";
    }
    
}

1.4  SpringBoot输出日志

debug: 

true 在 SpringBoot 框架启动时自动输出日志信息,同时显示相互之间的依赖关系。仅仅用于开发阶段,产品阶段一定关闭,或者删除该配置。


切记,在实际项目中,使用 slf4j 作为自己的日志框架。使用 slf4j 记录日 
志非常简单,直接使用 LoggerFactory 创建即可。

        1.4.1  logback

  SpringBoot 针对日志系统默认采用 logback
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Test {
private static final Logger logger = LoggerFactory.getLogger(Test.class);
// ……
}

        1.4.2  application.yml中的日志配置

在Spring Boot应用程序中,我们可以使用application.yml配置文件来配置日志信息。在这个文件中,我们可以设置日志级别、输出目的地、输出格式等。

比如,下面是一个简单的应用程序.yml配置

<span style="color:#050e17"><span style="background-color:#f1f2f2"><span style="background-color:#2b2b2b"><span style="color:#f8f8f2"><code><span style="color:#abe338">logging:</span>
<span style="color:#abe338">  level:</span>
<span style="color:#abe338">    root:</span> INFO
</code></span></span></span></span>

其中,logging表示日志配置的主要属性,level表示日志级别,root表示根日志级别。在这个示例中,根日志级别为INFO,表示只输出INFO及以上级别的日志。

如果我们想要将日志输出到文件,可以在配置文件中添加如下配置:

<span style="color:#050e17"><span style="background-color:#f1f2f2"><span style="background-color:#2b2b2b"><span style="color:#f8f8f2"><code><span style="color:#abe338">logging:</span>
<span style="color:#abe338">  level:</span>
<span style="color:#abe338">    root:</span> INFO
<span style="color:#abe338">  file:</span>
<span style="color:#abe338">    name:</span> myapp.log
</code></span></span></span></span>

这样,日志就会被输出到名为myapp.log的文件中。

        1.4.3  logback.xml配置文件解析

logback.xml是一个用于配置logback日志框架的XML文件。在logback.xml中,我们可以指定日志的输出格式、输出目的地、日志级别等等,以满足不同应用程序的日志需求。

总之,logback.xml是一种非常灵活和强大的日志配置文件格式,通过合理配置可以帮助我们更好地了解应用程序的运行情况,以及快速定位和解决问题。

                a.  定义日志输出格式和存储路径

 使用<编码器>节点来定义日志的输出格式,例如:

<span style="color:#050e17"><span style="background-color:#f1f2f2"><span style="background-color:#2b2b2b"><span style="color:#f8f8f2"><code><span style="color:#ffa07a"><</span><span style="color:#ffa07a">encoder</span><span style="color:#ffa07a">></span>
  <span style="color:#ffa07a"><</span><span style="color:#ffa07a">pattern</span><span style="color:#ffa07a">></span>%d<span style="color:#ffa07a">{yyyy-MM-dd HH:mm:ss.SSS}</span> [%thread] %-5level %logger<span style="color:#ffa07a">{36}</span> - %msg%n<span style="color:#ffa07a"></</span><span style="color:#ffa07a">pattern</span><span style="color:#ffa07a">></span>
<span style="color:#ffa07a"></</span><span style="color:#ffa07a">encoder</span><span style="color:#ffa07a">></span></code></span></span></span></span>

               

使用<追加器>节点来定义日志的存储路径,例如:

<span style="color:#050e17"><span style="background-color:#f1f2f2"><span style="background-color:#2b2b2b"><span style="color:#f8f8f2"><code><appender name=<span style="color:#abe338">"FILE"</span> <span style="color:#dcc6e0">class</span>="<span style="color:#abe338">ch</span>.<span style="color:#abe338">qos</span>.<span style="color:#abe338">logback</span>.<span style="color:#abe338">core</span>.<span style="color:#abe338">rolling</span>.<span style="color:#abe338">RollingFileAppender</span>">
  <<span style="color:#abe338">file</span>>/<span style="color:#abe338">path</span>/<span style="color:#abe338">to</span>/<span style="color:#abe338">logs</span>/<span style="color:#abe338">myapp</span>.<span style="color:#abe338">log</span></<span style="color:#abe338">file</span>>
  <<span style="color:#abe338">rollingPolicy</span> <span style="color:#abe338">class</span>="<span style="color:#abe338">ch</span>.<span style="color:#abe338">qos</span>.<span style="color:#abe338">logback</span>.<span style="color:#abe338">core</span>.<span style="color:#abe338">rolling</span>.<span style="color:#abe338">TimeBasedRollingPolicy</span>">
    <<span style="color:#abe338">fileNamePattern</span>>/<span style="color:#abe338">path</span>/<span style="color:#abe338">to</span>/<span style="color:#abe338">logs</span>/<span style="color:#abe338">myapp</span>.%<span style="color:#abe338">d</span>{yyyy-MM-dd}.log</fileNamePattern>
  </rollingPolicy>
  <encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %<span style="color:#f5ab35">-5</span>level %logger{<span style="color:#f5ab35">36</span>} - %msg%n</pattern>
  </encoder>
</appender></code></span></span></span></span>

b.  定义控制台输出

<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder><!-- 按照上面配置的 LOG_PATTERN 来打印日志 -->
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
</configuration>

在logback.xml文件中,我们可以使用<追加器>节点来设置日志的输出目的地,例如控制台输出。将控制台输出定义为一个名为CONSOLE的appender,类型为ConsoleAppender,表示输出到控制台。为了使输出的日志信息更清晰一点儿和方便阅读,可以使用预定义的输出格式LOG_PATTERN来格式化日志信息,然后通过${}引用该格式即可。

                c.   定义日志文件的相关参数

在logback.xml文件中,我们可以使用<追加器>节点来定义日志文件的相关参数

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <file>/path/to/logs/myapp.log</file>
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>/path/to/logs/myapp.%d{yyyy-MM-dd}.log</fileNamePattern>
    <maxHistory>30</maxHistory>
  </rollingPolicy>
  <encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
  </encoder>
</appender>

        1.4.4  使用Logger打印日志

在代码中一般使用 Logger 对象来打印出一些 log 信息,可以指定打印出的日志级别,也支持占位符,很方便的。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
private final static Logger logger = LoggerFactory.getLogger(TestController.class);
@RequestMapping("/log")
public String testLog() {
logger.debug("=====测试日志 debug 级别打印====");
logger.info("======测试日志 info 级别打印=====");
logger.error("=====测试日志 error 级别打印====");
logger.warn("======测试日志 warn 级别打印=====");
// 可以使用占位符打印出一些参数信息
String str1 = "blog.yan.com";
String str2 = "blog.csdn.net/yanjun";

// 输出日志内容时,允许使用{}表示一个占位符,后续参数按照位置对应进行赋值
logger.info("======闫峻的个人博客:{};闫峻的 CSDN 博客:{}", str1, str2);
return "success";
}
}

二、项目配置

2.1  情景一:只有少量配置

在logback.xml文件中,如果只需要配置少量的信息,可以使用最简单的配置方式,例如:

<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="INFO">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

这种简单的配置方式适用于应用程序比较小,只需要输出到控制台并且不需要滚动日志的情形。如果需要更多的配置选项,可以使用更复杂的配置方式。

2.2  情景二:有多个配置

在logback.xml文件中,如果需要配置多个信息,可以使用更复杂的配置方式,例如:```

<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>/path/to/logs/myapp.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>/path/to/logs/myapp.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <logger name="com.example" level="DEBUG">
    <appender-ref ref="FILE" />
  </logger>

  <root level="INFO">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

这种复杂的配置方式适用于应用程序比较大,需要输出到多个输出目的地并且需要更复杂的日志管理的情形。根据实际需要,可以灵活地添加和修改<appender>和<logger>元素,以满足日志管理的需要。

2.3  指定项目配置文件

在实际项目中,一般有两个环境:开发环境和生产环境。

开发环境中的配置和生产环境中的配置是不同的哈,例如有环境、端口、数据库、相关地址等。实际上不可能在开发环境调试好之后,就部署到生产环境后,又要将配置信息全部修改成生产环境上的配置,这样太麻烦了。


我认为最好的解决方法就是开发环境和生产环境都有一套对用的配置信息,然后在开发的时候,指定读取开发环境的配置,把项目部署到服务器上,再指定去读取生产环境的配置。

三、MVC支持

Spring Boot 的 MVC 支持主要来最常用的几个注解,包括@RestController 用于声明控制器、@RequestMapping用于实现方法映射地址、@PathVariable 用于接受路径中的参数、@RequestParam 用于接受 request 请求中的参数以及@RequestBody 用于接受 application/json 类型的请求信息。
以下是几个注解常用的使用方式和特点:

3.1  @RestController

@RestController 是 Spring Boot 新增加的一个注解,相当于@Controller+@ResponseBody
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
String value() default "";
}
可以看出@RestController 注解包含了原来的@Controller 和@ResponseBody 注解,使用过 Spring 的对@Controller 注解已经非常了解了,@ResponseBody 注解是将返回的数据结构转换为 Json 格式。


@RestController可以看作是@Controller和@ResponseBody的结合体,为了编码方便建议使用@RestController后就不用再使用@Controller 了。@Controller 则返回的是逻辑地址名。

如果使用@Controller 注解则表示返回一个逻辑地址名 user 字符串,需要依赖于 ViewResovler 组件将逻辑地址名称转换为物理地址。在 Spring Boot 集成 Thymeleaf 模板引擎中会使用。


spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html


如果使用@Controller,方法的返回值是字符串 user,则前后缀自动生效,将逻辑地址名
user 转换为物理地址名/user.html,静态页面默认存储位置可以考虑使用resources/static 目录

3.2  @RequestMapping

@RequestMapping 是一个用来处理请求地址映射的注解,它可以用于类上,也可以用于方法上。在类的级别上的注解会将一个特定请求或者请求模式映射到一个控制器之上,表示类中的所有响应请求的方法都是以该地址作为父路径;在方法的级别表示进一步指定到处理方法的映射关系。

@Controller
@RequestMapping("/test") 表示当前类中每个方法映射路径的统一前缀/test
public class TestController {
@RequestMapping("/get") 针对方法的映射,加上类上的映射配置,则当前方法
的请求地址为/test/get
public String get(){
return "user";
}
}

3.3  @PathVariable

@PathVariable 注解主要是用来获取 url 参数,Spring Boot 支持 restfull 风格的 url,比如一个 GET 请求携带一个参数 id 过来 localhost:8080/user?id=123,可以将 id 作为参数接收,注解使用@RequestParam。


注意问题:如果想要 url 中占位符中的{id}值直接赋值到参数 id 中,需要保证 url 中的参数和方
法接收参数一致,否则就无法接收。如果不一样的话,其实也可以解决,需要用@PathVariable 中的 value 属性来指定对应关系。

@RequestMapping("/user/{idd}")
public String testPathVariable(@PathVariable(value = "idd") Integer id) {

System.out.println("获取到的 id 为:" + id);
return "success";
}


对于访问的 url,占位符的位置可以在任何位置,不一定非要在最后,比如这样也行/xxx/{id}/user。另外 url也支持多个占位符,方法参数使用同样数量的参数来接收,原理和一个参数是一样的
@GetMapping("/user/{idd}/{name}") 例如对应的请求地址为 localhost:8080/user/123/abc,按照位置对应的 idd=123,name=abc。


 

public String testPathVariable(@PathVariable(value = "idd") Integer id, @PathVariable String name) {
System.out.println("获取到的 id 为:" + id);
System.out.println("获取到的 name 为:" + name);
return "success";
}

3.4  @RequestParam

@RequestParam 和 @PathValiable 注解一样也都是获取请求参数的。
@RequestParam @PathVariable不同:
@PathValiable 是从 url 模板中获取参数值, 即这种风格的 url http://localhost:8080/user/{id}
@RequestParam 是从 request 里面获取参数值,即这 种风格的 http://localhost:8080/user?id=1
如果参数不是 String 类型,就会自动执行数据类型转换
public String testRequestParam(@RequestParam Integer id) {
System.out.println("获取到的 id 为:" + id);
return "success";
}
可以正确的从控制台打印出 id 信息。  url 上面的参数和方法的参数需要一样,如果不一样,也需要
使用 value 属性来说明。
具体测试:
可以使用 postman 来模拟一下表单提交,测试一下接口。但是如果表单数据很多,不可能在后台
方法中写上很多参数,每个参数还要 @RequestParam 注解。针对这种情况,需要封装一个实体类来接收这些 参数,实体中的属性名和表单中的参数名一致就行了!!!
 
public class User {
private String username;
private String password;
// set get
}
使用实体接收的话,不能在前面加 @RequestParam 注解了,直接使用!
 
@PostMapping("/form2")
public String testForm(User user) {
System.out.println("获取到的 username 为:" + user.getUsername());
System.out.println("获取到的 password 为:" + user.getPassword());
return "success";
}
如果写成 public String testForm(User user String username) 则提交的请求参数 username 的值会赋值两个 地址,一个 user 中的 username 属性;
另一个是方法的参数 username 可以使用 postman 再次测试一下表单提交,观察一下返回值和控制台打印出的日志即可。
在我见到的实际项目中,一 般都是封装一个实体类来接收表单数据,因为实际项目中表单数据一般都很多。

3.5  @RequestBody

@RequestBody 注解用于接收前端传来的实体,接收参数也是对应的实体,
使用 @RequestBody 接收会非常方便。
public class User {
private String username;
private String password;
// set get
}

 

控制器中方法的定义


@PostMapping("/user")
public String testRequestBody(@RequestBody User user) {
System.out.println("获取到的 username 为:" + user.getUsername());
System.out.println("获取到的 password 为:" + user.getPassword());
return "success";
}
然后使用  postman 工具来测试一下效果,打开 postman 后输入请求地址和参数,参数用 json 来模拟,调用 之后返回 success
同时看一下后台控制台输出的日志:
获取到的 username 为:徐苗
获取到的 password 为: 123456
可以看出, @RequestBody 注解用于 POST 请求上,接收 json 实体参数。它和上面表单提交有点类似,只不过 参数的格式不同,一个是 json 实体,一个是表单提交。
在实际项目中根据具体场景和需要使用对应的注解就OK!!!!!

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

SpringBoot用slf4j日志 及其 项目配置、MVC支持 的相关文章

随机推荐

  • CSDN-markdown编辑器

    这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题 有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中 居左 居右 Sma
  • 使用高德地图 vue-amap 中遇到的问题

    1 搜索组件进行搜索的时候 无论搜索哪个城市 地图一直固定在一个城市 我的是深圳
  • 基于Docker环境安装ElasticSearch

    1 搜索技术 搜索技术在我们日常生活的方方面面都会用到 例如 综合搜索网站 百度 谷歌等 电商网站 京东 淘宝的商品搜索 软件内数据搜索 我们用的开发工具 如Idea的搜索功能 这些搜索业务有一些可以使用数据库来完成 有一些却不行 因此我们
  • 【Java进阶篇】—— File类与IO流

    一 File类的使用 1 1 概述 File 类以及本章中的各种流都定义在 java io 包下 一个File对象代表硬盘或网络中可能存在的一个文件或文件夹 文件目录 File 能新建 删除 重命名 文件和目录 但 File不能访问文件内容
  • 数据结构视频教程 -《[北风网]C#版数据结构与算法高级教程》

    整个视频打包下载地址 史上最全的数据结构视频教程系列分享之 北风网 C 版数据结构与算法高级教程 转载请保留出处和链接 更多优秀资源请访问 我是码农 数据结构是计算机存储 组织数据的方式 数据结构是指相互之间存在一种或多种特定关系的数据元素
  • Redis可视化工具无法连接Redis(安装在服务器上面)的解决方案

    redis可视化工具连接安装在阿里云上面的redis时 一直连接不上 你可以按下面三步去完美解决 第一 确保redis正常启动 我这主要解决redis可视化工具无法连接redis哈 具体redis安装我就不讲了奥 首先通过指令 cd usr
  • 区块链共识机制技术一——POW(工作量证明)共识机制

    什么是共识机制 所谓 共识机制 是通过特殊节点的投票 在很短的时间内完成对交易的验证和确认 对一笔交易 如果利益不相干的若干个节点能够达成共识 我们就可以认为全网对此也能够达成共识 区块链作为一个去中心化的分布式账本系统 然而在实际运行中
  • RPC通信基本原理 -- 浅析RPC远程过程调用基本原理

    一 RPC基本概念 1 1 RPC简介 RPC 的全称是 Remote Procedure Call是一种进程间通信方式 RPC只是一个概念 而不是具体的协议或框架 它允许程序调用另一个地址空间 通常是共享网络的另一台机器上 的过程或函数
  • 应用布尔盲注来爆库(1)

    先上道练习题Less 8 打开sqli labs项目的练习题Less 8 http 192 168 3 2 sqli labs Less 8 然后输入id 1参数 可以得到以下信息 输入有效id 1时 只提示成功 You are in 没有
  • 基於RISC-V QEMU 仿真運行Linux 系統環境搭建

    前言 文章詳細說明如何從堶零開始基於RISC V QEMU 仿真運行Linux 系統環境搭建 是Linux 小白入門教程不二之選 歡迎留言討論 轉發請注明原文出處 1 準備QEMU 仿真環境 RISC V 64bits 安裝包下載地址 ht
  • 【华为OD机试】猴子爬山 (C++ Python Java)2023 B卷

    时间限制 C C 1秒 其他语言 2秒 空间限制 C C 262144K 其他语言524288K 64bit IO Format lld 语言限定 C clang11 C clang 11 Pascal fpc 3 0 2 Java jav
  • 红米Note 4超简单刷成开发版获取ROOT权限的流程

    小米的设备不同手机型号一般miui论坛都提供两个不同的系统 可分为稳定版和开发版 稳定版没有提供root超级权限管理 开发版中就开启了root超级权限 较多时候我们需要使用的一些功能强大的应用 都需要在root超级权限下工作 举个栗子我们团
  • python 列表(list)排序

    使用python的sorted函数 可对列表进行排序 该函数默认从小到大排序 1 列表中为普通元素 a 80 85 90 100 a sorted a sorted函数默认从小到大排序 print a 输出结果 80 85 90 100 倒
  • RIA项目失败的教训

    作者 Abel Avram 译者 崔康 发布于 2009年7月22日 上午11时6分 社区 Architecture Java 主题 可用性 用户界面 RIA 富客户端 桌面 EffectiveUI公司主席Anthony Franco最近做
  • MySQL Note

    一 MySQL动作关键字 1 1 create 用途 创建index procedure function schema table 语法 index create unique fulltext spatial index index n
  • Vim知识详解

    这是一个笔记 Shift Lock 大小写锁定键没有按下 正常模式 按ESC处于正常模式 移动光标 q 丢弃改动并退出 x 删除当前字符 i 在当前光标插入文本 a 在句子最后添加文本 wq 保存文件以退出 dw 从光标处删除至一个单词的末
  • Matlab实现电动汽车系列仿真(附上多个完整仿真源码+数据)

    Matlab是一种功能强大的数学软件 可以用于实现各种仿真模型和算法 在本文中 我们将介绍如何使用Matlab来实现电动汽车系列仿真 说明 首先 我们需要定义电动汽车的物理模型 电动汽车的物理模型可以包括电池 电动机 传动系统和车辆动力学模
  • Microsoft Store打不开解决办法

    1 打开 运行 输入 inetcpl cpl 或者 WINDOWS R 键 输入 inetcpl cpl亦可 2 点开高级往下拉 勾上 使用TLS 1 2 选项 或者点还原高级设置 3 打开Microsoft Store刷新页面可成功打开
  • #define相关语法

    跨行的宏定义 跨行宏定义使用反斜杠 连接 define YW GPIO ERR do printk yw gpio err d LINE printk VA ARGS while 0 使用 功能 用来把参数转化成字符串 示例代码 defin
  • SpringBoot用slf4j日志 及其 项目配置、MVC支持

    一 Slf4j日志的使用 我一直以来用的都是最传统的System out println 来打印一些错误信息时 其实我也面临过一些问题 这样做的话 错误信息和别的输出结果混在一起 我一直都很难从结果里面找到我调试出来的问题 而且我用这种传统