SpringBoot快速实践 --Ⅰ

news2024/10/6 23:21:50

文章目录

  • 启动一个SpringBoot项目
  • 如何替换内嵌容器
  • 玩转SpringBoot配置
  • 全局异常处理
  • 过滤器
  • 拦截器
  • 使用Lombok简洁代码
  • 使用IDEA HTTP Client进行接口调试

启动一个SpringBoot项目

如果你觉得使用官网来创建太慢了,那你直接把以前项目的依赖粘过来就行了:

一个是父工程的依赖:

    <!--指定了一个父工程,父工程中的东西在该工程中可以继承过来使用-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
    </parent>
    <!--JDK 的版本-->
    <properties>
        <java.version>8</java.version>
    </properties>

一个是常用的web依赖和测试依赖:

    <dependencies>
        <!--该依赖就是我们在创建 SpringBoot 工程勾选的那个 Spring Web 产生的-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--这个是单元测试的依赖,我们现在没有进行单元测试,所以这个依赖现在可以没有-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

最后一个是打包的插件:

    <build>
        <plugins>
            <!--这个插件是在打包时需要的,而这里暂时还没有用到-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

然后写一个启动类就行,这里为了效果,我再写一个Controller:

@SpringBootApplication
@RestController
public class MyApplication  {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class,args);
    }

    @GetMapping("/hello")
    public String test1(){
        System.out.println(123);
        return "123";
    }
}

注意:

  • 类名没有啥要求
  • 该类不能放在默认包中,也就是说你直接放在java包下,它会显示Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.

至于打包发布,直接maven package就行,然后在对应的目录java -jar即可。前提是要有我们上面那个打包插件,否则会运行不了
这个插件的作用:

  • 把项目打包成一个可执行的超级JAR(uber-JAR),包括把应用程序的所有依赖打入JAR文件内,并为JAR添加一个描述文件,其中的内容能让你用java -jar来运行应用程序。
  • 搜索public static void main()方法来标记为可运行类。

如何替换内嵌容器

spring-boot-starter-web默认集成了tomcat,假如我们想把它换为jetty,可以在pom.xml中spring-boot-starter-web下排除tomcat依赖,然后手动引入jetty依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
</dependencies>

在这里插入图片描述

玩转SpringBoot配置

在SpringBoot中有如下几种配置形式:

  • 全局配置文件(一般名为application.xxx,xxx可以为properties、yml、yaml)
  • 自定义配置文件 + @PropertySource(作用是将指定的属性文件加载到环境中,这样才使@Value、@ConfigurationProperties等注解能使用其中的属性进行值的注入。)
  • 命令行配置
  • xml配置(基本不用)
  • profile多环境配置
  • 外部配置文件

读取配置文件的形式:

  • @Value(${xxx})
  • Environment对象
  • 自定义对象 + @ConfigurationProperties(在bean定义中指定外部化配置的来源)

注意:

  • @EnableConfigurationProperties注解是一个组合注解,它包含@Import注解(一个用来导入其他组件或者配置类到当前Spring容器中的注解),它的作用是将标注了@ConfigurationProperties的配置类导入Spring容器(也就是说如果标注了@ConfigurationProperties的配置类已经在容器中了,那么就不需要这个注解)。这样一来,自定义的配置类就被加载到了Spring上下文中,它的properties就会被绑定对应的ConfigurationProperties类。
  • @ConfigurationProperties允许我们在bean定义中指定外部化配置的来源。

提一嘴:
@ConfigurationProperties(prefix=“xxx”)和@ConfigurationProperties(“xxx”)是一个效果,我们可以看看源码:
在这里插入图片描述
@AliasFor注解的作用就是可以给一个属性创建一个别名,从而绑定到同一个外部属性上。

application全局配置文件能配置的属性:
application.properties中可配置所有官方属性

接下来我们一个个演示一下:

全局配置文件

这里我们使用@Value以及自定义对象的形式去拿到属性值:

server.port=8888

属性类:

@Component
@ConfigurationProperties(prefix="server")
public class PortConfig {
    private int port;

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}
@SpringBootApplication
@RestController
public class MyApplication  {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication();

        SpringApplication.run(MyApplication.class,args);
    }


    @Value("${server.port}")
    private int port;

    @Resource
    private PortConfig portConfig;

    @GetMapping("/hello")
    public String test1(){
        System.out.println(port);  //结果8888
        System.out.println(portConfig.getPort());  //结果8888
        return "123";
    }
}

