解决方案

Restlet 指南

seo靠我 2023-09-24 04:28:36

转载自:http://my.oschina.net/javagg/blog/3254

关于本指南

本指南的翻译工作经过了Restlet社区的官方授权,cleverpig作为贡献者完成了本文的翻译和整理工作SEO靠我。在此发布Matrix社区试读版的目的是为了让更多的技术爱好者阅读并提出翻译中的不足之处,以提高本指南的质量,以期修改后正式发布。

Servlet的限制

在2003年末,Jetty Web容器的作者、SeSEO靠我rvlet规范的贡献者:Greg Wilkins在其博客上对Servlet的问题进行了如下总计:

    * 没有对协议与应用之间的关系进行清洗的划分。

* 由于在设计Servlet时存在对阻塞IO的假设,因此不SEO靠我能充分利用非阻塞NIO机制。

    * 所有的Servlet Web容器对于某些应用来讲是过度设计的。

他提出构思新的API规范,使其能够真实地脱离协议,并定义能够暴露内容和元数据的contentlets。这些SEO靠我想法就是Restlet项目创建的灵感源泉。在之后的文章中,Greg Wilkins解释了为什么当前Servlet API限制非阻塞NIO API得到高效使用的详细理由:这种传统的用法针对每个HTTP请SEO靠我求都创建独立的线程进行处理。并提出了他对下一代Servlet技术的设想。

另一个主要问题就是Servlet API鼓励应用开发者在应用或者用户会话级别直接将session状态保存于内存中,尽管这看上去不SEO靠我错,但它造成了Servlet容器扩展性和高可用性的主要问题。为了克服这些问题,就必须实现复杂的负载均衡、session复制、持久化机制。这导致了可扩展性必然成为灾难。

Restlet简介

当复杂核心化模式SEO靠我日趋强大之时,面向对象设计范例已经不总是Web开发中的最佳选择,Java开发者需要认识到这一点,并且在开发新的Web服务端或是AJAX Web客户端时开始思考更加RESTfully的设计。RestleSEO靠我t这个开源项目为那些要采用REST结构体系来构建应用程序的Java开发者提供了一个具体的解决方案。它的非常简单易用的功能和RESTfully的Web框架,这使其成为了Web2.0开发中的又一利器。好吧SEO靠我,朋友们,下面就让我们开始Restlet探索之旅吧!

1. 注册一个Restlet实现

Restlet框架由两部分构成。第一部分是"Restlet API", 这个中立的API完美地实现了REST概念并简SEO靠我化了客户端和服务端应用的调用处理。在使用它之前,我们还需要一个支持此API的Restlet实现。Restlet的诸多实现可以通过开源项目或者商业产品获得。

API与实现的分离和Servlet API与wSEO靠我eb容器的分离(就像Jetty或Tomcat)、JDBC API与相应JDBC驱动的分离非常类似。目前,"Noelios Restlet Engine" (缩写为NRE)是Restle tAPI的参考SEO靠我实现之一。当下载Restlet发布版本时,API和NRE就绑定在一起,以备随时使用。如果你需要使用不同的实现,那么只需要添加JAR 文件到classpath,并删除com.noelios.restleSEO靠我t.jar这个NRE的JAR文件即可。

API实现的注册过程是完全自动的,如果你对此存在疑问,那么请参考JAR规范。当完成实现装载工作后,它将自动回调org.restlet.util.Engine.seSEO靠我tInstance()方法,来进行自注册。

2. 接收Web页面的内容

正如我们在Restlet介绍中所提到的,Restlet框架即是一个客户端,又是一个服务端框架。例如,NRE能够简单地通过它的HTTPSEO靠我客户端 connector(连接器)访问远程资源。在REST中,connector是一种软件元素,它使两个component(组件)之间能够进行通讯,其典型的实现方式是通过某种网络协议完成通讯。NRESEO靠我提供了多种客户端connector实现,这些实现都基于现存的开源项目。在connector一节中,列举出了所有可用的客户端、服务端connector,并解释了如何使用和配置它们。

下面,我们将获取一个现SEO靠我存资源的表示法(representation )并将其输出在JVM控制台:

// Outputting the content of a Web page

Client client = new ClieSEO靠我nt(Protocol.HTTP);

client.get("http://www.restlet.org").getEntity().write(System.out);

