RESTful服务的第三部分:HATEOAS和Richardson成熟度模型

by Sanchit Gera

通过Sanchit Gera

RESTful服务的第三部分:HATEOAS和Richardson成熟度模型 (RESTful Services Part III : HATEOAS and The Richardson Maturity Model)

In Part I of this series, you learned the very basics of HTTP. We went over common HTTP constructs such as headers, URLs and the different status codes available. We also looked at how each of these constructs could be useful when building resource-oriented web services.

在本系列的第一部分中,您学习了HTTP的基础知识。 我们介绍了常见的HTTP结构,例如标头,URL和可用的不同状态代码。 我们还研究了在构建面向资源的Web服务时这些构造中的每个构造如何有用。

In Part II, you learned about the different constraints you need to comply with in order to build scalable, high-performance RESTful systems.

在第二部分中 ,您了解了为了构建可扩展的高性能RESTful系统需要遵守的各种约束。

This post will provide you with the third and final piece of the puzzle. As noted before, REST is not a standard, but rather an abstract concept. This makes it hard to quantify exactly how “RESTful” a service is or isn’t.

这篇文章将为您提供难题的第三篇也是最后一部分。 如前所述,REST不是标准,而是抽象概念。 这使得很难准确地量化服务是否是“ RESTful”的。

While the constraints discussed in the previous part are helpful when creating a service, they aren’t as good at solving this problem. What if you chose to follow exactly one of those constraints? Two? Three? At what point does your service stop being partially RESTful and cross over into the magical land of complete RESTful-ness?

虽然上一部分中讨论的约束在创建服务时很有用,但它们并不能很好地解决此问题。 如果您选择完全遵循这些约束之一怎么办? 二? 三? 在什么时候,您的服务会停止部分地成为 RESTful并跨入完全 RESTful-ness的魔境?

This is exactly the problem that the Richardson Maturity Model (RMM) helps you solve. But before we dive further into the nitty gritty of RMM, there’s one final topic that will prove to be useful in your understanding of REST.

这正是Richardson成熟度模型(RMM)可以帮助您解决的问题。 但是,在我们进一步深入研究RMM的本质之前,有一个最后的主题对您理解REST很有用。

HATEOAS原理 (The Principle of HATEOAS)

Hypermedia As The Engine Of Application State, shortened to HATEOAS, builds on one of the constraints of REST (the Uniform Interface). I am still trying to determine how to pronounce it. I usually alternate between Hate-ee-ose and Hate-ose. Feel free to choose either, or come up with your own. But anyway, I digress.

ħypermedia 式TËngineöF A pplication 小号泰特,缩短到HATEOAS,建立在REST的约束中的一个( 统一接口 )。 我仍在尝试确定如何发音。 我通常会在“讨厌的人”和“讨厌的人”之间切换。 随意选择,或者提出自己的想法。 但是无论如何,我离题了。

The overarching goal behind HATEOAS is to provide a consistent way for machines to understand APIs and navigate them without having any information about them beforehand, identical to a user visiting a website for the first time.

HATEOAS的总体目标是为机器提供一致的方式来理解API和浏览API,而无需事先获得有关API的任何信息,这与首次访问网站的用户相同。

Assume you were visiting Medium for the first time to write a post. What steps would you take? In all likelihood, you would visit Medium’s homepage, head over to the Stories section, and begin writing your masterpiece. You aren’t really concerned with the URL that Stories section lives on. You don’t have it memorized, but you know that you will be able to get there when you need to.

假设您是第一次访问Medium写一篇文章。 您将采取什么步骤? 您很可能会访问Medium的主页,转到“ 故事”部分,然后开始撰写您的杰作。 您实际上并不关心“ 故事”部分所依据的URL。 您没有记住它,但是您知道您将可以在需要时到达那里。

Or imagine you were ordering something on Amazon. You go in, search for different items, add them to the cart, and checkout. The location of each of these components within the system is inconsequential to you as a user. If the URL required to get to the cart, there is a strong chance you wouldn’t even find out. And yet, your experience remains unhampered.

或想象您正在亚马逊上订购商品。 您进去,搜索其他项目,将它们添加到购物车,然后结帐。 这些组件中每个组件在系统中的位置对于您来说都是无关紧要的。 如果需要购物车的网址,很有可能您根本找不到。 但是,您的经验仍然没有受到阻碍。

