![]() |
![]() |
Restful的概述
REST是
Representational State Transfer (表述性状态转移)的缩写。
REST 式 Web
服务 (RESTful Web services) 的工作方式主要是通过超文本传输协议(HTTP)发送简单的消息来实现 SOA。REST并不是一个协议或技术;它是一种体系结构风格。
REST 是
SOAP 的轻量型替代品,它是面向资源的,而不是面向操作的。它常常被归结为远程过程使用 HTTP 调用 GET、POST、PUT 和 DELETE 语句。我认为,这只是第二个重要的步骤。 (第一个(也是最重要的)步骤是把所有资源建模为 URL 形式。)
REST比较简单朴素,在安全性,可靠消息传输,或标准化的业务过程自动化上还没有定义。(REST很适合面向数据的应用,但对于面向服务/面向方法的应用,比如需要事务、严密的安全性等等这些更高级的操作的应用来说,采用基于WS-*的方案显得更有道理。)
从基本原理层次上说,REST 样式和 SOAP 样式 Web
Service的区别取决于应用程序是面向资源的还是面向活动的。例如,在传统的WebService中,一个获得天气预报的webservice会暴露一个WebMethod。而RESTful WebService暴露的不是方法,而是对象(资源),通过Http
GET, Http PUT, Http POST 或者Http DELETE来对请求的资源进行操作。在 REST 的定义中,一个 Web Service总是使用固定的 URI 向外部世界呈现(或者说暴露)一个资源。可以说这是一种全新的思维模式:使用唯一资源定位地址 URI,加上 HTTP 请求方法从而达到对一个发布于互联网资源的唯一描述和操作。
RESTful HTTP核心操作包括:
* GET- 该操作返回已标识资源的状态表示。您可以通过大量的上下文要素来确定状态,例如谁正在提交请求、操作的参数(传入的参数如 HTTP 头或者查询字符串参数)和服务提供方维护的当前会话状态。
* POST- 该操作执行对已标识资源的一些特定于应用程序形式的更新。该操作行为完全依赖于实现它的服务。由该操作返回的数据也完全依赖于应用程序。举例来说,像 GET 操作一样,它可以返回一个状态表示,它还可以选择根本不返回任何数据。
* PUT- 该操作在已标识位置(URI)创建新资源。操作输入必须包括一个资源的状态表示。它完全依赖服务来创建基于这个状态表示的资源。
* DELETE- 该操作销毁已标识位置(URI)的资源。
REST是无状态的,服务器无需知道当前操作的上下文,或者上一次操作的情况。这能够提高系统的可伸缩性,是因为它强制所有操作都是stateless的,这样就没有context的约束,如果要做分布式、做集群,就不需要考虑context的问题了。同时,它令系统可以有效地使用pool。REST对性能的另一个提升来自其对client和server任务的分配: server只负责提供resource以及操作resource的服务,而client要根据resource中的data和 representation自己做render。这就减少了服务器的开销。
在设计
REST 式 WebService时,可以采用以下四个步骤:
1. 决定资源及其描述性 URL。(通过url来设计系统的结构则整个系统就是由这些resource组成的,注意设计思维方式的不同)
2. 为每个
URL 上的通信选择一种数据格式。
3. 指定每个资源上的方法。
4. 指定返回的数据和状态码。
Solr是一个拥有象WebService一样接口的独立运行的搜索服务器。它基于restful风格,并且扩展了Lucene.你将能够通过HTTP协议以XML格式将文档放入搜索服务器(这个过程叫做索引),你能够通过HTTP协议的GET来查询搜索服务器并且得到XML格式的结果。Solr的特性包括:
* 高级的全文搜索功能
* 专为高通量的网络流量进行的优化
* 基于开放接口(XML和HTTP)的标准
* 综合的HTML管理界面
* 可伸缩性-能够有效地复制到另外一个Solr搜索服务器
* 使用XML配置达到灵活性和适配性
* 可扩展的插件体系
如何添加plugin类
1.
将solr源文件解压,并且使用开发工具(如:Eclipse),新建工程,将源文件以及相关的jar导入。
2.
在org.apache.solr.handler包下(一般在此包下进行扩展),新建java类。
3.
新建的类需要继承RequestHandlerBase类,并且实现其中的handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)方法。同时需要覆盖getVersion()、getDescription()、getSourceId()、getSource()、getDocs()等方法。
4.
handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)方法中,req表示传入的参数对象,rsp表示经过处理后得到的需要显示的对象,
5.
业务处理根据个人的需要进行编写。
6.
在solr中,常量一般在org.apache.solr.common.params包下的接口CommonParams中定义。在本项目中,需要在CommonParams中添加新的常量,如:
public static final
String URI = "uri";//URI的值表示访问的参数。
7.
以上工作实现后,对solr重新打包。然后加入到Web项目目录\WEB-INF\lib中。
8.
打开solr文件夹(对应resin文件夹下的solr文件夹),打开conf文件夹下的solrconfig.xml文件,在<config>……</config>标签中,添加如下内容:
<requestHandler name="/urlinfo"
class="solr.URItoWordsHandler">
</requestHandler>
其中name属性决定了访问的路径,class属性决定了处理类。
9.
打开IE浏览器,输入“http://localhost:8081/index/urlinfo?url=?wt=?”,其中“localhost:8081/index/”表示该WEB应用程序的访问地址,“urlinfo”对应第8条中的<requestHandler>标签中的name属性的值。url对应传入的查询网页地址(对应第6条中添加的常量的值(uri))。wt表示要输出的格式,值一般为:xml和json,表示输出的格式为xml格式或者json格式。
10. 以下通过一个例子具体说明:
a. 在合适的包下编写所需要的java类,本例中类名为URItoWordsHandler,该类继承RequestHandlerBase类。
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
/**
* Solr MoreLikeThis --
*
* Return similar documents either based on a single document or based on posted
* text.
*
* @since solr 1.3
*/
public class URItoWordsHandler extends RequestHandlerBase
{
public void handleRequestBody(SolrQueryRequest
req, SolrQueryResponse rsp)
throws Exception {
// RequestHandlerUtils.addExperimentalFormatWarning(rsp);
//
/**
* 获取传递的参数集合
*/
SolrParams params = req.getParams();
/**
* 从参数集合中得到想要的参数
*/
String
uri = params.get(CommonParams.URI);
/**
* 进行业务处理
*/
ArrayList<String> s = new ArrayList<String>();
s.add("大家新年好");
s.add("今日新闻:火车票大战");
s.add("生活");
Words
words = new Words(s, "娱乐");
String
type = words.getType();
NamedList<Object> word = new SimpleOrderedMap<Object>();
for (String o : words.getWord()) {
word.add("word", o);
}
/**
* 将业务处理结果添加到rsp,并且输出
*/
rsp.add("type", type);
rsp.add("words", word);
}
class Words {
private List<String> word;
private String type;
public Words(List<String> word, String type) {
super();
this.word = word;
this.type = type;
}
public List<String> getWord() {
return word;
}
public void setWord(List<String> word) {
this.word = word;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
//////////////// SolrInfoMBeans
methods //////////////////////
////////////////////以下覆写父类的方法 //////////////////////////
@Override
public String getVersion() {
return "$Revision: 561904 $";
}
@Override
public String getDescription() {
return "Solr MoreLikeThis";
}
@Override
public String getSourceId() {
return "$Id: MoreLikeThisHandler.java
561904 2007-08-01 18:43:02Z ryan $";
}
@Override
public String getSource() {
return "$URL:
http://svn.apache.org/repos/asf/lucene/solr/trunk/src/java/org/apache/solr/handler/MoreLikeThisHandler.java
$";
}
@Override
public URL[] getDocs() {
try {
return new URL[] { new URL(
"http://wiki.apache.org/solr/MoreLikeThis") };
}
catch (MalformedURLException ex) {
return null;
}
}
}
b. 在solrconfig.xml中<config>标签下添加相应的配置信息:
<requestHandler name="/urlinfo"
class="solr.URItoWordsHandler">
<!-- /urlinfo表示访问路径 class表示对应的处理类 -->
<!-- 以下为其他说明,可根据需要修改或删除,此信息将会在网页显示 -->
<lst name="其他说明">
<int name="名称">参数</int>
</lst>
</requestHandler>
c. 启动服务器,在浏览器里查看结果:
![]()
上图为IE地址栏。其中,urlinfo对应b项中提到的访问路径,url表示需要传递的参数,wt表示返回的结果格式。图1为wt=xml时的显示结果:

图 1
图2为wt=json时的显示结果:
![]()
![]()
图 2