百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Java系统开发从入门到精通第四讲(文字版)

liuian 2025-02-26 12:45 14 浏览


课程目标:了解重要的Java API 和 一些必备框架的使用,这些都是系统开发的标配需要掌握

日期时间API

Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。

在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:

  • 非线程安全 ? java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
  • 设计很差 ? Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
  • 时区处理麻烦 ? 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。

Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:

  • Local(本地) ? 简化了日期时间的处理,没有时区的问题。
  • Zoned(时区) ? 通过制定的时区处理日期时间。

新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。

因为之前的日期时间API比较糟糕,一般都会自己写DateTimeUtil工具类,后来也有Joda-Time开源项目,确实帮广大程序员解决了大问题(所以程序员为什么不止要会用框架和java API,就是需要知其然也知其所以然,如果底层本身有缺陷或实现不好,最差我们知道,当然我们也可以增强或自己实现)

LocalDate/LocalTime 和 LocalDateTime 类可以在处理时区不是必须的情况。代码如下:


import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.Month;
 
public class Java8Tester {
   public static void main(String args[]){
      Java8Tester java8tester = new Java8Tester();
      java8tester.testLocalDateTime();
   }
    
   public void testLocalDateTime(){
    
      // 获取当前的日期时间
      LocalDateTime currentTime = LocalDateTime.now();
      System.out.println("当前时间: " + currentTime);
        
      LocalDate date1 = currentTime.toLocalDate();
      System.out.println("date1: " + date1);
        
      Month month = currentTime.getMonth();
      int day = currentTime.getDayOfMonth();
      int seconds = currentTime.getSecond();
        
      System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds);
        
      LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
      System.out.println("date2: " + date2);
        
      // 12 december 2014
      LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
      System.out.println("date3: " + date3);
        
      // 22 小时 15 分钟
      LocalTime date4 = LocalTime.of(22, 15);
      System.out.println("date4: " + date4);
        
      // 解析字符串
      LocalTime date5 = LocalTime.parse("20:15:30");
      System.out.println("date5: " + date5);
   }
}

如果我们需要考虑到时区,就可以使用时区的日期时间API:


import java.time.ZonedDateTime;
import java.time.ZoneId;
 
public class Java8Tester {
   public static void main(String args[]){
      Java8Tester java8tester = new Java8Tester();
      java8tester.testZonedDateTime();
   }
    
   public void testZonedDateTime(){
    
      // 获取当前时间日期
      ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");
      System.out.println("date1: " + date1);
        
      ZoneId id = ZoneId.of("Europe/Paris");
      System.out.println("ZoneId: " + id);
        
      ZoneId currentZone = ZoneId.systemDefault();
      System.out.println("当期时区: " + currentZone);
   }
}

Lombok

https://projectlombok.org/

现在很多的java工程里都有Lombok的应用,可见它有多实用(也有反对的文章,可以参见:
https://zhuanlan.zhihu.com/p/146659383)。

lombok可以通过简单的注解的形式来帮助我们简化和消除一些必须有但显得很臃肿的Java代码,比如常见的Getter&Setter、toString()、构造函数等等。lombok不仅方便编写,同时也让我们的代码更简洁。 lombok提供了一个功能完整的jar包,可以很方便的与我们的项目进行集成。

引入依赖:


    org.projectlombok
    lombok
    1.18.22
    provided

常见注解:

  • @Setter 注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成setter方法。
  • @Getter 使用方法同上,区别在于生成的是getter方法。
  • @ToString 注解在类,添加toString方法。
  • @EqualsAndHashCode 注解在类,生成hashCode和equals方法。
  • @NoArgsConstructor 注解在类,生成无参的构造方法。
  • @RequiredArgsConstructor 注解在类,为类中需要特殊处理的字段生成构造方法,比如final和被@NonNull注解的字段。
  • @AllArgsConstructor 注解在类,生成包含类中所有字段的构造方法。
  • @Data 注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
  • @Slf4j 注解在类,生成log变量,严格意义来说是常量。private static final Logger log = LoggerFactory.getLogger(UserController.class);

完整注解参见:
https://blog.csdn.net/afreon/article/details/109733866

最新的IDEA已经内置了Lombok插件,可以如丝滑般实用。

Lombok只是帮我们简化了代码,但背后java语言的基本规范,我们是需要知道的,这个需要大家必须掌握,请自检。

Lombok实现浅析:

在Lombok使用的过程中,只需要添加相应的注解,无需再为此写任何代码。自动生成的代码到底是如何产生的呢?

核心之处就是对于注解的解析上。JDK5引入了注解的同时,也提供了两种解析方式。

  • 运行时解析

运行时能够解析的注解,必须将@Retention设置为RUNTIME,这样就可以通过反射拿到该注解。java.lang.reflect反射包中提供了一个接口AnnotatedElement,该接口定义了获取注解信息的几个方法,Class、Constructor、Field、Method、Package等都实现了该接口,对反射熟悉的朋友应该都会很熟悉这种解析方式。

  • 编译时解析

编译时解析有两种机制,分别简单描述下:

1)Annotation Processing Tool