自定义配置文件

这里我创建一个自定义的配置文件myapplication.yaml:

server:
  port: 8888

我们要读取他,首先就要将这个配置文件加入到上下文中,那么就要使用到@PropertySource这个注解。这里有两个注意点:

第一个就是@PropertySource搜索区间问题

@PropertySource 默认是在以下三个地方搜索配置文件:

  1. FileSystem : 先搜索文件系统里指定的路径。
  2. ClassPath : 如果文件系统里没找到,那么搜索类路径里指定的路径。
  3. Environment : 如果类路径里没找到,那么搜索系统当前环境变量里指定的。

注意你必须标明是哪一类中去寻找,他并没有找不到就切换区间尝试的机制。

这也就是为什么我们一般在使用这个注解的时候会在前面加上classpath:

@PropertySource("classpath:myapplication.yaml")

当然这里我们这样还是读取不到配置文件的,接下来我们再看第二点:SpringBoot中@PropertySource的默认实现是properties类型文件的解析

我们自定义的配置文件使用的是yaml类型的,所以这里是没办法解析的,解决办法就是:实现PropertySourceFactory接口,实现一个解析yaml文件的工具类。

public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String s, EncodedResource encodedResource) throws IOException {
        return new YamlPropertySourceLoader().load(s,encodedResource.getResource()).get(0);
    }
}

接下来我们使用Environment的方法去读取:

@SpringBootApplication
@RestController
@PropertySource(value = "classpath:myapplication.yaml",factory = YamlPropertySourceFactory.class)
public class MyApplication  {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class,args);
    }

    @Value("${server.port}")
    private int port;

    @Resource
    private PortConfig portConfig;

    @Resource
    private Environment environment;

    @GetMapping("/hello")
    public String test1(){
        System.out.println(port);  //结果8888
        System.out.println(portConfig.getPort());  //结果8888
        System.out.println(environment.getProperty("server.port"));  //结果8888
        return "123";
    }
}

命令行配置

在运行Spring Boot jar文件时,可以使用命令java -jar xxx.jar --server.port=8081来改变端口的值。这条命令等价于我们手动到application.properties中修改(如果没有这条属性的话就添加)server.port属性的值为8081

在这里插入图片描述

如果不想项目的配置被命令行修改,可以在入口文件的main方法中进行如下设置:

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(Application.class);
    app.setAddCommandLineProperties(false);
    app.run(args);
}

profile多环境配置

Profile用来针对不同的环境下使用不同的配置文件,多环境配置文件必须以application-{profile}.{properties|yml|yaml}的格式命名,其中{profile}为环境标识。

至于哪个具体的配置文件会被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。

如:spring.profiles.active=dev就会加载application-dev.properties配置文件内容。可以在运行jar文件的时候使用命令java -jar xxx.jar --spring.profiles.active={profile}切换不同的环境配置。

我们来演示一下:

application-dev.properties:

server.port=8888

application-prod.properties:

server.port=9999

在这里插入图片描述

外部配置文件

在前一种情况的基础上,我们在当前jar包的同一目录下放一个配置文件application.properties:
在这里插入图片描述
内容如下:

spring.profiles.active=prod

然后我们运行jar包,这次我们不添加命令行参数:

在这里插入图片描述

全局异常处理

这里我们就介绍一种最常用的方式 @ControllerAdvice+@ExceptionHandler处理全局异常:

@RestController
public class ExceptionTestController {

    @GetMapping("/ex")
    public String testException(){
    	//抛出一个自定义的异常
        throw new MyException();
    }
}
//assignableTypes指定处理哪个Controller中的异常,不加代表处理所有Controller
@ControllerAdvice(assignableTypes = {ExceptionTestController.class}) 
public class MyExceptionHandler {
	
	//指定处理哪一类异常
    @ExceptionHandler(Exception.class)
    //返回Json数据
    @ResponseBody
    //指定异常处理方法返回的HTTP状态码
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Map<String, Object> handleUserNotExistsException(Exception e) {
        Map<String, Object> map = new HashMap<>();
        map.put("message", e.getMessage());
        return map;
    }
}

过滤器

首先我们用最简单的话弄清楚过滤器和拦截器的区别:

  • 归属不同:Filter(过滤器)属于Servlet技术,Interceptor(拦截器)属于SpringMVC技术
  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
  • 使用场景不同:
    在这里插入图片描述

在这里插入图片描述

这里我们先说说过滤器怎么实现,两种方式:

  • 手动配置
  • @WebFilter