请注意上面的示例使用了最简单的SEO靠我方式:通过通用的客户端类(generic Client class)调用。更加灵活的方式是创建一个新的Request对象,然后请求客户端去处理它。下面的示例展示了如何在调用时设置首选项(例如 refeSEO靠我rrer URI)。当然,也可以是接收回应时的首选语言或者媒体类型:

// Prepare the request

Request request = new Request(Method.GET, "hSEO靠我ttp://www.restlet.org");

request.setReferrerRef("http://www.mysite.org");

// Handle it using an HTTP cSEO靠我lient connector

Client client = new Client(Protocol.HTTP);

Response response = client.handle(request);SEO靠我

// Write the response entity on the console

Representation output = response.getEntity();

output.writeSEO靠我(System.out);

3. 侦听浏览器

现在,我们将了解一下Restlet框架是如何侦听客户端请求并作出回应的。这里,我们选用了NRE HTTP服务端connector(例如基于Jetty的HTTPSEO靠我服务端connector),返回简单的字符串表达式“Hello World!”。请注意在更加实际的应用中,我们可以创建一个独立的类,此类继承自Restlet类,而不依靠这里的匿名内部类。

RestletSEO靠我类与Servlet非常相似,并且在RESTful应用中处理调用时提供了有限的帮助。我们后面将看到一个提供了一些特定子类的框架,它能够更抽象、简单地进行处理。下面让我们先看一个简单的示例:

// CreaSEO靠我ting a minimal Restlet returning "Hello World"

Restlet restlet = new Restlet() {

    @Override

public void SEO靠我handle(Request request, Response response) {

response.setEntity("Hello World!", MediaType.TEXT_PLAIN)SEO靠我;

    }

};

// Create the HTTP server and listen on port 8182

new Server(Protocol.HTTP, 8182, restlet).start(SEO靠我);

如果你运行并启动服务端,那么你可以打开浏览器输入http://localhost:8182。实际上,输入任何的URI都可以工作,你也可以尝试一下http://localhost:8182/testSEO靠我/tutorial。值得注意的是,如果你从另一台服务器上测试服务端,那么就需要将localhost替换为服务器的IP地址或者它的域名。

4. REST架构概述

让我们先从REST的视角审视一下典型的webSEO靠我架构。在下面的图表中,端口代表了connector,而后者负责component之间的通讯(组件在图中被表示为大盒子)。链接代表了用于实际通讯的特定协议(HTTP,SMTP等)。

请注意,同一个compSEO靠我onent能够具有任何数量的客户端/服务端connector。例如,Web服务器B就具有一个用于回应用户代理组件(User Agent component)的服务端connector,和多个发送请求到SEO靠我其它服务端的客户端connector。

5. Component、virtual hosts和applications

另外,为了支持前面所表述的标准REST软件架构元素,Restlet框架也提供了一套类SEO靠我:它们极大地简化了在单一JVM中部署多个应用的工作。其目的在于提供一种RESTful、可移植的、比现存的Servlet API更加灵活的框架。在下面的图表中,我们将看到三种Restlet,它们用于管理SEO靠我上述复杂情况:Components能够管理多个Virtual Hosts和Applications。Virtual Hosts支持灵活的配置,例如同一个IP地址能够分享多个域名、使用同一个域名实现跨越SEO靠我多个IP地址的负载均衡。最后,我们使用应用去管理一套相关的 Restlet、Resource、Representations。另外,应用确保了在不同Restlet实现、不同Virtual Hosts之SEO靠我上的可移植性和可配置性。这三种Restlet的协助为我们提供了众多的功能:譬如访问日志、请求自动解码、配置状态页设置等。

为了展示这些类,让我们尝试一个简单的示例。首先,我们创建一个component,SEO靠我然后在其上添加一个HTTP服务端connector,并侦听 8182端口。接着创建一个简单的、具有追踪功能的Restlet,将它放置到组件默认的Virtual Hosts上。这个默认的主机将捕捉那些没SEO靠我有路由到指定Virtual Hosts的请求(详见Component.hosts属性)。在后面的一个示例中,我们还将介绍应用类的使用方法。请注意,目前你并不能在控制台输出中看到任何的访问日志。

// CSEO靠我reate a new Restlet component and add a HTTP server connector to it

Component component = new ComponeSEO靠我nt();

component.getServers().add(Protocol.HTTP, 8182);

// Create a new tracing Restlet