apt自JDK5产生,JDK7已标记为过期,不推荐使用,JDK8中已彻底删除,自JDK6开始,可以使用Pluggable Annotation Processing API来替换它,apt被替换主要有2点原因:

  • api都在com.sun.mirror非标准包下
  • 没有集成到javac中,需要额外运行

2)Pluggable Annotation Processing API

JSR 269自JDK6加入,作为apt的替代方案,它解决了apt的两个问题,javac在执行的时候会调用实现了该API的程序,这样我们就可以对编译器做一些增强。

Lombok本质上就是一个实现了“JSR 269 API”的程序。在使用javac的过程中,它产生作用的具体流程如下:

  1. javac对源代码进行分析,生成了一棵抽象语法树(AST)
  2. 运行过程中调用实现了“JSR 269 API”的Lombok程序
  3. 此时Lombok就对第一步骤得到的AST进行处理,找到@Data注解所在类对应的语法树(AST),然后修改该语法树(AST),增加getter和setter方法定义的相应树节点
  4. javac使用修改后的抽象语法树(AST)生成字节码文件,即给class增加新的节点(代码块)

通过读Lombok源码,发现对应注解的实现都在HandleXXX中,比如@Getter注解的实现在HandleGetter.handle()。还有一些其它类库使用这种方式实现,比如Google Auto、Dagger等等。

前面讲Spring AOP时有提及动态代理实现,底层都是字节码增强和这里的Lombok底层原理一致。(这和元数据理念如出一辙,在元数据、元元数据每一层抽象描述层增强都能使前一层的动态化能力成为现实)