第一种

我们首先实现一个自己的Filter:


public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("当前请求的ip地址为" + servletRequest.getLocalAddr());
        //对请求进行放行
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

然后再配置类中进行Filter注册:

@Configuration
public class ApplicationConfig {

    @Bean
    public FilterRegistrationBean<MyFilter> filterFilterRegistrationBean(){
        FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new MyFilter());
        //可以使用filterRegistrationBean.setUrlPatterns配置要拦截的路径
        return filterRegistrationBean;
    }
}

如果有多个Filter,想定义顺序:

在这里插入图片描述

第二种

在自己的过滤器的类上加上@WebFilter 然后在这个注解中通过它提供好的一些参数进行配置

@WebFilter(filterName = "MyFilter",urlPatterns = "/*")
//这里的urlPatterns支持的是Ant风格的路径
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("当前请求的ip地址为" + servletRequest.getLocalAddr());
        //对请求进行放行
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

另外,为了能让 Spring 找到它,你需要在启动类上加上 @ServletComponentScan 注解

在这里插入图片描述

拦截器

如果你需要自定义 Interceptor 的话必须实现 org.springframework.web.servlet.HandlerInterceptor接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter类,并且需要重写下面下面3个方法:

public boolean preHandle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object handler)
 
 
public void postHandle(HttpServletRequest request,
                       HttpServletResponse response,
                       Object handler,  //就是控制器方法HandlerMethod
                       ModelAndView modelAndView)
 
 
public void afterCompletion(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler,
                            Exception ex)

注意: preHandle方法返回 true或 false。如果返回 true,则意味着请求将继续到达 Controller 被处理。

处理顺序如下:
在这里插入图片描述

注意:postHandle只有当被拦截的方法没有抛出异常成功时才会处理,afterCompletion方法无论被拦截的方法抛出异常与否都会执行。

我们演示一下:

先自定义一个拦截器

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(handler.toString());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

然后再配置类中添加拦截器:

@Configuration
public class ApplicationConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }
}

使用Lombok简洁代码

Lombok是一个Java库,它通过注解的方式来简化Java代码的编写。它的实现原理主要是通过在编译阶段的注解处理器来处理被Lombok注解标记的代码,并在编译过程中生成相应的Java代码。

具体来说,当使用Lombok注解标记一个类、字段或方法时,编译器会在编译阶段将这些被注解标记的代码传递给Lombok的注解处理器。注解处理器会根据注解的类型和参数,生成相应的Java代码,并将生成的代码插入到编译后的Java文件中。

需要注意的是,Lombok生成的代码是在编译阶段完成的,所以在源代码中看不到生成的代码。但在编译后的.class文件中,可以看到Lombok生成的代码已经被插入到相应的位置。这样,生成的代码就可以在运行时被正常调用和使用。

Lombok的注解处理器是以插件的形式集成到Java编译器中的。当使用Lombok库时,IDE或构建工具会将Lombok的注解处理器添加到编译器的处理器列表中。这样,在编译Java代码时,编译器会自动调用Lombok的注解处理器来处理被Lombok注解标记的代码。

需要注意的是,为了使Lombok的注解处理器正常工作,需要在使用Lombok的项目中添加Lombok库的依赖。这样,编译器才能正确识别和处理Lombok的注解。

所以要使用Lombok我们除了添加依赖之外,还要在自己的IDEA中安装lombok的插件:

在这里插入图片描述

<!-- 引入 Lombok 依赖 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

