当前位置: 首页 > news >正文

08 | Jackson 注解在实体里面如何应用?常见的死循环问题如何解决?

  1. 我们用 Spring Boot 里面默认集成的 fasterxml.jackson 加以说明,这看似和 JPA 没什么关系,但是一旦我们和 @Entity 一起使用的时候,就会遇到一些问题,特别是新手同学,我们这一课时详细介绍一下用法。先来跟着我了解一下 Jackson 的基本语法。

    Jackson 基本语法

    我们先看一下我们项目里面的依赖。

    Drawing 0.png

    从中可以看到,当我们用 spring boot starter 的时候就会默认加载 fasterxml 相关的 jar 包模块,包括核心模块以及 jackson 提供的一些扩展 jar 包,下面详细介绍。

    核心模块有三个
    1. jackson-core:核心包,提供基于“流模式”解析的相关 API,它包括 JsonPaser 和 JsonGenerator。Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
    2. jackson-annotations:注解包,提供标准注解功能,这是我们必须要掌握的基础语法。
    3. jackson-databind:数据绑定包,提供基于“对象绑定”解析的相关 API( ObjectMapper ) 和“树模型”解析的相关 API(JsonNode);基于“对象绑定”解析的 API 和“树模型”解析的 API 依赖基于“流模式”解析的 API。如下图中一些标准的类型转换:

    Drawing 1.png

    jackson 提供了一些扩展 jar
    1. jackson-module-parameter-names:对原来的 jackson 进行了扩展,支持了构造方法和方法基本的参数支持。
    2. jackson-datatype:是对字段类型的支持做的一些扩展,包括下述几个部分。

    a. jackson-datatype-jdk8:是对 jdk8 语法里面的一些 Optional、Stream 等一些新的类型做的一些支持,如下图展示的一些类:

    Drawing 2.png

    b.jackson-datatype-jsr310:是对 jdk8 中的 JSR310 时间协议做了支持,如 Duration、Instant、LocalDate、Clock 等时间类型的序列化、反序列化,如下图展示的一些类:

    Drawing 3.png

    c.jackson-datatype-hibernate5:是对Hibernate的里面的一些数据类型的序列化、反序列化,如HibernateProxy 等。

    剩下不常见的咱们就不说了,jackson-datatype 其实就是对一些常见的数据类型做序列化、反序列化,省去了我们自己写序列化、反序列化的过程。所以在我们工作中,如果需要自定义序列化的时候,可以参考这些源码。

    知道了这些脉络之后,剩下的就是我们要掌握的注解有哪些了,下面我来介绍一下。

    常用的一些注解

    正如上面所说,我们打开 jackson-annotations,就可以看到有哪些注解了,一目了然,闲着没事的时候就可以到这里面看看,这样你会越来越熟悉。下面我们挑选一些常用的介绍一下。

    Drawing 4.png

    Jackson 里面常用的注解如下表格所示:

    Lark20201009-105051.png

    我们看个实例感受一下

    接下来我们写个测试用例看一下。

    首先,新建一个 UserJson 实体对象,将它转成 Json 对象,如下所示:

    复制代码

    package com.example.jpa.example1;
    import com.fasterxml.jackson.annotation.*;
    import lombok.*;
    import javax.persistence.*;
    import java.time.Instant;
    import java.util.*;
    @Entity
    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonPropertyOrder({"createDate","email"})
    public class UserJson {@Id@GeneratedValue(strategy= GenerationType.AUTO)private Long id;@JsonProperty("my_name")private String name;private Instant createDate;@JsonFormat(timezone ="GMT+8", pattern = "yyyy-MM-dd HH:mm")private Date updateDate;private String email;@JsonIgnoreprivate String sex;@JsonCreatorpublic UserJson(@JsonProperty("email") String email) {System.out.println("其他业务逻辑");this.email = email;}@Transient@JsonAnySetterprivate Map<String,Object> other = new HashMap<>();@JsonAnyGetterpublic Map<String, Object> getOther() {return other;}
    }
    

    然后,我们写一个测试用例,看一下运行结果。

    复制代码

    package com.example.jpa.example1;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.assertj.core.util.Maps;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.TestInstance;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
    import org.springframework.test.annotation.Rollback;
    import javax.transaction.Transactional;
    import java.time.Instant;
    import java.util.Date;
    @DataJpaTest
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    public class UserJsonRepositoryTest {@Autowiredprivate UserJsonRepository userJsonRepository;@BeforeAll@Rollback(false)@Transactionalvoid init() {UserJson user = UserJson.builder().name("jackxx").createDate(Instant.now()).updateDate(new Date()).sex("men").email("123456@126.com").build();userJsonRepository.saveAndFlush(user);}/*** 测试用User关联关系操作**/@Test@Rollback(false)public void testUserJson() throws JsonProcessingException {UserJson userJson = userJsonRepository.findById(1L).get();userJson.setOther(Maps.newHashMap("address","shanghai"));ObjectMapper objectMapper = new ObjectMapper();
    System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(userJson));}
    }
    

    最后,运行一下可以看到如下结果。

    复制代码

    {"createDate" : {"epochSecond" : 1600530086,"nano" : 588000000},"email" : "123456@126.com","id" : 1,"updateDate" : "2020-09-19 23:41","my_name" : "jackxx","address" : "shanghai"
    }
    

    这里可以和上面的注解列表对比一下,其中我们看到了 HashMap 被平铺开了。我们通过例子可以很容易想到使用场景是 SpringMvc 的情况下,在 get 请求的时候我们要用到序列化;在 post 请求的时候我们要用到反序列化,将 json 字符串反向转化成实体对象。

    那么在 Spring 里面 Jackson 都有哪些应用场景呢?我们来看一下。

    Jackson 和 Spring 的关系

    我们先看一下 Jackson 在 Spring 中常见的四个应用场景,来了解一下 Spring 在这些情况下的应用,带你详细掌握 Jackson 并知道它的重要性。

    应用场景一

    在Spring MVC中,我们需要知道Mvc的JSON视图的加载原理。我们看一下源码,mvc 对象的转化类:HttpMessageConvertersAutoConfiguration,里面要利用JacksonHttpMessageConvertersConfiguration,如下所示:

    Drawing 5.png

    而里面的MappingJackson2HttpMessageConverter 正是采用 fasterxml.jackson 进行转化的,看下面的图片。

    Drawing 6.png

    应用场景二

    我们在微服务之间相互调用的时候,都会用到 HttpMessageConverter 里面的 JacksonHttpMessageConverter 进行转化。特别是在用 open-feign 里面的 Encode 和 Decode 的时候,我们就可以看到如下应用场景:

    Drawing 7.png

    应用场景三

    redis、cacheable 都会用到 value 的序列化,都离不开 JSON 的序列化,看下面的 redis 里面的关键配置文件。

    Drawing 8.png

    应用场景四

    当我们项目之间解耦用到消息队列的时候,可能会基于 JMS消息协议发送消息,其也是基于 JSON 的序列化机制来继续converter的,它在用JmsTemplate 的时候也会遇到同样情况,我们看一下 JMS 里面相关代码。

    Drawing 9.png

    综上四个场景所述,我们是经常和 Entity 打交道的,而 @Entity 又要在各种场景转化成 JSONString,所以 Jackson 的原理我们还是要掌握一些的,下面来分析几个比较重要的。

    Jackson 原理分析

    Jackson 的可见性原理分析

    前面我们看到了注解@JsonAutoDetect JsonAutoDetect.Visibility 类包含与 Java 中的可见性级别匹配的常量,表示 ANY、DEFAULT、NON_PRIVATE、NONE、PROTECTED_AND_PRIVATE和PUBLIC_ONLY。

    那么我们打开这个类,看一下源码:

    Drawing 10.png

    这里面的代码并不复杂,通过JsonAutoDetect 我们可以看到,Jackson 默认不是所有的属性都可以被序列化和反序列化。默认的属性可视化的规则如下:

    • 若该属性修饰符是 public,该属性可序列化和反序列化。
    • 若属性的修饰符不是 public,但是它的 getter 方法和 setter 方法是 public,该属性可序列化和反序列化。因为 getter 方法用于序列化,而 setter 方法用于反序列化。
    • 若属性只有 public 的 setter 方法,而无 public 的 getter 方法,该属性只能用于反序列化。

    所以我们可以通过私有字段的 public get 和 public set 方法控制是否可以序列化。这里可以和我们前面讲到的“JPA 实体里面的注解生效方式”做一下对比,也可以通过直接更改 ObjectMapper 设置可视化策略,如下所示:

    复制代码

    ObjectMapper mapper = new ObjectMapper();// PropertyAccessor 支持的类型有 ALL,CREATOR,FIELD,GETTER,IS_GETTER,NONE,SETTER// Visibility 支持的类型有 ANY,DEFAULT,NON_PRIVATE,NONE,PROTECTED_AND_PUBLIC,PUBLIC_ONLYmapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
    

    这样,就可以直接看到所有字段了,包括私有字段。接着我们说一下反序列化相关方法。

    反序列化最重要的方法

    我们在做反序列化的时候要用到的三个重要方法如下所示。

    Drawing 11.png

    复制代码

    public <T> T readValue(String content, Class<T> valueType)
    public <T> T readValue(String content, TypeReference<T> valueTypeRef)
    public <T> T readValue(String content, JavaType valueType)
    

    可以看出,反序列化的时候要知道 java 的 Type 是很重要的,如下:

    复制代码

    String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(userJson);
    //单个对象的写法:
    UserJson user = objectMapper.readValue(json,UserJson.class);
    //返回List的返回结果的写法:List<User> personList2 = mapper.readValue(jsonListString, new TypeReference<List<User>>(){});
    

    我们也可以根据 java 的反射,即万能的 JavaType 进行反序列化和转化,如下:

    Drawing 12.png

    你也可以看一下 Jackson2HttpMessageConverter 里面的用法。

    Drawing 13.png

    这个时候你应该很好奇,readValue 里面是如何判断 java 类型的呢?我们看下 ObjectMapper 的源码里面做了如下操作:

    复制代码

    public <T> T readValue(DataInput src, Class<T> valueType) throws IOException
    {_assertNotNull("src", src);return (T) _readMapAndClose(_jsonFactory.createParser(src),_typeFactory.constructType(valueType));
    }
    

    到这里,我们看到 typeFactory 里面的 constructType 可以取到各种 type,那么点击进去看看。

    Drawing 14.png

    可以看到里面处理各种 java 类型和泛型的情况,当我们自己写反射代码的时候可以参考这一段,或者直接调用。此外,ObjectMapper 里面还一个重要的概念就是 Moduel,我们来看下。

    Moduel 的加载机制

    ObejctMapper 里面可以扩展很多 datatype,而不同的 datatype 封装到了不通的 modules 里面,我们可以 register 注册进去不同的 module,从而处理不同的数据类型。

    目前 Modules 官方网站提供了很多内容,具体你可以查看这个网址:https://github.com/FasterXML/jackson#third-party-datatype-modules。这里我们重点说一下常用的加载机制。

    Drawing 15.png

    我们通过在代码里面设置一个断点,就可以很清楚地知道常用的 ModuleType 都有哪些,如 Jdk8、jsr310、Hibernate5 等。在MVC 里面默认的 Module 也是图上那些,Hibernate5 是我们自己引入的,具体解决什么问题和如何自定义的呢?我们接着往下看。

    Jackson 与 JPA 常见的问题

    我们用 JPA 的时候,特别是关联关系的时候,最常见的就是死循环了,你在使用时一定要注意。

    死循环问题如何解决

    第一种情况:我们在写 ToString 方法,特别是 JPA 的实体的时候,很容易陷入死循环,因为实体之间的关联关系配置是双向的,我们就需要 ToString 的时候把一方排除掉,如下所示:

    Drawing 16.png

    第二种情况:在转化JSON的时候,双向关联也会死循环。按照我们上面讲的方法,这是时候我们要想到通过 @JsonIgnoreProperties(value={“address”})或者字段上面配置@JsonIgnore,如下:

    复制代码

    @JsonIgnore
    private List<UserAddress> address;
    

    此外,通过 @JsonBackReference 和 @JsonManagedReference 注解也可以解决死循环。

    复制代码

    public class UserAddress {@JsonManagedReferenceprivate User user;
    ....}
    public class User implements Serializable {@OneToMany(mappedBy = "user",fetch = FetchType.LAZY)@JsonBackReferenceprivate List<UserAddress> address;
    ...}
    

    如上述代码,也可以达到 @JsonIgnore 的效果,具体你可以自己操作一下试试,原理都是一样的,都是利用排除方法。那么接下来我们看下 HibernateModel5 是怎么使用的。

    JPA 实体 JSON 序列化的常见报错

    我们在实际跑之前讲过的 user 对象,或者是类似带有 lazy 对象关系的时候,经常会遇到下面的错误:

    复制代码

    No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.example.jpa.example1.User$HibernateProxy$MdjeSaTz["hibernateLazyInitializer"])
    com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.example.jpa.example1.User$HibernateProxy$MdjeSaTz["hibernateLazyInitializer"])
    

    这个时候该怎么办呢?下面介绍几个解决办法,第一个可以引入Hibernate5Module。

    常见报错解决方法

    解决方法一:引入 Hibernate5Module

    代码如下:

    复制代码

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new Hibernate5Module());
    String json = objectMapper.writeValueAsString(user);
    System.out.println(json);
    

    这样子就不会报错了。

    Hibernate5Module 里面还有很多 Feature 配置,例如FORCE_LAZY_LOADING,强制 lazy 里面加载就不会有上面的问题了。但是这个会有性能问题,我不建议使用。

    还有 USE_TRANSIENT_ANNOTATION,利用 JPA 的 @Transient 注解配置,这个默认是开启的。所以基本上 feature 默认配置都是 ok 的,不需要我们动手,只要知道这回事就行了。

    Drawing 17.png

    解决方法二:关闭 SerializationFeature.FAIL_ON_EMPTY_BEANS 的 feature

    代码如下:

    复制代码

            ObjectMapper objectMapper = new ObjectMapper();
    //直接关闭SerializationFeature.FAIL_ON_EMPTY_BEANS       objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);String json = objectMapper.writeValueAsString(user);System.out.println(json);
    

    因为是 lazy,所以 empty 的 bean 的时候不报错也可以。
    解决方法三:对象上面排除“hibernateLazyInitializer”“handler”“fieldHandler”等

    代码如下:

    复制代码

    @JsonIgnoreProperties(value={"address","hibernateLazyInitializer","handler","fieldHandler"})
    public class User implements Serializable {
    

    那有没有其他 ObjectMapper 的推荐配置了呢?

    ObjectMapper 实战经验推荐配置项

    下面是我根据自己实战经验为你推荐的配置项。

    复制代码

    ObjectMapper objectMapper = new ObjectMapper();
    //empty beans不需要报错,没有就是没有了
    objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
    //遇到不可识别字段的时候不要报错,因为前端传进来的字段不可信,可以不要影响正常业务逻辑
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
    //遇到不可以识别的枚举的时候,为了保证服务的强壮性,建议也不要关心未知的,甚至给个默认的,特别是微服务大家的枚举值随时在变,但是老的服务是不需要跟着一起变的
    objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL,true);
    objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE,true);
    

    时间类型的最佳实践,如何返回 ISO 格式的标准时间

    有的时候我们会发现,默认的 ObjectMapper 里面的 module 提供的时间转化格式可能不能满足我们的要求,可能要进行扩展,老师提供一个自定义 module 返回 ISO 标准时间格式的一个案例,如下:

    复制代码

    @Test
    @Rollback(false)
    public void testUserJson() throws JsonProcessingException {UserJson userJson = userJsonRepository.findById(1L).get();userJson.setOther(Maps.newHashMap("address","shanghai"));//自定义 myInstant解析序列化和反序列化DateTimeFormatter.ISO_ZONED_DATE_TIME这种格式SimpleModule myInstant = new SimpleModule("instant", Version.unknownVersion()).addSerializer(java.time.Instant.class, new JsonSerializer<Instant>() {@Overridepublic void serialize(java.time.Instant instant,JsonGenerator jsonGenerator,SerializerProvider serializerProvider)throws IOException {if (instant == null) {jsonGenerator.writeNull();} else {jsonGenerator.writeObject(instant.toString());}}}).addDeserializer(Instant.class, new JsonDeserializer<Instant>() {@Overridepublic Instant deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {Instant result = null;String text = jsonParser.getText();if (!StringUtils.isEmpty(text)) {result = ZonedDateTime.parse(text, DateTimeFormatter.ISO_ZONED_DATE_TIME).toInstant();}return result;}});ObjectMapper objectMapper = new ObjectMapper();//注册自定义的moduleobjectMapper.registerModule(myInstant);String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(userJson);System.out.println(json);
    }
    

    我们利用上面的UserJson案例,在测试用例里面自定义了myInstant来进行序列化和反序列化Instant这种类型,然后我们通过objectMapper.registerModule(myInstant); 注册进去。那么我们看一下运行结果:

    复制代码

    {"createDate" : "2020-09-20T02:36:33.308Z","email" : "123456@126.com","id" : 1,"updateDate" : "2020-09-20 10:36","my_name" : "jackxx","address" : "shanghai"
    }
    

    这时你会发现 createDate 的格式发生了变化,这样子的话,任何人看到我们这样的 JSON 结构就不必问我们到底是哪个时区的问题了。