In both cases, you only need a single piece of information, that is the entry point to the website. Everything else from that point on is completely discoverable and usable by navigating relevant links (aka hypermedia). This is how the web is designed to work and indeed how most users experience it today.

在这两种情况下,您只需要一条信息,即网站的入口点。 从那时起,通过导航相关链接(也称为超媒体) ,可以完全发现并使用所有其他内容 这就是设计网络工作方式的方式,实际上也是当今大多数用户的体验方式。

HATEOAS extends this idea of discoverability to APIs and web services as well. What if, given a single point of access to the service, I could make use of everything that it has to offer? Luckily, this can be achieved by exploiting the resource oriented nature of our data that we have been working so hard on!

HATEOAS还将可发现性的思想扩展到了API和Web服务。 如果在单点访问服务的情况下,我可以利用其所提供的一切,该怎么办? 幸运的是,这可以通过利用我们一直在努力的数据的面向资源的本质来实现!

We know that since everything being returned by our service is essentially a resource, there are only a handful of things that our service consumer can do with that resource. Further, each action corresponds to a well defined RESTful route within our system (think GET, POST, PUT etc.). This means that we could easily embed all potential interactions with a given resource in the form of actionable URLs within the response. Let’s see an example!

我们知道,由于我们的服务所返回的所有内容本质上都是一种资源,因此,我们的服务使用者只能使用该资源做一些事情。 此外,每个动作都对应于我们系统中定义良好的RESTful路由(请考虑GET,POST,PUT等)。 这意味着我们可以轻松地在响应中以可操作的URL形式嵌入与给定资源的所有潜在交互。 让我们来看一个例子!

Let’s return to our previous example of writing a story on Medium. Imagine if instead of a user-facing website, it was instead purely a web service. Under the HATEOAS model, the only piece of information to navigate the service I need would be the hostname: medium.com

让我们回到前面的例子中,该故事在Medium上写。 想象一下,如果它不是面向用户的网站,而是纯粹的Web服务。 在HATEOAS模型下,导航我需要的服务的唯一信息就是主机名: medium.com

I begin my interaction by making a GET request to the host. Medium promptly responds with a list of all the resources it has to offer, along with where I can find them.

我通过向主机发出GET请求开始交互。 中型会Swift响应并列出所有它必须提供的资源,以及在哪里可以找到它们。

GET medium.com
links : [  {    rel : "bookmarks",    href : "/bookmarks"  },   {    rel : "stories",     href: "/stories"  }]

In this simplified version of Medium, I’m told that there are two resources being offered: stories and bookmarks. I’m also told where each of those resources lives on the system.

在此简化版的Medium中,我被告知提供了两种资源: 故事书签。 还告诉我这些资源中的每一个在系统上的位置。

Next, I need to figure out how to create a new story. From our previous discussions, I already know that this is going to be a POST request, but as a client I still don’t know what kind of data the service is expecting for this request. This is exactly where an OPTIONS request comes in handy. So lets do just that!

接下来,我需要弄清楚如何创建一个新故事。 从前面的讨论中,我已经知道这将是一个POST请求,但是作为客户端,我仍然不知道该服务期望该请求使用哪种数据。 这正是OPTIONS请求派上用场的地方。 因此,让我们做到这一点!

OPTIONS medium.com/stories
Allow GET, POST{  name : "Stories",  description: "Ideas and opinions from around the world",   actions: [    {      POST: {        title: "string",        body: "string"      }    }  ]}

Aha! Looks like we need parameters named title and body corresponding to our new post. This gives us all the information that we need. We can now go ahead and start POSTing to the service and creating new articles on the service.

啊哈! 看起来我们需要与我们的新帖子相对应的名为titlebody的参数。 这为我们提供了所需的所有信息。 现在,我们可以开始发布服务,并在服务上创建新文章。

Now let’s say that following this approach, I land on an existing story. What would an individual story look like?

现在让我们说,按照这种方法,我着眼于一个已有的故事。 个人故事会是什么样?

GET medium.com/stories/3
{  "id": 3,  "title": "An Introduction to Microservices",  "body": "...",  "created_at": "2016-10-25T20:52:12.804Z",  "links": [  {    "rel": "self",    "href": "/stories/1"  },   {    "rel": "author",    "href": "/authors/3"  },   {    "rel": "comments",    "href": "/stories/3/comments"  }],}