接下来我们看看这个lombok具体怎么用:

  • @Getter 注解,添加在类或属性上,生成对应的 get 方法。

  • @Setter 注解,添加在类或属性上,生成对应的 set 方法。

  • @ToString 注解,添加在类上,生成 toString 方法。

  • @EqualsAndHashCode 注解,添加在类上,生成 equals 和 hashCode 方法。

  • @AllArgsConstructor、@RequiredArgsConstructor、@NoArgsConstructor 注解,添加在类上,为类自动生成对应参数的构造方法。

  • @Data 注解,添加在类上,是 5 个 Lombok 注解的组合。

    • 为所有属性,添加 @Getter、@ToString、@EqualsAndHashCode 注解的效果
    • 为非 final 修饰的属性,添加 @Setter 注解的效果
    • 为 final 修改的属性,添加 @RequiredArgsConstructor 注解的效果
  • @Value 注解,添加在类上,和 @Data 注解类似,区别在于它会把所有属性默认定义为 private final 修饰,所以不会生成 set 方法。

  • @CommonsLog、@Flogger、@Log、@JBossLog、@Log4j、@Log4j2、@Slf4j、@Slf4jX 注解,添加在类上,自动为类添加对应的日志支持。

  • @NonNull 注解,添加在方法参数、类属性上,用于自动生成 null 参数检查。若确实是 null 时,抛出 NullPointerException 异常。

  • @Cleanup 注解,添加在方法中的局部变量上,在作用域结束时会自动调用 #close() 方法,来释放资源。例如说,使用在 Java IO 流操作的时候。

  • @Builder 注解,添加在类上,给该类加个构造者模式 Builder 内部类。

  • @Synchronized 注解,添加在方法上,添加同步锁。

  • @SneakyThrows 注解,添加在方法上,给该方法添加 try catch 代码块。

  • @Accessors 注解,添加在方法或属性上,并设置 chain = true,实现链式编程。

我们来看看其中三个比较常用的: @Data 和 @Slf4j、@NonNull

@Data

@Data
public class Person {
    private String name;
    private int age;

}
@EqualsAndHashCode(callSuper = true)
@Data
@ToString(callSuper = true)
public class Student extends Person{
    private int studyId;
    private int className;
}

反编译后的Student类:

public class Student extends Person {
    private int studyId;
    private int className;

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Student)) {
            return false;
        } else {
            Student other = (Student)o;
            if (!other.canEqual(this)) {
                return false;
            } else if (!super.equals(o)) {
                return false;
            } else if (this.getStudyId() != other.getStudyId()) {
                return false;
            } else {
                return this.getClassName() == other.getClassName();
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Student;
    }

    public int hashCode() {
        int PRIME = true;
        int result = super.hashCode();
        result = result * 59 + this.getStudyId();
        result = result * 59 + this.getClassName();
        return result;
    }

    public Student() {
    }

    public int getStudyId() {
        return this.studyId;
    }

    public int getClassName() {
        return this.className;
    }

    public void setStudyId(final int studyId) {
        this.studyId = studyId;
    }

    public void setClassName(final int className) {
        this.className = className;
    }

    public String toString() {
        return "Student(super=" + super.toString() + ", studyId=" + this.getStudyId() + ", className=" + this.getClassName() + ")";
    }
}

如果使用 @Data 注解的类,继承成了其它父类的属性,最好额外添加 @ToString(callSuper = true) 和 @EqualsAndHashCode(callSuper = true) 注解。因为默认情况下,@Data 注解不会处理父类的属性。所以需要我们通过 callSuper = true 属性,声明需要调用父类对应的方法。

@Slf4j

@Slf4j 注解,添加在类上,给该类创建 Slf4j Logger 静态属性。

在这里插入图片描述

@NonNull 注解

@NonNull 注解,添加在方法参数、类属性上,用于自动生成 null 参数检查。若确实是 null 时,抛出 NullPointerException 异常。

在这里插入图片描述

使用IDEA HTTP Client进行接口调试

在这里插入图片描述

其好处就是: IDEA HTTP Client 采用后缀为 .http 的文本文件,可以和 Java 代码一起使用 Git 进行版本管理,从而实现团队协作的共享。同时因为内置在了IDEA中,不需要切换软件去进行接口测试,比较方便。

.http文件我们在Idea中右键就可以创建,也可以直接在Controller中自动生成:
在这里插入图片描述

进去之后可以看到右上角有几个选项,示意如下:
在这里插入图片描述

首先我们来说明三种比较常见的情况:

  • GET 请求
  • POST 请求 + Form
  • POST 请求 + JSON

POST 请求 + Form

@PostMapping("/user/login")
public Map<String, Object> login(@RequestParam("username") String username,
                                 @RequestParam("password") String password) {
    if ("yudaoyuanma".equals(username) && "123456".equals(password)) {
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("userId", 1);
        tokenMap.put("token", "token001");
        return tokenMap;
    }
    throw new RuntimeException("小朋友,你的账号密码不正确哟!");
}

对应的 IDEA HTTP Client 的代码如下:
在这里插入图片描述

### 测试 /user/login:登陆成功
POST http://127.0.0.1:8080/user/login
Content-Type: application/x-www-form-urlencoded

username=yudaoyuanma&password=123456

POST 请求 + JSON

@PostMapping("/user/update")
public Boolean update(@RequestBody UserUpdateVO updateVO) {
    logger.info("[update][收到更新请求:{}]", updateVO.toString());
    return true;
}