Restlet restlet SEO靠我= new Restlet() {

    @Override

    public void handle(Request request, Response response) {

// Print the requeSEO靠我sted URI path

        String message = "Resource URI  : " + request.getResourceRef()

+ + "Root URISEO靠我      : " + request.getRootRef()

                + + "Routed part   : "

+ request.getResourceRef().getBaseSEO靠我Ref() +

                + "Remaining part: "

                + request.getResourceRef().getRemainingPart();

response.setEntity(message,SEO靠我 MediaType.TEXT_PLAIN);

    }

};

// Then attach it to the local host

component.getDefaultHost().attach("/traSEO靠我ce", restlet);

// Now, lets start the component!

// Note that the HTTP server connector is also automaSEO靠我tically started.

component.start();

让我们通过在浏览器中输入http://localhost:8182/trace/abc/def?param=123来进行测试,得到测SEO靠我试结果如下:

Resource URI  : http://localhost:8182/trace/abc/def?param=123

Root URI      : http://localhost:SEO靠我8182/trace

Routed part   : http://localhost:8182/trace

Remaining part: /abc/def?param=123

6. 为静态文件提供服务

SEO靠我遇到过提供静态页面(类似Javadocs)服务的web应用?如果正在使用,那么可以直接编写一个Directory类,而无需为它建立Apache服务。请见下面如何使用:

// Create a compoSEO靠我nent

Component component = new Component();

component.getServers().add(Protocol.HTTP, 8182);

component.SEO靠我getClients().add(Protocol.FILE);

// Create an application

Application application = new Application(coSEO靠我mponent.getContext()) {

    @Override

    public Restlet createRoot() {

return new Directory(getContext(), ROOTSEO靠我_URI);

    }

};

// Attach the application to the component and start it

component.getDefaultHost().attach(""SEO靠我, application);

component.start();

正如你所注意到的,我们通过传递应用的父组件上下文(context)的方式来实例化应用,而不是在第5章中提到的代码那样简单。而其主要原因SEO靠我是应用在分配客户端请求时,请求的分配工作需要客户端connector来完成,而后者被component所控制,并在所有被包含其中的应用之间贡献。

为了运行此示例,你需要为ROOT_URI提供一个有效值,SEO靠我该值依赖于你的Restlet安装路径。默认情况下,它被设置为"file:///D: /Restlet/www/docs/api/"。请注意,这里不需要任何附加的配置。如果你希望自定义在文件扩展名和元数SEO靠我据(metadata,包括媒体类型、语言、编码等)之间的映射,或是提供一个与众不同的索引名,你可以使用应用的“metadataService”属性。

7. 访问日志

有目的地记录web应用的活动是一种常见SEO靠我的需求。Restlet组件能够在默认的情况下生成类似Apache风格的日志、甚至自定义日志。通过使用 JDK内置的日志功能,logger能够配置为像任何标准JDK日志那样过滤信息、对它们进行重新格式化SEO靠我或者发送它们到指定位置。并且支持日志的循环(rotation);细节请查看java.util.logging包。

值得注意的是,你能够通过修改component的"logService"属性来为javaSEO靠我.util.logging框架自定义logger名。如果希望完全掌控日志的配置,你需要通过设置系统属性来声明一个配置文件:System.setProperty("java.util.logging.cSEO靠我onfig.file", "/your/path/logging.config");

关于配置文件格式的细节,请查看JDK的LogManager类。

8. 显示错误页

另外一个常见的需求是:在调用处理过程中SEO靠我某些期望结果没有出现时,能够自定义返回的状态页面。也许它是某个资源没有找到或者一个可接受的表示是无效的。在这种情况下,或者遇到任何无法处理的异常时,Application或者Component将自动提SEO靠我供一个默认的状态页面。此服务与 org.restlet.util.StatusService类相关联,并可以作为被称为“statusService”的Application或者 Component的属SEO靠我性而被访问。

为了自定义默认的信息,你只需要简单地创建StatusService类的子类,并覆盖其getRepresentation(Status, Request, Response)方法。然后设置这SEO靠我个类的实例为指定的“statusService”属性即可。

9. 对敏感资源的访问保护

当你需要保护对某些Restlet的访问时,可以使用下面的方法:一种通用的方法是依靠cookie来识别客户端(或者客户SEO靠我端session),并根据你的应用状态检查给定的用户ID或者session ID,从而判断次访问是否被允许。Restlet通过访问Request或者Response中的Cookie和CookieSetSEO靠我ting对象支持cookie。

另一种方法是基于标准HTTP认证机制。Neolios Restlet引擎目前允许基于简单HTTP方案的证书发送、接收和基于Amazon Web服务方案的证书发送。