Now I not only have information about the story, but I also have a means of getting information about the author and the comments.

现在,我不仅可以获得有关故事的信息,而且还可以获取有关作者和评论的信息。

Of course, this is overly simplistic. There are tons of other things going on such as authentication and authorization that need to be taken care of. And a lot of work needs to be done to design systems that are decomposable into resources this easily. But it serves well to understand the idea behind HATEOAS.

当然,这过于简单了。 还有很多其他事情需要进行,例如身份验证和授权。 要设计可轻松分解为资源的系统,需要做大量的工作。 但是,了解HATEOAS背后的想法非常有用。

This eliminates the need for you as a developer to maintain documentation for your service. Everything a client could possibly need to know about using your service is already in there.

这消除了您作为开发人员维护服务文档的需要。 客户可能需要知道的有关使用您的服务的所有信息。

Similarly, as a client, I do not need to keep track of the URLs associated with each of these resources. I look for the object corresponding to the resource, and navigate to it. If it changes, I don’t care.

同样,作为客户端,我不需要跟踪与这些资源中的每一个相关的URL。 我寻找与资源相对应的对象,然后导航到它。 如果改变了,我不在乎。

With this in mind, let’s now shift our focus to the Richardson Maturity Model (RMM).

考虑到这一点,现在让我们将重点转移到Richardson成熟度模型(RMM)。

理查森成熟度模型 (The Richardson Maturity Model)

As mentioned previously, RMM is a tool to help you evaluate how RESTful a service is. This system of classification — first described by Leonard Richardson — provides a neat way to think about your web services from the perspective of an end user, then make judgments accordingly.

如前所述,RMM是帮助您评估服务的RESTful程度的工具。 这种分类系统(首先由Leonard Richardson描述)提供了一种从最终用户的角度考虑Web服务并进行相应判断的巧妙方法。

Richardson describes four distinct levels in the spectrum of RESTful-ness.

理查森(Richardson)描述了RESTful-ness范围中的四个不同级别。

0级 (Level 0)

This is rock bottom when it comes to a service being RESTful. Services in this category follow the “one URL, one method” principle. That means, the service only exposes a single URL to the outside world and accepts only one type of request (usually POST) at that location.

当涉及到RESTful服务时,这是最基本的。 此类服务遵循“一个URL,一种方法”的原则。 这意味着该服务仅向外界公开一个URL,并且在该位置仅接受一种类型的请求(通常为POST)。

This is typical for SOAP services for example. A typical request to a SOAP service looks something like this:

例如,这对于SOAP服务是典型的。 对SOAP服务的典型请求如下所示:

POST /Quotation HTTP/1.0Host: www.xyz.orgContent-Type: text/xml; charset=utf-8Content-Length: nnn<?xml version="1.0"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle="http://www.w3.org/2001/12/soap-encoding" >   <SOAP-ENV:Body xmlns:m="http://www.xyz.org/quotations" >	      <m:GetQuotation>         <m:QuotationsName>MiscroSoft</m:QuotationsName>      </m:GetQuotation>		   </SOAP-ENV:Body>	</SOAP-ENV:Envelope>

Everything is described in the body of the request, including the action (getQuotation) and the parameters for that request (Microsoft). Clearly, the service does not make use of any of the REST principles we have discussed thus far, not to mention the cost of having a whole other additional data format on top of HTTP.

在请求的主体中描述了所有内容,包括操作(getQuotation)和该请求的参数(Microsoft)。 显然,该服务未利用我们到目前为止讨论的任何REST原理,更不用说在HTTP之上具有其他所有附加数据格式的成本。

级别1:资源 (Level 1: Resources)

The next step on our path to complete RESTful-ness is introducing resources based abstractions. This is the equivalent of breaking up the application into distinct resource specific URLs. It’s characterized by Richardson as the “Multiple URLs, One Method” implementation.

完成RESTful-ness的下一步是引入基于资源的抽象。 这相当于将应用程序分解为不同的资源特定的URL。 理查森(Richardson)将其称为“多个URL,一种方法”实施。

Here, there are several different URLs in the system working together to provide the desired functionality. But each accepts only one type of requests (again, usually POST).

在这里,系统中有几个不同的URL协同工作以提供所需的功能。 但是每个都只接受一种类型的请求(同样,通常是POST)。