对应的 IDEA HTTP Client 的代码如下:

在这里插入图片描述

### 测试 /user/update:更新成功
POST http://127.0.0.1:8080/user/update
Content-Type: application/json

{
  "nickname": "我是昵称",
  "gender": 1
}

GET 请求

@GetMapping("/user/get-current")
public Map<String, Object> getCurrentUser(@RequestHeader("Authorization") String authorization,
                                          @RequestParam("full") boolean full) {
    if ("token001".equals(authorization)) {
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("id", 1);
        // full 为 true 时,获得完整信息
        if (full) {
            userInfo.put("nickname", "芋道源码");
            userInfo.put("gender", 1);
        }
        return userInfo;
    }
    throw new RuntimeException("小朋友,你没有登录哟!");
}

对应的 IDEA HTTP Client 的代码如下:

在这里插入图片描述

### 测试 /user/get-current:获取成功
GET http://127.0.0.1:8080/user/get-current?full=true
Authorization: token001

如果想要了解更多,可以参考下面的文章:
芋道 Spring Boot API 接口调试 IDEA HTTP Client

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/742755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytorch LBFGS

LBFGS pytorch的LBFGS也是一个优化器 但是与一般的优化器不同 平常我们的顺序是 losscriterion(predict, gt) optim.zero_grad() loss.backward() optim.step()而LBFGS是 def closure():optim.zero_grad()loss criterion(predict, gt)loss.backward()return lossoptim.step…

5.EFLK(ELK+filebeat)+filter过滤

文章目录 EFLK&#xff08;ELKfilebeat&#xff09;部署filebeat修改配置文件logstash配置 logstash的filter过滤grok(正则捕获插件)内置正则表达式调用自定义表达式 mutate(数据修改插件)重命名字段添加字段删除字段转换数据类型替换字段内容以"|"为分割符拆分数据成…

系统升级丨让VR全景制作简单再简单

最高端的VR全景 往往只需要最朴素的制作方式 酷雷曼3D VR数字化升级平台4.0版本 闪耀上线 全新的后台界面 丝滑的编辑工具 无需代码 不用建模 简单拖拉拽移 依然有手就行 轻松搭建VR元宇宙空间 1、界面升级&#xff0c;让VR创作更加可视 全新视觉设计 酷雷曼3D VR…

【必读】未来八大最具潜力行业!看懂就赚了

1 网络安全行业 现在保护“网络安全”已经成为世界各国的重要共识。有专家表示&#xff0c;未来网络安全行业有望超越金融、地产业成最赚钱行业。 2 动漫行业 我国的动漫产业才刚刚起步&#xff0c;现在全国各地如北京、上海、杭州、大连、深圳、广州等城市均建立起动漫产业…

2023年中总结:未到年末,立的Flag就已实现

前言 去年年末&#xff0c;搞了一篇年终总结&#xff0c;立了一个小小的Flag&#xff0c;2023年实现全网粉丝量突破1.5万&#xff0c;可以很负责任的告诉大家&#xff0c;截至到当前&#xff0c;不仅已经实现&#xff0c;而且超额完成&#xff0c;虽然这个量&#xff0c;很低&a…

【目标检测】基于yolov5的道路坑洼检测(附代码和数据集)

写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 路虽远,行则将至;事虽难,做则必成。只要有愚公移山的志气、滴水穿石的毅力,脚踏实地,埋头苦干,积跬步以至千里,就…

《TCP/IP网络编程》第3,4章学习记录

基础知识&#xff1a; struct sockaddr_in {sa_family_t sin_family; //地址族&#xff08;Address Family)uint16_t sin_port; //16位TCP/UDP端口号struct in_addr sin_addr; //32位IP地址char sin_zero[8]; //不使用 }sa_family_t包括&#xff1a; (1)AF_INET,IPv4网络协议…

【Linux】分布式监控 Zabbix

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Zabbix 介绍zabbix 概述Zabbix 监控原理Zabbix 6.0 新特性Zabbix 6.0 功能组件 Zabbix 6.0 部署Zabbix 添加客户端主机Zabbix 自定义监控内容Zabbix 自动发现与自动…

2.1、修改Gitea上传附件大小限制

目录 1. 修改Gitea配置2. 重启服务3. 使用 之前在Gitea上传附件时&#xff0c;显示大小超过3MB&#xff0c;不能符合我的使用场景。记录一下修改这个限制的配置。 1. 修改Gitea配置 默认在安装路径的custom/conf/app.ini文件中&#xff1a; 添加参数 [repository.upload] ; 是…