关于字节码增强,感兴趣的同学自行baidu(
https://www.cnblogs.com/luxiaoxun/p/15075778.html)

Swagger

https://swagger.io/

Swagger 是一个用于生成、描述和调用 RESTful 接口的 Web 服务。通俗的来讲,Swagger 就是将项目中所有(想要暴露的)接口展现在页面上,并且可以进行接口调用和测试的服务。

PS:Swagger 遵循了 OpenAPI 规范,OpenAPI 是 Linux 基金会的一个项目,试图通过定义一种用来描述 API 格式或 API 定义的语言,来规范 RESTful 服务开发过程。

Swagger 有以下 3 个重要的作用:

  • 将项目中所有的接口展现在页面上,这样后端程序员就不需要专门为前端使用者编写专门的接口文档;
  • 当接口更新之后,只需要修改代码中的 Swagger 描述就可以实时生成新的接口文档了,从而规避了接口文档老旧不能使用的问题
  • 通过 Swagger 页面,我们可以直接进行接口调用,降低了项目开发阶段的调试成本

为什么需要swagger?

前面我们讲过,随着技术的发展,前后端分离架构越来越普及,我们知道以前在jvm内部调用别人的库要看javadoc,后来基于RPC的分布式调用使用java同种语言也是看javadoc(非同种语言调用就需要其他的调用描述),同理,前后端工程师需要一个统一沟通的接口描述方式,swagger就是解决这个问题的。对于服务提供方,我们主流的方式是基于RESTful规范,接口描述也有规范就是OpenAPI 规范,这也是后来面向API编程的一个基础设施。

常用注解:

  • @Api()用于类;

表示标识这个类是swagger的资源

  • @ApiOperation()用于方法;

表示一个http请求的操作

  • @ApiParam()用于方法,参数,字段说明;

表示对参数的添加元数据(说明或是否必填等)

  • @ApiModel()用于类

表示对类进行说明,用于参数用实体类接收

  • @ApiModelProperty()用于方法,字段

表示对model属性的说明或者数据操作更改

  • @ApiIgnore()用于类,方法,方法参数

表示这个方法或者类被忽略

  • @ApiImplicitParam() 用于方法

表示单独的请求参数

  • @ApiImplicitParams() 用于方法,包含多个 @ApiImplicitParam

看几个示例:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用户基本信息")
public class SysUser {
    /**
     * 用户名
     */
    @ApiModelProperty("用户名")
    private String userName;
    /**
     * 用户昵称
     */
    @ApiModelProperty("用户昵称")
    private String nickName;
    /**
     * 邮件
     */
    @ApiModelProperty("邮件")
    private String email;
    /**
     * 手机号
     */
    @ApiModelProperty("手机号")
    private String mobile;
}
@Api(tags = "用户管理")
@RestController
@RequestMapping("/sysUser")
public class SysUserController {
    /**
     * 保存用户信息
     * @param sysUser
     * @return ResultT
     * @author missye
     * @since 2020/7/21
     */
    @ApiOperation("保存用户信息")
    @PostMapping("/saveSysUser")
    public ResultT saveSysUser(@RequestBody SysUser sysUser) {
        //保存用户信息
        return ResultT.ok("用户保存成功!");
    }
}

SpringBoot集成Swagger3

  • 增加依赖


    org.springframework.boot
    spring-boot-starter-web




    io.springfox
    springfox-boot-starter
    3.0.0
  • 增加SpringBoot配置
Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null

出现如上错误,配置增加:
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

  • 设置Configuration
@EnableOpenApi
@Configuration
public class SwaggerConfig {
    @Bean
    public Docket docket() {
        Docket docket = new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo()).enable(true)
                .select()
                //apis: 添加swagger接口提取范围
                .apis(RequestHandlerSelectors.basePackage("com.easycloud.controller"))
                .paths(PathSelectors.any())
                .build();

        return docket;
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Java系统开发从入门到精通 演示 API")
                .description("ruyicloud")
                .contact(new Contact("小刀神", "https://ruyicloud.cn", "yq76034150@163.com"))
                .version("1.0")
                .build();
    }
}

SpringBoot集成Knife4j

  • 增加依赖
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            com.github.xiaoymin
            knife4j-spring-boot-starter
            3.0.3
        
  • application.properties
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
  • 设置Configuration(同上)
  • 效果如下图


Knife4j可以参考这篇文章:
https://www.jianshu.com/p/7838842cb45e

掌握了swagger的基本用法后,其实它还是不足以支撑真实的项目运转的,简单点就是不够工程化(请再一次记住工程化这个概念,没有工程化的思想是不可能进一步提升的),现在五花八门的解决方案都有一些,这里罗列下(感兴趣的同学可以先自行学习)


yapi:https://hellosean1025.github.io/yapi/

yapi和swagger集成:
https://www.jianshu.com/p/b6bcf95ddbfe

相关推荐

2023年最新微信小程序抓包教程(微信小程序 抓包)

声明:本公众号大部分文章来自作者日常学习笔记,部分文章经作者授权及其他公众号白名单转载。未经授权严禁转载。如需转载,请联系开百。请不要利用文章中的相关技术从事非法测试。由此产生的任何不良后果与文...

测试人员必看的软件测试面试文档(软件测试面试怎么说)