当接收到SEO靠我调用时,开发者能够通过Request.challengeResponse.identifier/secret类中的Guard filter(保护过滤器)使用已经解析好的证书。过滤器是一种特殊的RestSEO靠我let,它能够在调用相应Restlet之前进行预处理,或者在相应 Restlet调用返回后进行后期处理。如果你熟知Servlet API,这里的过滤器概念和Servlet API中的Filter接口非SEO靠我常接近。看一下我们如何修改从前的代码来对目录访问进行访问保护:

// Create a Guard

Guard guard = new Guard(getContext(),

ChallengeSchemeSEO靠我.HTTP_BASIC, "Tutorial");

guard.getSecrets().put("scott", "tiger".toCharArray());

// Create a DirectorSEO靠我y able to return a deep hierarchy of files

Directory directory = new Directory(getContext(), ROOT_URISEO靠我);

guard.setNext(directory);

return guard;

请注意:认证和授权的最终结果是完全可定制的,这只需要通过authenticate()和authorize()方法便可完成SEO靠我。任何自定义的机制都能够被用来检查给定的证书是否有效、通过认证的用户是否被授权继续访问相应Restlet。下面是我们简单地硬编码了用户、密码对。为了测试,我们使用了客户端Restlet API:

// SEO靠我Prepare the request

Request request = new Request(Method.GET, "http://localhost:8182/");

// Add the clSEO靠我ient authentication to the call

ChallengeScheme scheme = ChallengeScheme.HTTP_BASIC;

ChallengeResponseSEO靠我 authentication = new ChallengeResponse(scheme,

        "scott", "tiger");

request.setChallengeResponse(authenSEO靠我tication);

// Ask to the HTTP client connector to handle the call

Client client = new Client(Protocol.SEO靠我HTTP);

Response response = client.handle(request);

if (response.getStatus().isSuccess()) {

// Output thSEO靠我e response entity on the JVM console

    response.getEntity().write(System.out);

} else if (response.getStSEO靠我atus()

        .equals(Status.CLIENT_ERROR_UNAUTHORIZED)) {

    // Unauthorized access

    System.out

.println("Access aSEO靠我uthorized by the server, " +

                    "check your credentials");

} else {

    // Unexpected status

System.out.printlnSEO靠我("An unexpected status was returned: "

            + response.getStatus());

}

你可以修改这里的user ID或者password,来检查服务端返回的reSEO靠我sponse。请别忘记了在启动客户端之前,先执行Restlet服务端程序。请注意,如果你从另一台机器上测试服务端,那么在浏览器中输入URI时需要将"localhost"替换为服务器的IP地址或者域名。SEO靠我由于使用了默认接收任何类型URI的 VirtualHost,因此服务端无需任何修改。

10. URI重写和重定向

Restlet框架的另一个优点是对cool URI的内建支持。Jacob Nielsen在SEO靠我他的AlertBox中给出了对URI设计的重要性的绝佳描述。

首先介绍的工具是Redirector,它能够将cool URI重写为另一个URI,并接着进行相应的自动重定向。这里支持一些重定向类型:通过客SEO靠我户端/浏览器的外部重定向、类似代理行为的connector重定向。在下面的例子中,我们将基于Google为名为"mysite.org"的站点定义一个检索服务。与URI相关的"/search"就是检索服SEO靠我务,它通过"kwd"参数接收一些检索关键字:

// Create an application

Application application = new Application(component.geSEO靠我tContext()) {

    @Override

    public Restlet createRoot() {

        // Create a Redirector to Google search service

StSEO靠我ring target =

           "http://www.google.com/search?q=site:mysite.org+{keywords}";

return new Redirector(getCoSEO靠我ntext(), target,

                Redirector.MODE_CLIENT_TEMPORARY);

    }

};

// Attach the application to the components defSEO靠我ault host

Route route = component.getDefaultHost().attach("/search", application);

// While routing reSEO靠我quests to the application, extract a query parameter

// For instance :

// http://localhost:8182/searchSEO靠我?kwd=myKeyword1+myKeyword2

// will be routed to

// http://www.google.com/search?q=site:mysite.org+myKeSEO靠我yword1%20myKeyword2

route.extractQuery("keywords", "kwd", true);

请注意,Redirector只需要三个参数。第一个参数是父级上下文,第二个SEO靠我参数定义了如何基于URI模板重写URI。这里的URI模板将被Template类处理。第三个参数定义了重定向类型:出于简化的目的,我们选择了客户端重定向。