linux下cuda的安装

linux下cuda的安装 安装cuda11.1和pytorch1.8安装显卡驱动第一个报错第二个报错第三个错误屏幕不显示问题解决方案 安装cuda11.1 安装cuda11.1和pytorch1.8 通过上表可以发现&#xff0c;如果要使用CUDA11.1&#xff0c;那么需要将显卡的驱动更新至455.23或以上&#xff08;Lin…

SpringBoot2+Vue2实战(十六)vue集成视频播放组件

修改文件上传大小限制 servlet:multipart:max-file-size: 100MBmax-request-size: 100MB Video.vue <template><div style"padding: 10px"><el-card><div v-for"item in videos" :key"item.id"style"margin: 10px 0…

走进Linux世界【二、VM与Linux安装】

第二章 VM与Linux安装 1、安装VMware ​ 这里安装Vm主要是为了安装Linux系统&#xff0c;除了相对云服务器&#xff0c;比较大众化的操作&#xff0c;当然更多的是熟悉Linux操作 1、Windows安装 ​ (1) 下载链接&#xff0c;目前版本上下载VM15的版本即可https://www.vmwar…

JavaScript ES6实现继承

1 对象的方法补充 2 原型继承关系图 3 class方式定义类 4 extends实现继承 5 extends实现继承 6 多态概念的理 function 创建的名称如果开头是大写的&#xff0c;那这个创建的不是函数&#xff0c;是创建了类。 ES6-class类中的内容 <!DOCTYPE html> <html lang&…

ChatGPT助力校招----面试问题分享(十一)

1 ChatGPT每日一题&#xff1a;PCB布线&#xff0c;高速信号线走直角的后果 问题&#xff1a;PCB布线&#xff0c;高速信号线走直角的后果 ChatGPT&#xff1a;对于高速信号线来说&#xff0c;最好避免使用直角布线。直角布线会引入反射和信号损耗&#xff0c;从而导致信号完…

IP网络基础

文章目录 数据通信基础数据流方向&#xff08;工作模式&#xff09;网络和Internet简介网络&#xff1a;互联网&#xff1a;总结&#xff1a; 协议和标准标准化组织标准化组织——IETF标准的种类 IP网络基本架构 lP网络在现代社会中有着越来越重要的地位。本课程将介绍数据通信…

详解c++---c++11(上)

目录标题 {}初始化decltype和autonullptr范围forfinal什么是左值和右值左值引用和右值引用右值引用的意义右值引用的使用const右值引用万能引用默认移动构造和移动赋值 {}初始化 在c98中允许使用{}对数组或者结构体元素进行统一的列表初始值设定&#xff0c;比如说下面有个结构…

使用USB转TTL线连接树莓派4B

一般我们刷完树莓派系统后&#xff0c;都是通过连接鼠标键盘及显示器来进行操作&#xff0c;当我们开启SSH功能后我们才可以通过ssh客户端进行远程访问&#xff0c;那么是否有更方便的方式进行连接&#xff0c;并且不需连接外部设备进行操作呢&#xff1f; 串口通信 当然可以…

python3+requests+unittest实战系列【一】

1.环境准备 python3 pycharm编辑器 2.框架目录展示 &#xff08;该套代码只是简单入门&#xff0c;有兴趣的可以不断后期完善&#xff09; &#xff08;1&#xff09;run.py主运行文件&#xff0c;运行之后可以生成相应的测试报告&#xff0c;并以邮件形式发送&#xff1b;…

探索现代设备管理系统的功能和优势

在现代工业环境中&#xff0c;设备管理对于企业的生产效率和可靠性至关重要。随着科技的不断发展&#xff0c;现代设备管理系统为企业提供了更多的优势和功能&#xff0c;以帮助企业实现设备全生命周期管理和优化运营。本文将探索现代设备管理系统的优势和功能&#xff0c;以帮…

PicGo搭建Gitee图床

文章目录 1、创建Gitee仓库2. 填写仓库信息3、生成私人令牌3.1、点击个人设置3.2、点击私人令牌3.3、生成新令牌3.4、密码验证3.5、记录个人令牌 4、PicGo配置4.1、插件设置&#xff0c;安装gitee插件4.2、PicGo图床配置为gitee并设置详细信息 5、特殊问题5.1、上传失败原因15.…