用Restlet创建面向资源的服务

article/2025/9/21 9:02:34

Restlet项目(http://www.restlet.org)为“建立REST概念与Java类之间的映射”提供了一个轻量级而全面的框架。它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务;而且,事实证明它自从2005年诞生之时起,就是一个可靠的软件。

Restlet项目受到Servlet API、JSP(Java Server Pages)、HttpURLConnection及Struts等Web开发技术的影响。该项目的主要目标是:在提供同等功能的同时,尽量遵守Roy Fielding博士论文中所阐述的REST的目标。它的另一个主要目标是:提出一个既适于客户端应用又适于服务端的应用的、统一的Web视图。

Restlet的思想是:HTTP客户端与HTTP服务器之间的差别,对架构来说无所谓。一个软件应可以既充当Web客户端又充当Web服务器,而无须采用两套完全不同的APIs。

Restlet包括Restlet API和Noelios Restlet Engine(NRE)两部分,NRE是对Restlet API的一种参考实现。这种划分,使得不同实现可以具有同样的API。NRE包括若干HTTP服务器连接器(HTTP server connector),它们都是基于Mortbay的Jetty、Codehaus的AsyncWeb,以及Simple框架这些流行的HTTP Java开源项目的。它甚至提供一个适配器(adapter),使你可以在标准Servlet容器(如Apache Tomcat)内部署一个Restlet应用。

Restlet还提供两个HTTP客户端连接器(HTTP client connector)。它们一个是基于官方的HttpURLConnection类,一个是基于Apache的HTTP客户端库。还有一个连接器允许你容易地按REST风格通过XML文档来处理JDBC源(source);此外,一个基于JavaMail API的SMTP连接器允许你发送内容为XML的Email。

Restlet API包括一些能够创建基于字符串、文件、流(stream)、通道(channel)及XML文档的表示(representation),它支持SAX、DOM及XSLT。使用FreeMaker或Apache Velocity模板引擎,你可以很容易地创建基于JSP式模板的表示(representations)。你甚至可以像普通Web服务器那样,用一个支持内容协商(content negotiation)的Directory类来返回静态文件与目录。

简单性(simplicity)和灵活性(flexibility)是贯穿整个框架的设计原则。Restlet API旨在把HTTP、URI及REST的概念抽象成一系列类(classes),同时又不把低层信息(如原始HTTP报头)完全隐藏起来。

基本概念

Restlet在术语上参照了Roy Fielding博士论文在讲解REST时采用的术语,如:资源(resource)、表示(representation)、连接器(connector)、组件(component)、媒体类型(media type)、语言(language),等等。这些术语你应该不会陌生。Restlet增加了一些专门的类(如Application、Filter、Finder、Router和Route),用以简化restlets的彼此结合,以及简化把收到的请求(incoming requests)映射为处理它们的资源。

图12-1:Restlet的类层次结构

抽象类Uniform及其具体子类Restlet,是Restlet的核心概念。正如其名称所暗示的,Uniform暴露一个符合REST规定的统一接口(uniform interface)。虽然该接口是按HTTP统一接口定义的,但它也可用于其他协议(如FTP和SMTP)。

handle是一个重要的方法,它接受两个参数:Request和Response。正如你可以从图12-1中看到的,每个暴露于网上的调用处理者(call handler)(无论作为客户端还是服务端)都是Restlet的一个子类——也就是说,它是一个restlets——并遵守这个统一接口。由于有统一接口,restlets可以非常复杂的方式组合在一起。

Restlet支持的每一个协议都是通过handle方法暴露的。这就是说,HTTP(服务器和客户端)、HTTPS、SMTP,以及JDBC、文件系统,甚至类加载器(class loaders)都是通过调用handle方法来操作的。这减少了开发者需掌握的APIs的数量。

过滤、安全、数据转换及路由是“通过把Restlet的子类链起来”进行处理的。Filters可以在处理下个restlet调用之前或之后进行处理。Filters实例的工作方式与Rails过滤器差不多,只不过Filters实例跟其他Restlet类一样响应handle方法,而不是具有一个专门的API。

一个Router restlet有许多附属的Restlet对象,它把每个收到的协议调用(incoming protocol call)路由给适当的Restlet处理器。路由(routing)通常是根据目标URI进行的。跟Rails不同的是,Restlet没有对资源层次结构(resource hierarchy)作URI规则限定,所以可以随意设置想要的URI,只要对Routers作相应编程就行了。

除了这一常见用途,Router还可用于其他用途。你可以用一个Router在多台远程机器之间以动态负载均衡的方式来转发调用。即使在这种复杂的情况下,它也一样响应Restlet的统一接口,并且可成为一个更大路由系统中的一个组件。VirtualHost类(Router的一个子类)使我们可以在同一台物理主机上运行多个具有不同域名的应用。在过去,你要引入一个前端Web服务器(如Apache的httpd)才能实现此功能;而用Restlet的话,它只是另一个响应统一接口的Router实现。

一个Application对象能够管理一组restlets,并提供常见的服务,比方说对压缩的请求进行透明解码,或者利用method查询参数在重载的POST(overloaded POST)之上实现PUT和DELETE请求。最后,Component对象可以包含并编配(orchestrate)一组Connectors、VirtualHosts及Applications(作为独立Java应用运行的,或者嵌入在一个更大系统(如J2EE环境)中的)。

在第6章,我向你介绍了“把一个问题划分为一组响应HTTP统一接口的资源”的步骤。在第7章,为了处理Ruby on Rails的简单化假设(simplifying assumptions),我对该步骤作了相应的调整。因为Restlet没有做简单化假设(simplifying assumptions),所以我们无须对此步骤进行修改。它可以实现任何REST式系统。如果你刚好想实现一个REST式面向资源的Web服务,可以按愿意的方式来组织和实现这些资源。Restlet确实提供了一些便于创建面向资源的应用的类。其中特别值得一提的是Resource类,它可作为你所有应用资源的基础。

我在本书中一直用URI模板作为一组URIs的简化表达(见第9章)。Restlet用URI模板来进行URI与资源的映射。假如用Restlet来实现第7章那个社会性书签服务的话,它也许要指定一个代表特定书签的URI:

/users/{username}/bookmarks/{URI}

你可以在把Resource子类附加到Router上时使用这种语法。假如你不相信真会这么好的话,可以等到下一节,那时我会实际实现部分书签服务。

编写Restlet客户端

在示例2-1中,你看到的是一个从Yahoo!搜索服务获取XML搜索结果的Ruby客户端。示例12-3是一个用Java参照Restlet 1.0实现的具有同样功能的客户端。要确保把以下JAR包写在你的classpath中,才能成功编译并运行接下来的例子:

  • org.restlet.jar(Restlet API)
  • com.noelios.restlet.jar (Noelios Restlet Engine核心)
  • com.noelios.restlet.ext.net.jar (基于JDK的HttpURLConnection的HTTP客户端连接器)

这些JAR包可以在Restlet发布包中的lib目录里找到。要确保你的Java环境支持Java SE 5.0(或更高)版本。如果你确实需要的话,可以用Retrotranslator(http://retrotranslator. sourceforge.net/)轻易地把Restlet代码反移植(backport)到J2SE 4.0版上去。

示例12-3:Yahoo!搜索服务的一个Restlet客户端

// YahooSearch.java
import org.restlet.Client;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Response;
import org.restlet.resource.DomRepresentation;
import org.w3c.dom.Node;/*** 用返回XML的Yahoo!搜索服务来搜索Web */
public class YahooSearch {static final String BASE_URI = "http://api.search.yahoo.com/WebSearchService/V1/webSearch";public static void main(String[] args) throws Exception {if (args.length != 1) {System.err.println("You need to pass a term to search");} else {// 获取一个资源,即一个包含搜索结果的XML文档String term = Reference.encode(args[0]);String uri = BASE_URI + "?appid=restbook&query=" + term;Response response = new Client(Protocol.HTTP).get(uri);DomRepresentation document = response.getEntityAsDom();// 用XPath找出数据结构中重要部分String expr = "/ResultSet/Result/Title";for (Node node : document.getNodes(expr)) {System.out.println(node.getTextContent());}}}
} 

跟示例2-1一样,你可以在执行这个类时把一个搜索关键字作为命令行参数传给它。比如像下面这样:

$ java YahooSearch xsltXSL Transformations (XSLT) The Extensible Stylesheet Language Family (XSL)XSLT Tutorial...

该示例证明了“用Restlet从Web服务获取XML数据,并用标准工具处理它”是极其简单的事。Yahoo!资源的URI是用一个常量和用户提供的搜索关键字构造而成的。客户端连接器(client connector)是用HTTP协议来初始化的。XML文档是通过get方法获得的,该方法对应于HTTP统一接口的GET方法。当调用返回时,程序将得到一个DOM表示。跟前面的Ruby例子一样,XPath是对XML进行查询的最简单方式。

跟前面的Ruby例子一样,这个程序也忽略了XML文档里的XML名称空间(namespaces)。Yahoo!为整个文档采用名称空间urn:yahoo:srch,但我是直接引用标签的,比方说,我用ResultSet,而不是urn:yahoo:srch:ResultSet。前面的Ruby例子忽略名称空间,是因为Ruby的默认XML解析器不支持名称空间。Java的XML解析器支持名称空间,而且Restlet API令正确处理名称空间变得更加容易。虽然对上面那个简单例子来说,它们区别不大,但支持名称空间可以避免一些因名称空间而导致的微妙的问题。

当然,若一直用urn:yahoo:srch:ResultSet,是比较烦人的。Restlet API可以容易地把一个简短前缀跟一个名称空间进行关联,然后就可以在XPath表达式中使用这个简短前缀而不是整个名称空间了。示例12-4对示例12-3后半部分代码作了改动,它使用了带名称空间的Xpath,这样就不会把来自Yahoo!的ResultSet标签与来自其他名称空间的标签搞混了。

示例12-4:支持名称空间的文档处理代码

            DomRepresentation document = response.getEntityAsDom();// 把该名称空间与前缀‘y’关联起来document.setNamespaceAware(true);document.putNamespace("y", "urn:yahoo:srch");// 用XPath找出数据结构中重要部分String expr = "/y:ResultSet/y:Result/y:Title/text()";for (Node node : document.getNodes(expr)) {System.out.println(node.getTextContent());}

示例2-15是Yahoo!搜索服务的另一个Ruby客户端。它请求的是JSON格式(而不是XML格式)的搜索数据。示例12-5是一个与之功能等价的Restlet客户端。它通过Restlet里的另两个JAR文件获取JSON支持:

  • org.restlet.ext.json_2.0.jar(用于JSON的Restlet扩展)
  • org.json_2.0/org.json.jar(JSON官方程序库)

示例12-5:Yahoo!的JSON搜索服务的一个Restlet客户端

// YahooSearchJSON.java
import org.json.JSONArray;
import org.json.JSONObject;
import org.restlet.Client;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Response;
import org.restlet.ext.json.JsonRepresentation;/*** 用返回JSON的Yahoo!搜索服务来搜索Web */
public class YahooSearchJSON {static final String BASE_URI ="http://api.search.yahoo.com/WebSearchService/V1/webSearch";public static void main(String[] args) throws Exception {if (args.length != 1) {System.err.println("You need to pass a term to search");} else {// 获取一个资源,即一个包含搜索结果的JSON文档String term = Reference.encode(args[0]);String uri = BASE_URI + "?appid=restbook&output=json&query=" + term;Response response = new Client(Protocol.HTTP).get(uri);JSONObject json = new JsonRepresentation(response.getEntity()).toJsonObject();// 在JSON文档中寻找并显示标题JSONObject resultSet = json.getJSONObject("ResultSet");JSONArray results = resultSet.getJSONArray("Result");for (int i = 0; i < results.length(); i++) {System.out.println(results.getJSONObject(i).getString("Title"));}}}
}

当你为Yahoo!的Web服务编写客户端时,可以选择表示格式(representation format)。Restlet核心API支持XML,另外还可以通过扩展支持JSON。正如你所预料的那样,这两个例子的区别仅仅在于对响应的处理上。JsonRepresentation类可以把响应实体主体(response entity-body)转换成一个JSONObject实例(而Ruby的JSON库是把JSON数据结构转换成一个本地数据结构)。该数据结构只能进行人工遍历,因为目前JSON中还没有类似XPath的查询语言。

编写Restlet服务

接下来的例子会稍微复杂一些。我将向你展示如何设计并实现一个服务端应用。在第7章,我用Ruby on Rails实现了一个书签管理应用,现在我用Restlet来重新实现其部分功能。为了简单起见,该应用只支持对用户及其书签进行安全的(safe)操作。

Java包结构是这样的:

org restletexamplebookrestch7-Application-ApplicationTest-Bookmark-BookmarkResource-BookmarksResource-User-UserResource

也就是说,Bookmark等类都在org.restlet.example.book.rest.ch7包里。

我不打算在此展示完整的代码。如果需要,你可以去本书的官方网站(http://www.oreilly. com/catalog/9780596529260),那里提供了本书的所有示例程序代码。你也可以在restlet.org(http://www.restlet.org)上找到本例的完整代码。如果你已经下载了Restlet的话,那么也可以在src/org/restlet.example/org/restlet/example/book/rest目录里找到本节的示例代码。

我将从一些简单的代码开始。示例12-6是Application.main方法,它用来建立Web服务器,并开始处理请求。

示例12-6:Application.main方法:建立Web服务器

public static void main(String... args) throws Exception {// 用HTTP服务器连接器创建一个组件Component comp = new Component();comp.getServers().add(Protocol.HTTP, 3000);// 把应用附加到默认主机上,并启动comp.getDefaultHost().attach("/v1", new Application());comp.start();
}

资源与URI设计

由于Restlet未对资源设计作特别的限制,所以你完全可以根据ROA的设计原则来进行资源类(resource classes)及URIs的设计。在第7章,我要围绕“Rails的基于控制器的架构”来进行设计;而这里,我不需要围绕Restlet架构来进行设计。图12-2 展示了URI是如何经由Router映射到资源,再映射到下层restlet类的。

图12-2:社会性书签应用的Restlet架构

为了理解如何用Java代码实现这些映射,我们来看一下Application类及它的createRoot 方法(见示例12-7)。它跟示例7-3所示的Rails routes.rb文件在功能上是等价的。

示例12-7:Application.createRoot方法:实现URI模板到restlet的映射

public Restlet createRoot() {Router router = new Router(getContext());// 为用户资源增加路由router.attach("/users/{username}", UserResource.class);// 为用户的书签资源增加路由router.attach("/users/{username}/bookmarks", BookmarksResource.class);// 为书签资源增加路由Route uriRoute = router.attach("/users/{username}/bookmarks/{URI}",BookmarkResource.class);uriRoute.getTemplate().getVariables().put("URI", new Variable(Variable.TYPE_URI_ALL));
}

在我创建一个Application对象(比如像示例12-6中的那样)时,这段代码便会运行。它会在资源类UserResource与URI模板“/users/(username)”之间建立起清晰而直观的映射关系。Router先拿请求的目标URI跟URI模板(URI templates)进行比较,然后把请求转发给一个新建的相应的资源类实例。模板变量的值被存放在请求的属性地图(attributes map)里(跟Rails例子中的params地图类似),以便于在Resource代码中使用。这既有效,又易于理解;当你事隔很久再回顾代码时,这很有帮助。

请求处理和表示

假定一个客户端向URI http://localhost:3000/v1/users/jerome发出GET请求。我有一个监听本地主机3000端口的Component对象,和一个隶属于 /v1 的Application对象。该Application有一个Router和一组Route对象,这些Route对象正等待着跟各个URI模板匹配的请求。 URI路径片段“/users/jerome”跟模板“/users/{username}”相匹配,而该模板的Route是与UserResource类(大致等价于Rails UsersController类)相关联的。

Restlet通过初始化一个新的UserResource对象,并调用它的handleGet方法来处理该请求。示例12-8是UserResource类的构造方法。

示例12-8:UserResource类的构造方法

/*** 构造方法** @param context*           上级上下文* @param request*           要处理的请求* @param response*           要返回的响应*/public UserResource(Context context, Request request, Response response) {super(context, request, response);this.userName = (String) request.getAttributes().get("username");ChallengeResponse cr = request.getChallengeResponse();this.login = (cr != null) ? cr.getIdentifier() : null;this.password = (cr != null) ? cr.getSecret() : null;this.user = findUser();if (user != null) {getVariants().add(new Variant(MediaType.TEXT_PLAIN));}
}

至此,这个架构已经建立了一个Request对象,它包含了我所需要的关于请求的所有信息。username属性来自URI,认证证书来自请求的Authorization报头。我还调用findUser方法来根据认证证书在数据库中查找用户(为节省篇幅,我就不在此展示findUser方法的代码了)。这些工作在第7章都是由Rails过滤器完成的。

在框架把一个UserResource实例化后,它会对资源对象调用适当的handle方法。HTTP统一接口中的每一个方法,都有一个对应handle方法。 在这个例子中,Restlet架构最后的任务是调用UserResource.handleGet。

由于我没有定义UserResource.handleGet这个方法,所以它将具有继承Resource. handleGet方法的行为。HandleGet的默认行为是找到最符合客户端要求的资源的表示。客户端通过内容协商(content-negotiation)来表达它的要求。Restlet通过Accept报头的值来决定返回哪个表示。由于这里只有一个表示格式,所以客户端的要求不起作用。这是由getVariants和getRepresentation方法处理的。由于在上述构造方法中把text/ plain定义为唯一支持的表示格式,所以我的getRepresentation方法的实现是很简单的(见示例12-9)。

示例12-9:UserResoure.getRepresentation:构造一个用户的表示

@Override
public Representation getRepresentation(Variant variant) {Representation result = null;if (variant.getMediaType().equals(MediaType.TEXT_PLAIN)) {// 创建一个文本表示StingBuilder sb=new StringBuilder();sb.append("------------\n");sb.append("User details\n");sb.append("------------\n\n");sb.append("Name:  ").append(this.user.getFullName()).append('\n');sb.append("Email: ").append(this.user.getEmail()).append('\n');result = new StringRepresentation(sb);}return result;
}

虽然这只是一个资源的一个方法,但其他资源,以及UserResource的其他HTTP方法的工作原理都差不多,比如:对用户的PUT请求将被路由给UserResource.handlePut,等等。正如我前面所提到的,这里的代码只是社会性书签应用所有代码的一部分;所以,如果你有兴趣进一步学习的话,可以去下载一个完整的示例代码来阅读。

现在,你应该了解Restlet架构是如何把收到的(incoming)HTTP请求路由给特定的Resource类,然后再路由给该类的特定方法了。你也应该知道如何由资源状态来构造表示(representations)了。一般,只要关注Application和Router代码一次就行,因为一个Router可用于你的所有资源。

编译、运行与测试

Application类实现了运行社会性书签服务的HTTP服务器。你需要在classpath中加入以下JAR文件:

  • org.restlet.jar
  • com.noelios.restlet.jar
  • com.noelios.restlet.ext.net.jar
  • org.simpleframework_3.1/org.simpleframework.jar
  • com.noelios.restlet.ext.simple_3.1.jar
  • com.db4o_6.1/com.db4o.jar

这些JAR包可以在Restlet发布包中的lib目录里找到。有两点需要注意:第一,Web服务器的实际工作是由一个非常紧凑的、基于Simple框架的HTTP服务器连接器来处理的;第二,我们是用强大的db4o对象数据库(而不是关系数据库)来存储领域对象(用户和书签)的。在编译好所有示例文件后,运行org.restlet.example.book.rest.ch7. Application,它将作为服务器的端点(endpoint)。

ApplicationTest类为服务提供了一个客户端接口。它采用上节描述的Restlet客户端类来添加和删除用户和书签。它是通过HTTP统一接口进行工作的:用PUT请求创建用户和书签,用DELETE请求删除用户和书签。

在命令行下运行ApplicationTest类,你将得到以下消息:

   Usage  depends  on  the  number  of  arguments:
-  Deletes  a  user                     :  userName,  password
-  Deletes  a  bookmark         :  userName,  password,  URI
-  Adds  a  new  user               :  userName,  password,  "full  name",  email
-  Adds  a  new  bookmark   :  userName,  password,  URI,  shortDescription,longDescription,  restrict[true  /  false]

你可以用这个程序来添加一些用户,并增加一些书签。然后,你就可以在Web浏览器中通过访问适当的URI(如http://localhost:3000/v1/users/jerome等)来浏览用户书签的HTML表示了。

小结

Restlet项目在2007年初发布了1.0正式版。它只用了12个多月的开发时间。目前,该项目具有一个繁荣的开发与用户群体。Restlet邮件列表很友好,不论是新手,还是有经验的开发者,它都欢迎。作为该项目的创建者,Noelios咨询公司是主要的开发力量,他们也提供专业的支持计划与培训。

在本书编写之时,1.0版处于维护中,新的1.1版已经开始开发了。该项目计划将来把Restlet API提交给JCP(Java Community Process)。还有一个用于REST式Web服务的高层API,它已由Sun公司提交给JCP(JSR311)。这个高层API使得“把Java领域对象暴露为REST式资源”更加容易。这将是对Restlet API(尤其是其Resource类)的一个很好的补充。Noelios咨询公司是最初的专家组成员,他们将根据标准的进展来对Restlet引擎作相应的更新。


本文节选自博文视点出版公司即将推出的经典著作《RESTful Web Services中文版》中的第12章《REST式服务框架》。

《RESTful Web Services中文版》向读者介绍了什么是REST、什么是面向资源的架构(Resource-Oriented Architecture,ROA)、REST式设计的优点、REST式Web服务的真实案例分析、如何用各种流行的编程语言编写Web服务客户端、如何用三种流行的框架(Ruby on Rails、Restlet和Django)实现REST式服务等。不仅讲解REST与面向资源的架构(ROA)的概念与原理,还向读者介绍如何编写符合 REST风格的Web 2.0应用。本书详实、易懂,实战性强,提供了大量RESTful Web服务开发的最佳实践和指导,适合广大的Web开发人员、Web架构师及对Web开发或Web架构感兴趣的广大技术人员与学生阅读。

与此同时,博文视点还授权InfoQ中文站独家为大家提供额外的样章进行试读:欢迎下载第3章《REST式服务有什么不同》

9 条回复



http://chatgpt.dhexx.cn/article/pHw4ohd2.shtml

相关文章

RESTlet——轻量级REST框架

https://github.com/restlet/restlet-framework-java https://restlet.talend.com/

ResT解读

最近的一篇基于Transformer的工作&#xff0c;由南京大学的研究者提出一种高效的视觉Transformer结构&#xff0c;设计思想类似ResNet&#xff0c;称为ResT&#xff0c;这是我个人觉得值得关注的一篇工作。 简介 ResT是一个高效的多尺度视觉Transformer结构&#xff0c;可以作…

Restlet入门示例

http://cunfu.iteye.com/blog/757467 本文的目的在于完成一个Restlet入门示例。 首先&#xff0c;是一个Stand alone应用。 然后&#xff0c;将其部署与Tomcat容器中。 最后&#xff0c;完成Restlet与Spring的整合。 1.按照官方教程&#xff0c;完成“firstSteps” 创建…

RestLet框架的入门

官网地址 创建maven工程&#xff08;war)pom.xml文件中导入jar包 <repositories><repository><id>restlet</id><url>http://maven.restlet.com/</url></repository></repositories><dependencies><dependency>&l…

Restlet

转载自http://my.oschina.net/javagg/blog/3254 关于本指南 本指南的翻译工作经过了Restlet社区的官方授权&#xff0c;cleverpig作为贡献者完成了本文的翻译和整理工作。在此发布Matrix社区试读版的目的是为了让更多的技术爱好者阅读并提出翻译中的不足之处&#xff0c;以提高…

restlet处理各种请求方式参考示例

restlet处理各种请求方式参考示例 1.新建web工程&#xff0c;项目结构如下&#xff1a; 1.编写实体类Student.java&#xff1a; package test;public class Student {private String name;private String sex;private int age;public Student(String name,String sex,int age){…

使用Restlet Client发送各种Get和Post请求

在开发web应用时&#xff0c;在对Spring中的Controller进行测试时&#xff0c;需要发送各种get以及post请求进行测试&#xff0c;当然可以自己在浏览器里输入url或者对于测试而言使用Spring提供的MockMvc编写代码进行测试&#xff0c;但是当我们想要测试诸如带Form表格提交&…

Restlet官方指南

Restlet官方指南 Table of contents Restlet overviewRetrieving the content of a Web pageListening to Web browsersOverview of a REST architectureComponents, virtual hosts and applicationsServing static filesAccess loggingDisplaying error pagesGuarding access …

谷歌安装Restlet Client插件

目录 一、Restlet Client插件下载链接二、Restlet Client插件安装步骤 一、Restlet Client插件下载链接 链接&#xff1a; https://pan.baidu.com/s/15rWwbQv6KlTS_T6tcpT_YA 提取码&#xff1a;6mxp 二、Restlet Client插件安装步骤 1、下载完Restlet-Client-v2.8.0.1.zip压…

Restlet指南

cleverpig 发表于 2007-11-30 15:15:48 作者:cleverpig 来源:Matrix 评论数:1 点击数:13,237 投票总得分:5 投票总人次:1 关键字:Restlet,REST,指南,入门 摘要: 当复杂核心化模式日趋强大之时&#xff0c;面向对象设计范例已经不总是Web开发中的最佳选择&#xff0c…

Restlet 学习笔记

摘要&#xff1a;网络上对 restlet 的评判褒贬不一&#xff0c;有的说框架封装的很好&#xff0c;很有弹性&#xff0c;有的说 rest 架构风格本身是一种简单的风格&#xff0c;restlet 过设计以使编程过于复杂&#xff0c;其实我倒不觉得 restlet 有什么复杂&#xff0c;相反很…

Restlet实战(一)Restlet入门资料及概念

先贴上几个本人认为比较有价值&#xff0c;值得初学者一看的文章。 http://www.matrix.org.cn/resource/article/2007-11-30/1312be72-9f14-11dc-bd16-451eadcf4db4.html http://blog.sina.com.cn/s/blog_537c5aab010096v8.html~typev5_one&labelrela_nextarticle http://…

Restlet 2.3 指南

2019独角兽企业重金招聘Python工程师标准>>> #Restlet 2.3 指南 #1. Restlet概述 Restlet框架由两个主要部分构成。首先&#xff0c;一部分是"Restlet API"&#xff0c;是一个中立的&#xff0c;支持REST概念&#xff0c;并能促进客户端、服务器端应用程序…

minio用法

1 Minio是在Apache License v2.0下发布的对象存储服务器。它与Amazon S3云存储服务兼容。 它最适合存储非结构化数据&#xff0c;如照片&#xff0c;视频&#xff0c;日志文件&#xff0c;备份和容器/ VM映像。对象的大小可以从几KB到最大5TB。 Minio服务器足够轻&#xff0c…

minio使用

一、介绍 开源协议的对象存储服务,轻量,性能强 二、安装 windows版链接: https://pan.baidu.com/s/1vv2p8bZBeZFG9cpIhDLVXQ?pwds5dd 提取码: s5dd 下载后创建minioData文件用于储存文件 创建run.bat脚本&#xff0c;内容如下 # 设置用户名 set MINIO_ROOT_USERadmin # …

CentOS Minimal 和 NetInstall 版本区别

Index of /centos/7.9.2009/isos/x86_64/ 如图&#xff1a; BinDVD版——就是普通安装版&#xff0c;需安装到计算机硬盘才能用&#xff0c;bin一般都比较大&#xff0c;而且包含大量的常用软件&#xff0c;安装时无需再在线下载&#xff08;大部分情况&#xff09;。 minim…

简易最小化虚拟机安装配置(CentOS-7-Minimal)

文章目录 镜像选择虚拟机安装&#xff08;VMware Workstation&#xff09;虚拟网络配置&#xff08;NAT模式&#xff09;虚拟网卡配置 虚拟机配置静态IP配置及测试系统初始化及库安装停止防火墙 & 关闭防火墙自启动关闭 selinux 防火墙更换镜像源并重建镜像源缓存安装 ifco…

pr双击打开图标没反应,下载ZXPSignLib-minimal.dll替换

微智启今天安装了pr cc2018&#xff0c;双击打开图标无反应 于是又试了Premiere cc2019&#xff0c;还是没反应 桌面还多出一些白色文件图标.crash结尾的 解决方案&#xff1a; 下载ZXPSignLib-minimal.dll文件&#xff0c;微智启软件工作室放到pr安装目录的根目录&#xff…

Minimal Square

文章目录 一、A. Minimal Square总结 一、A. Minimal Square 本题链接&#xff1a;A. Minimal Square 题目&#xff1a; A. Minimal Square time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Find the minimu…

出现minimal bash-like...的问题如何解决?

2021.9.4写下此文&#xff0c;以备查阅。 问题如图&#xff1a; 一般出现这个界面即为引导程序出现问题&#xff0c;根据下面两种情况看待&#xff1a; 卸载双系统之一&#xff08;比如之前是windeepin双系统&#xff0c;现在卸载了deepin系统&#xff09;重启时出现。安装新…