So for example, continuing our previous example, we can proceed to first retrieve a list of all companies from our application:

因此,例如,继续前面的示例,我们可以首先从应用程序中检索所有公司的列表:

POST /companies[  {    "name" : "Microsoft",    "id" : 3  },   {    "name" : "Apple",    "id" : 4  }]

…and then get a quotation for a single company:

…然后获得一家公司的报价:

POST /quotations/3
{  quotation: {}}

This is definitely a step up from before. In fact, this is how a lot of applications had been written until REST gained popularity. But again, we aren’t utilizing the strengths of HTTP. We can do better!

这绝对是从前的一步。 实际上,这就是在REST流行之前编写许多应用程序的方式。 但同样,我们没有利用HTTP的优势。 我们可以做得更好!

2级:动词 (Level 2: Verbs)

Now we throw the concept of action verbs into the mix. In addition to having well defined resources, the actions that can be performed on a resource must strictly follow HTTP conventions.

现在,我们将动作动词的概念混入其中。 除了拥有定义明确的资源外,可对资源执行的操作还必须严格遵循HTTP约定。

A GET MUST not modify the resource state, a POST MUST only be used for resource creation, and so on. It is characterized as, of course, the “Many URLs, Many Actions” system.

GET绝不能修改资源状态,POST只能用于资源创建,依此类推。 它的特征当然是“许多URL,许多操作”系统。

This brings us to the services most of us are familiar with and use on a day to day basis. These are also the kind of services that we usually consider RESTful. However, there is one more level that services must conform to in order to achieve the coveted status of complete RESTfulness.

这使我们获得了我们大多数人每天都熟悉和使用的服务。 这些也是我们通常认为是RESTful的服务。 但是,服务必须达到一个更高的级别,才能达到令人羡慕的完全RESTful状态。

第3级:HATEOAS (Level 3: HATEOAS)

This is where most services fall short. The vast majority of APIs and web services that you encounter as a developer, or likely ones that you will work on likely don’t follow the principle of HATEOAS.

这是大多数服务不足的地方。 作为开发人员或您将要使用的开发人员遇到的绝大多数API和Web服务可能都不遵循HATEOAS的原理。

Most service providers still prefer to document their services traditionally, by providing developers with a list of available endpoints along with some information on how to interact with that endpoint. Here’s the Twitter REST API, for example. (Interestingly, the PayPal API strongly pushes for Hypermedia Controls.)

大多数服务提供商仍然喜欢通过传统方式记录其服务,方法是为开发人员提供可用端点的列表以及有关如何与该端点进行交互的一些信息。 例如,这是Twitter REST API 。 (有趣的是,PayPal API 强烈推动了超媒体控件。)

This isn’t necessarily bad. There are some good arguments to be made both in favor of and against utilizing HATEOAS. While on the one hand it makes APIs easy to discover and use, that usually comes at the cost of more development time and effort.

这不一定是坏事。 无论是赞成还是反对利用HATEOAS,都有一些很好的论据。 一方面,它使API易于发现和使用,但通常以花费更多的开发时间和精力为代价。

In fact, if all you need to do is make a single call to the API, introducing HATEOAS may actually make things more difficult for you as a consumer.

实际上,如果您需要做的只是对API的一次调用,那么引入HATEOAS可能实际上会使您作为消费者变得更加困难。

结论 (Conclusion)

At the end of the day, these measures aren’t something you need to be swear by. REST, along with all it’s constraints, is merely a tool in your tool belt when building web services and applications. It’s entirely up to you to take from it what best fits your needs.

归根结底,这些措施并不是您需要保证的。 REST及其所有约束条件,在构建Web服务和应用程序时只是工具带中的工具。 完全取决于您的需求,这完全取决于您。

I hope you learned a lot of useful concepts from this series. If you’re looking to create a RESTful web service to supplement your next project, or looking to work with an existing one, you should now have a good understanding of some of the rationales behind them.

希望您从本系列中学到了许多有用的概念。 如果您希望创建一个RESTful Web服务来补充您的下一个项目,或者希望与现有的项目一起使用,那么您现在应该对它们背后的一些原理有很好的了解。

Here are the links to the previous parts, in case you missed them:

如果您错过了它们,以下是前几部分的链接:

RESTful Services Part I: HTTP in a Nutshell

RESTful服务的第一部分:简而言之的HTTP