同时,当调用被传递给application时,我SEO靠我们使用了Route类从request中提取查询参数“kwd”。如果发现参数,参数将被复制到request的“keywords”属性中,以便Redirector在格式化目标URI时使用。

11. 路由器和SEO靠我分层URI

作为Redirector的补充,我们还具有另一个管理cool URI的工具:Router(路由器)。它们是一种特殊的Restlet,能够使其它Restlet(例如Finder和Filter)SEO靠我依附于它们,并基于URI模板进行自动委派调用(delegate call)。通常,你可以将Router设置为Application的根。

这里,我们将解释一下如何处理下面的URI模板:

1. /docs/SEO靠我 用于显示静态文件

   2. /users/{user} 用于显示用户帐号

   3. /users/{user}/orders 用于显示特定用户的所有订单

4. /users/{user}/orders/{ordeSEO靠我r} 用于显示特定的订单

实际上,这些URI包含了可变的部分(在大括号中)并且没有文件扩展名,这在传统的web容器中很难处理。而现在,你只需要做的只是使用URI模板将目标Restlet附着到RouterSEO靠我上。在Restlet框架运行时,与request的URI最为匹配的Route将接收调用,并调用它所附着的 Restlet。同时,request的属性表也将自动更新为URI模板变量。

请看下面的具体实现代SEO靠我码。在真实的应用中,你可能希望创建单独的子类来代替我们这里使用的匿名类:

// Create a component

Component component = new Component();

compoSEO靠我nent.getServers().add(Protocol.HTTP, 8182);

component.getClients().add(Protocol.FILE);

// Create an apSEO靠我plication

Application application = new Application(component.getContext()) {

    @Override

public Restlet SEO靠我createRoot() {

        // Create a root router

        Router router = new Router(getContext());

// Attach a guard to sSEO靠我ecure access to the directory

        Guard guard = new Guard(getContext(),

ChallengeScheme.HTTP_BASIC, "RestlSEO靠我et tutorial");

        guard.getSecrets().put("scott", "tiger".toCharArray());

router.attach("/docs/", guard);SEO靠我

        // Create a directory able to expose a hierarchy of files

Directory directory = new Directory(getContSEO靠我ext(), ROOT_URI);

        guard.setNext(directory);

        // Create the account handler

Restlet account = new RestletSEO靠我() {

            @Override

            public void handle(Request request, Response response) {

// Print the requested URI pathSEO靠我

                String message = "Account of user \""

                        + request.getAttributes().get("user") + "\"";

response.setEntitySEO靠我(message, MediaType.TEXT_PLAIN);

            }

        };

        // Create the orders handler

Restlet orders = new Restlet(getConteSEO靠我xt()) {

            @Override

            public void handle(Request request, Response response) {

// Print the user name of thSEO靠我e requested orders

                String message = "Orders of user \""

                        + request.getAttributes().get("user") + "\"";

rSEO靠我esponse.setEntity(message, MediaType.TEXT_PLAIN);

            }

        };

        // Create the order handler

Restlet order = new RSEO靠我estlet(getContext()) {

            @Override

            public void handle(Request request, Response response) {

// Print the SEO靠我user name of the requested orders

                String message = "Order \""

                        + request.getAttributes().get("order")

+ SEO靠我"\" for user \""

                        + request.getAttributes().get("user") + "\"";

response.setEntity(message, MediaType.TSEO靠我EXT_PLAIN);

            }

        };

        // Attach the handlers to the root router

        router.attach("/users/{user}", account);

routeSEO靠我r.attach("/users/{user}/orders", orders);

        router.attach("/users/{user}/orders/{order}", order);

// RetSEO靠我urn the root router

        return router;

    }

};

// Attach the application to the component and start it

componentSEO靠我.getDefaultHost().attach(application);

component.start();

请注意,变量的值是直接从URI中提取的,因此这是没有精确解码的。为了实现这样的工作,请查SEO靠我看手册中的decode(String)方法。

12. 抵达目标资源

在前面的示例中,在从目标URI中提取那些有趣部分时,我们利用了Restlet框架非常灵活的路由特性对request进行路由。但是,我们没SEO靠我有注意request方法和客户端对于它所期望的response的偏好。于是,我们如何才能将Restlet处理器和后台系统、域对象联系在一起呢?