相关文章:

08 | Jackson 注解在实体里面如何应用?常见的死循环问题如何解决?

我们用 Spring Boot 里面默认集成的 fasterxml.jackson 加以说明&#xff0c;这看似和 JPA 没什么关系&#xff0c;但是一旦我们和 Entity 一起使用的时候&#xff0c;就会遇到一些问题&#xff0c;特别是新手同学&#xff0c;我们这一课时详细介绍一下用法。先来跟着我了解一下…...

JavaScript—获取当前时间 并转化为yyyy-MM-dd hh:mm:ss格式

JavaScript—获取当前时间 并转化为yyyy-MM-dd hh:mm:ss格式 每次项目都需要用到时间戳格式,可以封装成一个方法 下次直接CV过去 const timestampPadStart=(str)=>{str=String(str);return str.padStart(2,0)...

OpenHarmony创新赛丨报名倒计时,超强秘籍带你直通大奖!

OpenHarmony创新赛报名倒计时开始啦&#xff01; 设于开放原子全球开源大赛下的OpenHarmony创新赛&#xff0c;目前正在如火如荼地进行赛事招募中&#xff01;这次大赛围绕创新应用、商显行业、金融行业三大赛题&#xff0c;邀请来自企业、个人、高校师生等各界群体的优秀开发者…...

Linux高性能服务器编程 学习笔记 第十四章 进程池和线程池

动态创建子进程或子线程的缺点&#xff1a; 1.动态创建进程或线程比较耗时&#xff0c;这将导致较慢的客户响应。 2.动态创建的子进程或子线程通常只用来为一个客户服务&#xff08;除非我们做特殊处理&#xff09;&#xff0c;这将导致系统上产生大量的进程或线程&#xff0c…...

微信小程序/vue3/uview-plus form兜底校验

效果图 代码 <template><u-form :model"form" ref"formRole" :rules"rules"><u-form-item prop"nickname"><u-input v-model"form.nickname" placeholder"姓名" border"none" /&…...

Photoshop 2024正式发布!内置最新PS AI,创意填充等功能无限制使用!

PS正式版目前更新到了2024&#xff0c;版本为25.0。 安装教程 1、下载得到安装包后&#xff0c;先解压。鼠标右键&#xff0c;【解压到当前文件夹】 2、双击 Set-up 开始安装 3、这里可以更改安装位置。如果C盘空间不够大&#xff0c;可以把它安装到C盘以外。更改好后&#x…...

芯片学习记录TLP184

TLP184 芯片介绍 TLP184是一款光耦隔离器&#xff0c;它的主要特点包括&#xff1a;高电压耐受能力、高传输速度、高共模隔离能力、低功耗等。它可以用于工业自动化、通信设备、家用电器等领域的电气隔离应用。由一个光电晶体管组成&#xff0c;光学耦合到两个红外发射二极管…...

C++ 重载运算符和重载函数

前言 C 允许在同一作用域中的某个函数和运算符指定多个定义&#xff0c;分别称为函数重载和运算符重载。重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明&#xff0c;但是它们的参数列表和定义&#xff08;实现&#xff09;不相同。 当您调用一个…...

Linux:mongodb数据库基础操作(3.4版本)

安装 3.*版本和4.*版本安装都是一样的 Linux&#xff1a;mongodb数据库源码包安装&#xff08;4.4.25版本&#xff09;_鲍海超-GNUBHCkalitarro的博客-CSDN博客https://blog.csdn.net/w14768855/article/details/133826626?spm1001.2014.3001.5501 mysql和mongodb对比 登录…...

nginx实现灰度上线(InsCode AI 创作助手)

要基于Nginx实现灰度上线&#xff0c;有以下三种方法&#xff1a; 权重分发&#xff1a;使用Nginx的upstream模块来设置不同服务器的权重。将一部分请求分发给新版本服务器&#xff0c;另一部分请求分发给旧版本服务器。这可以通过以下方式实现&#xff1a; http {upstream bac…...

记:apifox 返回 invalid header token 的问题排查思路

背景&#xff1a; 某接口服务使用 springboot 2.x 开发&#xff0c; RestController 、ReqeustBody 在本地(localhost)调用的时候正常、chrome (.cn域名访问)浏览器访问正常。 换成 apifox (.cn域名访问)、postman (.cn域名访问)调用异常返回&#xff1a;invalid header t…...

【00】神经网络之初始化参数

问题描述 #随机初始化权重 w12 np.random.randn(100, 784)/np.sqrt(784) 为什么除以28 回答 这里的代码是初始化一个深度学习模型中的权重矩阵w12。权重矩阵的形状是(100, 784)&#xff0c;这是一个从784个输入节点到100个隐藏节点的全连接层。 除以np.sqrt(784)是权重初始…...

代码随想录Day20 回溯算法 LeetCode77 组合问题

以下内容更详细解释来自于:代码随想录 (programmercarl.com) 1.回溯算法理论基础 回溯法也叫回溯搜索法,是搜索法的一种,我们之前在二叉树中也经常使用到回溯来解决问题,其实有递归就有回溯,有的时候回溯隐藏在递归之下,我们不容易发觉,今天我们来详细介绍一下什么是回溯,它能…...

免费获取天气预报的API接口(Json格式)

免费获取天气预报的API接口&#xff08;Json格式&#xff09; 1、接口地址2、城市代码 1、接口地址 当需要获取某个城市天气数据json时候&#xff0c;需要传入一个城市代码编码作为入参&#xff0c;地址&#xff1a; http://t.weather.itboy.net/api/weather/city/xxxxx &…...

安卓程序执行入口

Android程序执行入口 Android应用程序的执行入口是在一个特定的 Java 类中&#xff0c;通常是 MainActivity 或 SplashActivity&#xff0c;具体取决于应用的设计和结构。 Android应用程序的执行入口通常通过以下方式进行定义&#xff1a; 在 AndroidManifest.xml 文件中&am…...

消息队列(中间件)

通信协议&#xff1a; 为了实现客户端和服务器之间的通信来完成的逻辑&#xff0c;基于TCP实现的自定义应用层协议。通过这个协议,完成客户端–服务器远程方法调用。 序列化/反序列化&#xff1a; 通过网络传输对象把对象存储到硬盘上。 序列化&#xff1a;把对象转化为二进制的…...

Java|学习|异常

1.异常 1.1 异常 1.1.1 概述 异常&#xff1a;就是程序出现了不正常的情况。 Error&#xff1a;严重问题&#xff0c;不需要处理。 Exception&#xff1a;称为异常类&#xff0c;它表示程序本身可以处理的问题。 RuntimeException&#xff1a;在编译器不检查&#xff0c;出…...

nextjs项目修改启动端口号,以及开发启动后自动打开浏览器

next版本&#xff1a;13.5.4 一、修改端口 在package.json文件当中修改启动命令 "scripts": {"dev": "next dev -p 3100","build": "next build","start": "next start","lint": "ne…...

微服务架构 | 超时管理

INDEX LSA 级别与全年停机时间速查表LSA 级别实战TP 性能超时时间设计原则 LSA 级别与全年停机时间速查表 计算公式&#xff1a;60 * 60 * 24 * 365 * (1-LSA) 31,536,000‬ * (1-LSA) 系统级别LSA级别全年停机时间099.999%5分钟099.99%52分钟199.9%8.8小时299%3.65 天 LSA…...

Qt 样式表大全整理

【QT】史上最全最详细的QSS样式表用法及用例说明_qt样式表使用大全_半醒半醉日复日&#xff0c;花落花开年复年的博客-CSDN博客 QT样式表的使用_qt 设置按下 release hover 按钮样式表_create_right的博客-CSDN博客 QPushButton {border-image: url(:/Start_Stop.png); } QPu…...

k8s-10 cni 网络

k8s通过CNI接口接入其他网络插件来实现网络通讯。目前比较流行的插件有flannel,calico等。 CNI插件存放位置: # cat /etc/cni/net.d/10-flannel.conflist 插件使用的解决方案如下: 虚拟网桥&#xff0c;虚拟网卡&#xff0c;多个容器共用一个虚拟网卡进行通信。多路复用: Mac…...

IDEA中.gitignore配置不生效的解决方案

一、创建项目 二、执行以下Git命令 git rm -r --cached . git add . git commit -m "update .gitignore"...

SparkContext 与 SparkContext 之间的区别是什么

SparkContext 是 Spark 的入口点&#xff0c;它是所有 Spark 应用程序的主要接口&#xff0c;用于创建 RDD、累加器、广播变量等&#xff0c;并管理与 Spark 集群的连接。在一个 Spark 应用程序中只能有一个 SparkContext。 而 SparkSession 是 Spark 2.0 新增的 API&#xff0…...

lv8 嵌入式开发-网络编程开发 17 套接字属性设置

1 基本概念 设置套接字的选项对套接字进行控制除了设置选项外&#xff0c;还可以获取选项选项的概念相当于属性&#xff0c;所以套接字选项也可说是套接字属性有些选项&#xff08;属性&#xff09;只可获取&#xff0c;不可设置&#xff1b;有些选项既可设置也可获取 2 选项…...

VulnHub Alice

一、信息收集 发现开发了22、80 2.访问ip&#xff0c;右击查看源代码 发现需要利用X-Forwarded-For 火狐插件&#xff1a;X-Forwarded-For Header 挂上代理后&#xff1a; 出现以下页面&#xff1a; 先注册一个账户&#xff0c;然后再登录 发现有参数进行传参 发现传参&a…...

AUTOSAR组织发布20周年纪念册,东软睿驰NeuSAR列入成功案例

近日&#xff0c;AUTOSAR组织在成立20周年之际发布20周年官方纪念册&#xff08;20th Anniversary Brochure&#xff09;&#xff0c;记录了AUTOSAR组织从成立到今天的故事、汽车行业当前和未来的发展以及AUTOSAR 伙伴关系和合作在重塑汽车方面的作用。东软睿驰提报的基于AUTOS…...

转行网络安全是否可行?

一、前言 其实很多的IT大佬之前也不是专门学计算机的&#xff0c;都是后期转行的。而且大学学什么专业&#xff0c;对后期的工作真的没有太大关系&#xff0c;这也是现在高校的教育现状。有80%的学生都是通过临时抱佛脚&#xff0c;考前冲刺拿到毕业证书的。下面就带大家详细分…...

netca_crypto.dll找不到怎么修复?详细解决办法和注意事项

当你在使用计算机时&#xff0c;突然出现了一个错误提示&#xff1a;“netca_crypto.dll 找不到”。不知道该如何解决这个问题&#xff1f;其实要解决是非常的简单的&#xff0c;今天我们将为你提供几种修复 netca_crypto.dll 找不到的解决方法和一些注意事项。在深入探讨修复方…...

axios的请求中断和请求重试

请求中断 场景&#xff1a;1、假如一个页面接口太多、或者当前网络太卡顿、这个时候跳往其他路由&#xff0c;当前页面可以做的就是把请求中断掉&#xff08;优化&#xff09;2、假如当前接口调取了第一页数据&#xff0c;又调去了第二页的数据&#xff0c;当我们调取第二页数…...

视频怎么压缩?视频太大这样处理变小

在当今时代&#xff0c;视频已经成为了我们日常生活中不可或缺的一部分&#xff0c;然而&#xff0c;视频文件往往非常大&#xff0c;给我们的存储和传输带来了很大的不便&#xff0c;那么&#xff0c;如何有效地压缩视频呢&#xff1f; 一、使用压缩软件 首先我们给大家分享一…...

广州网站建设比较好的公司/企业建站系统模板

Django rest framework 源码分析 ----认证 一、基础 django 2.0官方文档 1 https://docs.djangoproject.com/en/2.0/ 安装 pip3 install djangorestframework 假如我们想实现用户必须是登陆后才能访问的需求&#xff0c;利用restframework该如何的去实现&#xff0c;具体的…...

做网站需要ftp/网络营销模式

一扫二拖&#xff0c;早上扫完下午脏,来回拖完地玩还得清洁拖把&#xff0c;心理暗悄悄想着怎么逃避这一现实&#xff0c;然鹅&#xff0c;第二天继续死循环……扫地机器人的出现可以说是一大救星&#xff0c;不用动手&#xff0c;不用弯腰&#xff0c;还可以坐在沙发吃着零食看…...

商务网站策划书/求职seo服务

1、shell脚本基本元素&#xff1a;以下四行#!/bin/bash第一行#注释变量流程控制结构2、Example&#xff1a;helloworld.sh#!/bin/bash#这是一个打印“helloworld”的shell脚本printchar”hello world”echo $printchar以上四行是脚本的内容&#xff0c;然后执行以下命令&#x…...

旅游公司网站开发与实现/青岛招聘seo

作者&#xff1a;JOE&#xff0c;原文链接&#xff0c;原文日期&#xff1a;2016-05-01译者&#xff1a;ckitakishi&#xff1b;校对&#xff1a;mmoaay&#xff1b;定稿&#xff1a;CMB当前&#xff0c;有许多人正在努力将 Swift 3.0 引入到基于 ARM 的系统中。通过本文你将了…...

wordpress 简书风格/今日新闻头条官网

但是依靠pycharm的下载&#xff0c;我自己也是一直失败&#xff0c;就算是换了镜像 开始尝试其他方法&#xff0c;更新conda的版本 conda update conda 执行pip命令 pip install tensorflow-gpu2.2.0rc1 -i https://pypi.tuna.tsinghua.edu.cn/simple 出现Traceback (most re…...

营销型网站的建设和运营/如何设计企业网站

VFW概念 VFW是微软公司1992年推出的关于数字视频的一个软件包&#xff0c;它能使应用程序通过数字化设备从传统的模拟视频源得到数字化的视频剪辑。VFW的一个关键思想是播放时不需要专用硬件&#xff0c;为了解决数字视频数据量大的问题&#xff0c;需要对数据进行压缩。它引进…...