RESTful Services Part II: Constraints and Goals

RESTful服务第二部分:约束和目标

Let me know what you thought of this post in the comments, or contact me via LinkedIn.

在评论中让我知道您对此帖子的看法,或者通过LinkedIn与我联系。

Don’t forget to hit the ? if you enjoyed this article.

别忘了打吗? 如果您喜欢这篇文章。

Cheers and happy learning!

祝您学习愉快!

More Resources

更多资源

  • Martin Fowler’s Blog

    马丁·福勒的博客

  • Leonard Richardson’s presentation

    伦纳德·理查森(Leonard Richardson)的演讲

  • SOAP example borrowed from TutorialsPoint

    从TutorialsPoint借用的SOAP示例

翻译自: https://www.freecodecamp.org/news/restful-services-part-iii-hateoas-and-the-richardson-maturity-model-48d4e4c79b8d/

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

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

相关文章

mongdb集群3.4 shard 模式

从图中可以看到有四个组件&#xff1a;mongos、config server、shard、replica set。mongos&#xff1a;数据库集群请求的入口&#xff0c;所有的请求都通过mongos进行协调&#xff0c;不需要在应用程序添加一个路由选择器&#xff0c;mongos自己就是一个请求分发中心&#xff…

我想变得富有的10个理由

1.我想和娘家人住得近一些&#xff0c;可以经常见面、聊天、逛街、吃饭。我们需要彼此的时候&#xff0c;可以马上赶到。 2.我想在家人病痛的时候&#xff0c;能得到最好的救治。 3.我想住在干净宽敞的大房子里&#xff0c;不要和长辈住^_^ 4.我希望不用我动手&#xff0c;家里…

alpha值计算 qcolor_量化交易与机器学习(四):如何研究alpha因子

算法交易策略由指示何时购买或出售资产以产生相对于基准&#xff08;例如指数&#xff09;的较高回报的信号驱动。 资产回报率中未通过暴露于该基准而无法解释的部分称为alpha&#xff0c;因此旨在产生这种不相关收益的信号也称为alpha因子。本章主要介绍alpha因子一、从数据到…

项目启动及需求分析(靳嘉豪、胡新宇、李晨曦、杨航、李瑶)团队作业

&#xff08;1&#xff09; 这次团队我们给我们团队起的名字是&#xff1a;桥上吊刀刀倒吊着 队员分别为&#xff1a;靳嘉豪、胡新宇、李晨曦、李瑶、杨航。 队训为&#xff1a;黑化肥挥发发灰会挥发。 胡新宇&#xff1a;http://www.cnblogs.com/hxy94264/ 靳嘉豪&#xff1a;…

java两种传参,有关java参数的两种传递机制

值传递&#xff1a;方法调用时&#xff0c;实际参数把它的值传递给对应的形式参数&#xff0c;方法执行中形式参数值的改变不影响实际参 数的值。引用传递&#xff1a;也称为传地址。方法调用时&#xff0c;实际参数的引用(地址&#xff0c;而不是参数的值)被传递给方法中相对应…

tcp选项部分编码_学习编码中最难的部分也是最有趣的部分

tcp选项部分编码by Corey Slaven通过Corey Slaven 学习编码中最难的部分也是最有趣的部分 (The hardest part of learning to code is also the funnest part) “The more you know, the more you know you don’t know.”“知道的越多&#xff0c;知道的越多。” ― Aristotl…

SCU 4439 Vertex Cover(二分图最小覆盖点)题解

题意&#xff1a;每一条边至少有一个端点要涂颜色&#xff0c;问最少涂几个点 思路&#xff1a;最小顶点覆盖&#xff1a;用最少的点&#xff0c;让每条边都至少和其中一个点关联&#xff0c;显然是道裸最小顶点覆盖题&#xff1b; 参考&#xff1a;二分图 代码&#xff1a; #i…

20155229 实验一《Java开发环境的熟悉》实验报告

20155229 实验一《Java开发环境的熟悉》实验报告 实验内容 1.使用JDK编译、运行简单的Java程序&#xff1b; 2.使用Idea 编辑、编译、运行、调试Java程序。 实验步骤 &#xff08;一&#xff09;命令行下Java程序开发 输入 mkdir 20155229命令建立实验目录&#xff0c;用ls查看…

js时间搓化为今天明天_js转时间戳,时间戳转js