前言又到了毕业季,我们将会迎来许多需要面试的小伙伴,在这里呢笔者给从事软件测试的小伙伴准备了一份顶级的面试文档。1、什么是bug?bug由哪些字段(要素)组成?1)将在电脑系统或程序中,隐藏着的...

复活,视频号一键下载,有手就会,长期更新(2023-12-21)

视频号下载的话题,也算是流量密码了。但也是比较麻烦的问题,频频失效不说,使用方法也难以入手。今天,奶酪就来讲讲视频号下载的新方案,更关键的是,它们有手就会有用,最后一个方法万能。实测2023-12-...

新款HTTP代理抓包工具Proxyman(界面美观、功能强大)

不论是普通的前后端开发人员,还是做爬虫、逆向的爬虫工程师和安全逆向工程,必不可少会使用的一种工具就是HTTP抓包工具。说到抓包工具,脱口而出的肯定是浏览器F12开发者调试界面、Charles(青花瓷)...

使用Charles工具对手机进行HTTPS抓包

本次用到的工具:Charles、雷电模拟器。比较常用的抓包工具有fiddler和Charles,今天讲Charles如何对手机端的HTTS包进行抓包。fiddler抓包工具不做讲解,网上有很多fidd...

苹果手机下载 TikTok 旧版本安装包教程

目前苹果手机能在国内免拔卡使用的TikTok版本只有21.1.0版本,而AppStore是高于21.1.0版本,本次教程就是解决如何下载TikTok旧版本安装包。前期准备准备美区...

【0基础学爬虫】爬虫基础之抓包工具的使用

大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章,为实现从易到难全方位覆盖,特设【0基础学爬...

防止应用调试分析IP被扫描加固实战教程

防止应用调试分析IP被扫描加固实战教程一、概述在当今数字化时代,应用程序的安全性已成为开发者关注的焦点。特别是在应用调试过程中,保护应用的网络安全显得尤为重要。为了防止应用调试过程中IP被扫描和潜在的...

一文了解 Telerik Test Studio 测试神器

1.简介TelerikTestStudio(以下称TestStudio)是一个易于使用的自动化测试工具,可用于Web、WPF应用的界面功能测试,也可以用于API测试,以及负载和性能测试。Te...

HLS实战之Wireshark抓包分析(wireshark抓包总结)

0.引言Wireshark(前称Ethereal)是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料。Wireshark使用WinPCAP作为接口,直接...

信息安全之HTTPS协议详解(加密方式、证书原理、中间人攻击 )

HTTPS协议详解(加密方式、证书原理、中间人攻击)HTTPS协议的加密方式有哪些?HTTPS证书的原理是什么?如何防止中间人攻击?一:HTTPS基本介绍:1.HTTPS是什么:HTTPS也是一个...

Fiddler 怎么抓取手机APP:抖音、小程序、小红书数据接口

使用Fiddler抓取移动应用程序(APP)的数据接口需要进行以下步骤:首先,确保手机与计算机连接在同一网络下。在计算机上安装Fiddler工具,并打开它。将手机的代理设置为Fiddler代理。具体方...

python爬虫教程:教你通过 Fiddler 进行手机抓包

今天要说说怎么在我们的手机抓包有时候我们想对请求的数据或者响应的数据进行篡改怎么做呢?我们经常在用的手机手机里面的数据怎么对它抓包呢?那么...接下来就是学习python的正确姿势我们要用到一款强...

Fiddler入门教程全家桶,建议收藏

学习Fiddler工具之前,我们先了解一下Fiddler工具的特点,Fiddler能做什么?如何使用Fidder捕获数据包、修改请求、模拟客户端向服务端发送请求、实施越权的安全性测试等相关知识。本章节...

fiddler如何抓取https请求实现手机抓包(100%成功解决)

一、HTTP协议和HTTPS协议。(1)HTTPS协议=HTTP协议+SSL协议,默认端口:443(2)HTTP协议(HyperTextTransferProtocol):超文本传输协议。默认...