到目前为止,我们已经介绍了一些在Restlet中超越传统SSEO靠我ervlet API的特性。但我们并没有在"Restlet"这个框架名称中使用"REST"。如果你还没有做的话,我推荐你学习一些关于REST架构风格和将其应用于Web应用的最佳实践。这里提供了相关的FSEO靠我AQ记录,希望能给你一些启示,同时我们也运营着很有用的REST搜索引擎(基于Google)。如果你对传统MVC框架有一定了解,那么你可以阅读一下另一个FAQ记录,它提供了对MVC与Restlet关系的SEO靠我详细说明。

总结一下,request中含有标识目标资源的URI,而目标资源就是调用的主旨。这种资源信息被保存在Request.resourceRef属性中,并能够像我们之前所见那样服务于路由机制。因此在SEO靠我处理request时的首要目标就是发现目标资源。。。Resource类的实例或者其子类中的某个。为了帮助我们完成此项任务,我们可以使用专用的Finder,一个Restlet子类,它将Resource类SEO靠我引用作为参数并在request到来时自动实例化它。然后Finder将动态将调用分配给最新创建的实例,实际上就是根据request方法调用它的handle*()方法中的某一个(handleGet,hanSEO靠我dleDelete等)。当然,我们可以自定义这种行为,甚至使用Router的attach()方法,将URI模板和 Resource类作为其参数透明地创建Finder!现在,让我们看一下展示了示例中主框SEO靠我架类之间关系的全景图表:

回到代码中,我们在这里重构了Application.createRoot()方法。出于简化目的,我们没有提供具有静态文件的目录。你可以发现将Resource类直接指派给RoutSEO靠我er的方法。

// Create a router

Router router = new Router(getContext());

// Attach the resources to the routSEO靠我er

router.attach("/users/{user}", UserResource.class);

router.attach("/users/{user}/orders", OrdersResSEO靠我ource.class);

router.attach("/users/{user}/orders/{order}",

        OrderResource.class);

// Return the root roSEO靠我uter

return router;

我们最后将重审一下UserResource类。这个类继承自org.restlet.resource.Resource类,因此它覆盖了具有三个参数的构造方法。此方法初SEO靠我始化了"context"、"request"和"response"属性。接着,我们使用从"/users/{user} "URI模板中提取出的"user"属性,将它的值保存在一个方便使用的成员变量中。然SEO靠我后,我们便可以在整个application中查找与"user" 相关的域对象了。最终,我们声明了用于暴露给用户的表示变量(representation variants),在这个简单的例子中只是文字而SEO靠我已。它将用于在运行时透明地完成一些内容导航,以便为每个request选择适合的变量,所有这些工作都是透明的。

public class UserResource extends Resource {

StSEO靠我ring userName;

    Object user;

    public UserResource(Context context, Request request,

            Response response) {

sSEO靠我uper(context, request, response);

        this.userName = (String) request.getAttributes().get("user");

this.uSEO靠我ser = null; // Could be a lookup to a domain object.

// Here we add the representation variants exposSEO靠我ed

        getVariants().add(new Variant(MediaType.TEXT_PLAIN));

    }

    @Override

public Representation getRepresentaSEO靠我tion(Variant variant) {

        Representation result = null;

if (variant.getMediaType().equals(MediaType.TEXTSEO靠我_PLAIN)) {

            result = new StringRepresentation("Account of user \""

                    + this.userName + "\"");

        }

return resuSEO靠我lt;

    }

}

你可以查看本指南中提供的代码包并对应用进行测试,并能够以仅接受Get请求的方式获得在第十一章中的相同行为。如果你希望使用PUT方法,那么就需要在UserResource中创建一个"allowSEO靠我Put()"方法并简单地返回"true",并且添加一个"put (Representation)"方法来处理调用。关于详细内容请查阅Restlet的Javadocs。

结论

我们已经涵盖了Restlet框SEO靠我架的许多方面。在你打算行动之前,让我们先回顾一下展示了本指南的主要概念和它们之间关系的两个层次图表:

这里是核心表示类:

除了本指南,你最好的信息来源就是Restlet API的Javadocs、RestSEO靠我let扩展和NRE。还可以阅读一下connector一节,它列举出了客户端和服务端connector,并解释了如何使用、配置它们。集成一节列出了提供可插入特性的所有可用扩展:例如与servlet容器的SEO靠我集成、动态表示的生成等。你还可以在我们的讨论组中提出问题并帮助别人。
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2