js转时间戳转此时此刻的时间1、var timestamp1 (new Date()).valueOf();valueOf() 方法返回指定对象的原始值2、var timestamp2 new Date().getTime();Date.prototype.getTime()方法的返回值一个数值&#xff0c;表示从1970年1月1 日0时0分0秒(UTC&#xff0c;即协调世界时)距…

PHP代码20个实用技巧(转)

这些技巧特别是封装的&#xff0c;相对路径的还是挺好的&#xff0c;本身来自微信公众号&#xff0c;但是我担心以后删除&#xff0c;所以在我的博客上备份一下&#xff08;微信公众号为:菜鸟教程&#xff09; 在这篇文章中我们将看看一些关于PHP开发有用的提示和技巧&#xff…

需求简报_代码简报:NASA将所有研究成果发布为开放数据

需求简报Here are three stories we published this week that are worth your time:这是我们本周发布的三个值得您关注的故事&#xff1a; With open data, you finally get what you’ve paid for all these years: 4 minute read 有了开放的数据&#xff0c;您终于可以得到…

matlab 16位灰度值转8位,在matlab中如何将灰度值为24位的转化为8?

我使用的是Visual c6。0技术内幕里提供的类CDib来操作位图&#xff0c;最好提供可以两个独立的函数来分辨别实现着俩个功能。他们可以作为CDib类的成员函数来使用。类似下面的这个就可以&#xff0c;我用了下面的这个&#xff0c;但是下面这个不好用&#xff0c;处理后的图象有…

quartz基本使用

创建一个任务调度 Scheduler scheduler StdSchedulerFactory.getDefaultScheduler();//Schedulers can be immediately used to schedule jobs, but they will not start executing any until the .start()scheduler.start();//And then schedule those jobs with triggers th…

em模型补缺失值_基于EM算法数据单变量缺失处理方法研究

龙源期刊网http://www.qikan.com.cn基于EM算法数据单变量缺失处理方法研究作者&#xff1a;黄铉来源&#xff1a;《科技传播》2015年第20期摘要数据分析方法大都针对完整数据&#xff0c;而实际上由于一些原因&#xff0c;观测数据常存在缺失。本文采用EM算法对正态分布下的随机…

流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls)

RTP 参考文档 RFC3550/RFC3551 Real-time Transport Protocol)是用于Internet上针对多媒体数据流的一种传输层协议。RTP协议详细说明了在互联网上传递音频和视频的标准数据包格式。RTP协议常用于流媒体系统&#xff08;配合RTCP协议&#xff09;&#xff0c;视…

我从#100DaysOfCode中学到的东西

by E. Wilson由E. Wilson 我从&#xff03;100DaysOfCode中学到的东西 (What I learned from #100DaysOfCode) I made it up to Day 95 before officially ending my #100DaysOfCode challenge. Check out my GitHub repo and see for yourself.在正式结束&#xff03;100Days…

mysql 表ful,你所不知的table is full那些事

当我们要写入新数据而发生“The table is full”告警错误时&#xff0c;先不要着急&#xff0c;按照下面的思路来逐步分析即可&#xff1a;1、查看操作系统以及MySQL的错误日志文件确认操作系统的文件系统没有报错&#xff0c;并且MySQL的错误日志文件中是否有一些最直观的可见…

Calendar、Date、long类型的时间,三者之间如何转化

1. Calendar类型转化为Date类型和long类型 Calendar calendarCalendar.getInstance(); Date datecalendar.getTime(); long timecalendar.getTimeInMillis(); 2.Date类型转化为Calendar类型和long类型 Date datenew Date(System.currentTimeMillis()100000000); Calendar calen…

sit是什么环境_软件环境常识 --dev sit uat

DEV环境&#xff1a;DEV顾名思义就是develop&#xff0c;即代码开发的环境。SIT环境&#xff1a;System Integration Test系统集成测试&#xff0c;开发人员自己测试流程是否走通。UAT环境&#xff1a;User Acceptance Test用户验收测试&#xff0c;由专门的测试人员验证&#…

python基础数据类型的相关知识点

1、字符串的函数join >>> s "Hello" >>> s1 s.join("你好")#将字符串Hello插入到你好中 >>> s1 你Hello好 >>> s2 "Tanxu".join("你好吗")#将字符串Tanxu插入到你好吗中 >>> s2 你Ta…