来源:http://www.cnblogs.com/springyangwc/archive/2012/01/18/2325784.html

概述

REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表示方式。获得这些表徵致使这些应用程序转变了其状态。随着不断获取资源的表示方式,客户端应用不断地在转变着其状态,所谓表述性状态转移(Representational State Transfer)。

这一观点不是凭空臆造的,而是通过观察当前Web互联网的运作方式而抽象出来的。Roy Fielding 认为,

“设计良好的网络应用表现为一系列的网页,这些网页可以看作的虚拟的状态机,用户选择这些链接导致下一网页传输到用户端展现给使用的人,而这正代表了状态的转变。”

REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML以及HTML这些现有的广泛流行的协议和标准。

  • 资源是由URI来指定。
  • 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
  • 通过操作资源的表现形式来操作资源。
  • 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。
REST的要求
  • 客户端和服务器结构
  • 连接协议具有无状态性
  • 能够利用Cache机制增进性能
  • 层次化的系统
  • 隨需代碼 - Javascript (可選)

RESTful Web 服务

RESTful Web 服务(也称为 RESTful Web API)是一个使用HTTP并遵循REST原则的Web服务。它从以下三个方面资源进行定义:URI,比如:http://example.com/resources/。

§ Web服务接受与返回的互联网媒体类型,比如:JSON,XML ,YAML 等。

§ Web服务在该资源上所支持的一系列请求方法(比如:POST,GET,PUT或DELETE)。

该表列出了在实现RESTful Web 服务时HTTP请求方法的典型用途。

HTTP 请求方法在RESTful Web 服务中的典型应用

资源

GET

PUT

POST

DELETE

一组资源的URI,比如http://example.com/resources/

列出 URI,以及该资源组中每个资源的详细信息(后者可选)。

使用给定的一组资源替换当前整组资源。

在本组资源中创建/追加一个新的资源。 该操作往往返回新资源的URL。

删除 整组资源。

单个资源的URI,比如http://example.com/resources/142

获取 指定的资源的详细信息,格式可以自选一个合适的网络媒体类型(比如:XML、JSON等)

替换/创建 指定的资源。并将其追加到相应的资源组中。

把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。

删除 指定的元素。

PUT 和 DELETE 方法是幂等方法。GET方法是安全方法 (不会对服务器端有修改,因此也是幂等的)。

不像基于SOAP的Web服务,RESTful Web服务并没有的“正式”标准。 这是因为REST是一种架构,而SOAP只是一个协议。虽然REST不是一个标准,但在实现RESTful Web服务时可以使用其他各种标准(比如HTTP,URL,XML,PNG等)。

REST的优点

  • 可以利用缓存Cache来提高响应速度
  • 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
  • 浏览器即可作为客户端,简化软件需求
  • 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
  • 不需要额外的资源发现机制
  • 在软件技术演进中的长期的兼容性更好

Rest 开发

首先先定义接口IRestHandler:

 /// <summary>
/// The IRestHandler is an interface which provides Delete,Get,Post and Put methods.
/// </summary>
public interface IRestHandler : ICloneable
{
/// <summary>
/// Delete method for RestHandler
/// </summary>
/// <param name="processor">The rest processor.</param>
/// <param name="authenticated">if set to <c>true</c> [authenticated].</param>
/// <returns>The http response</returns>
RestHandlerResponse Delete(IRestProcessor processor, bool authenticated); /// <summary>
/// Get method for RestHandler
/// </summary>
/// <param name="processor">The rest processor.</param>
/// <param name="authenticated">if set to <c>true</c> [authenticated].</param>
/// <returns>The http response</returns>
RestHandlerResponse Get(IRestProcessor processor, bool authenticated); /// <summary>
/// Post method for RestHandler
/// </summary>
/// <param name="processor">The rest processor.</param>
/// <param name="authenticated">if set to <c>true</c> [authenticated].</param>
/// <returns>The http response</returns>
RestHandlerResponse Post(IRestProcessor processor, bool authenticated); /// <summary>
/// Put method for RestHandler
/// </summary>
/// <param name="processor">The rest processor.</param>
/// <param name="authenticated">if set to <c>true</c> [authenticated].</param>
/// <returns>The http response</returns>
RestHandlerResponse Put(IRestProcessor processor, bool authenticated);
}

我们要定义一个HttpListener,先定义一个接口IRestListener:

 /// <summary>
/// Listen an ip point and accept connection.
/// </summary>
public interface IRestListener : IDisposable
{
/// <summary>
/// Gets or sets the max allowed connections to this listener.
/// </summary>
int MaxConnections { get; set; } /// <summary>
/// Gets or sets desktop rest manager.
/// </summary>
DesktopRestManager DesktopRestManager { get; set; } /// <summary>
/// Gets a value that indicate if it is listening.
/// </summary>
bool IsRunning { get; } /// <summary>
/// Gets or sets the server address information.
/// </summary>
IPEndPoint ServerAddress { get; set; } string Protocol { get; set; } /// <summary>
/// Start a listener.
/// </summary>
/// <returns>The ip end point to listen.</returns>
bool Start(TcpListener listener, IPEndPoint address); /// <summary>
/// Stop the listener.
/// </summary>
/// <returns>True if successfully, else false.</returns>
bool Stop();
}

接下来实现

public class HttpListener : IRestListener
{
public HttpListener(DesktopRestManager drm)
{
this.desktopRestManager = drm;
this.isRunning = false;
MaxConnections = 50;
this.serverAddress = new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 10000);
this.Protocol = "Http";
} #region IRestServer Members //public event ServerStatusChangedHandler ServerStatusChanged; public DesktopRestManager DesktopRestManager
{
get { return this.desktopRestManager; }
set { this.desktopRestManager = value; }
} public bool IsRunning
{
get { return this.isRunning; }
} public IPEndPoint ServerAddress
{
get { return this.serverAddress; }
set { this.serverAddress = value; }
} public int MaxConnections
{
get;
set;
} public string Protocol
{
get;
set;
} public bool Start(TcpListener tcpListener, IPEndPoint address)
{
this.ServerAddress = address;
this.listener = tcpListener;
this.isRunning = true;
Thread th = new Thread(new ThreadStart(this.Listening));
th.Start();
return true;
} public bool Stop()
{
bool success = true; ;
if (this.isRunning == true)
{
try
{
this.isRunning = false;
if (listener != null)
{
listener.Stop();
}
}
catch (SocketException socketEx)
{
_traceLog.InfoFormat("Stop http rest server: {0}", socketEx.Message);
success = false;
} }
return success;
} #endregion #region IDisposable Members public void Dispose()
{
this.Stop();
} #endregion #region Private Methods
private void Listening()
{
while (this.isRunning)
{
TcpClient tcpClient = null;
try
{
tcpClient = listener.AcceptTcpClient();
HttpConnection connection = new HttpConnection(tcpClient);
RestProcessor rh = new RestProcessor(this.desktopRestManager);
Thread processThread = new Thread(new ParameterizedThreadStart(req => connection.SendResponse(rh.HandleRequest(req as RestHandlerRequest))));
processThread.Name = "RestManager_Http_ProcessRequest";
processThread.Start(connection.GetRequest());
}
catch (SocketException socketEx)
{
if (this.isRunning)
{
_traceLog.InfoFormat("Socket exception: {0}", socketEx.Message);
}
else
{
_traceLog.Info("The use stop the http listener.");
}
if (tcpClient != null && tcpClient.Connected)
{
tcpClient.Close();
}
}
catch (System.ArgumentNullException ex)
{
_traceLog.ErrorFormat("Error occured: {0}", ex.Message);
}
catch (System.OutOfMemoryException ex)
{
_traceLog.ErrorFormat("Error occured: {0}", ex.Message);
}
catch (System.Threading.ThreadStateException ex)
{
_traceLog.ErrorFormat("Error occured: {0}", ex.Message);
}
catch (System.InvalidOperationException ex)
{
_traceLog.ErrorFormat("Error occured: {0}", ex.Message);
}
catch (ApplicationException ex)
{
_traceLog.ErrorFormat("Error occured: {0}", ex.Message);
}
}
this.Stop();
} #endregion #region Private Members
private DesktopRestManager desktopRestManager;
private bool isRunning;
private IPEndPoint serverAddress;
private TcpListener listener;
private static LogManager _traceLog = new LogManager("RestManager-HttpListener");
#endregion
}

接下来处理HandleRequest:

/// <summary>
/// Handles an http request for an Api call.
/// </summary>
public RestHandlerResponse HandleRequest(RestHandlerRequest rhr)
{
RestHandlerResponse res;
// 50 Requests in maximum
if (!this.restProcessorSemaphore.WaitOne(0))
{ res = new RestHandlerResponse(503);
} else
{
try
{
// There is no need decode the url here, since the address will be decoded when it is parsed.
//rhr.Address = System.Web.HttpUtility.UrlDecode(rhr.Address); res = this.process(rhr); }
catch (RestManagerException ex)
{
traceLog.ErrorFormat("Error happened while processing request\n{1}.\nException info:\n{0} ",ex.Message);
res = new RestHandlerResponse(500);
}
try
{
this.restProcessorSemaphore.Release();
}
catch (System.Threading.SemaphoreFullException)
{
traceLog.ErrorFormat("Error happened while processing Semaphore.Release");
}
catch (System.IO.IOException)
{
traceLog.ErrorFormat("Error happened while processing Semaphore.Release");
}
catch (System.UnauthorizedAccessException)
{
traceLog.ErrorFormat("Error happened while processing Semaphore.Release");
}
} return res;
}

接下来我们写发送请求代码:

private JObject MakeRequest(string url)
{
var subsequentRequest = WebRequest.Create(url) as HttpWebRequest;
subsequentRequest.Timeout = 30000;
subsequentRequest.Headers.Add("Authorization", "OAuth " + TestToken);
subsequentRequest.Headers.Add("App-User", TestUserName); WebResponse subsequentResponse; try
{
subsequentResponse = subsequentRequest.GetResponse();
Stream stream = subsequentResponse.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string output = sr.ReadToEnd();
JObject jsonStr = JObject.Parse(output);
return jsonStr; }
catch (WebException ex)
{
if (ex.Response != null)
{
HttpWebResponse errorResponse = (HttpWebResponse)ex.Response;
StreamReader reader = new StreamReader(errorResponse.GetResponseStream());
string output = reader.ReadToEnd();
JObject jsonStr = JObject.Parse(output);
return jsonStr;
}
else
{
return null;
}
}
}

涉及项目的原因,代码只能提供这么多了,仅供参考

Json的返回结果格式如下:

[{"CreatedDate":"//Date(1299687080328+0800)//","Detail":"Do Something 1","Title":"Task1"},{"CreatedDate":"//Date(1299687080328+0800)//","Detail":"Do Something 5","Title":"Task5"}]

Rest Api(转载)的更多相关文章

  1. Serial Port Programming using Win32 API(转载)

    In this tutorial we will learn How to communicate with an external device like a microcontroller boa ...

  2. Android 开发 View的API 转载

    转载地址:https://blog.csdn.net/lemonrabbit1987/article/details/47704679 View类代表用户界面组件的基本构建块.一个View占据屏幕上的 ...

  3. WebApi系列~基于RESTful标准的Web Api 转载 https://www.cnblogs.com/lori/p/3555737.html

    微软的web api是在vs2012上的mvc4项目绑定发行的,它提出的web api是完全基于RESTful标准的,完全不同于之前的(同是SOAP协议的)wcf和webService,它是简单,代码 ...

  4. 基础项目构建,引入web模块,完成一个简单的RESTful API 转载来自翟永超

    简介 在您第一次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复粘贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot ...

  5. smack api 转载未测试

    ===============================================================主动发送信息给某个用户-------------------------- ...

  6. ASP.NET Web API之消息[拦截]处理

    标题相当难取,内容也许和您想的不一样,而且网上已经有很多这方面的资料了,我不过是在实践过程中作下记录.废话少说,直接开始. Exception 当服务端抛出未处理异常时,most exceptions ...

  7. C#—ASP.NET:集成极光推送(Push API v3)

    C#—ASP.NET:集成极光推送(Push API v3) 原文地址: https://blog.csdn.net/CXLLLK/article/details/86489994   1.极光推送官 ...

  8. Self-Host c#学习笔记之Application.DoEvents应用 不用IIS也能執行ASP.NET Web API

    Self-Host   寄宿Web API 不一定需要IIS 的支持,我们可以采用Self Host 的方式使用任意类型的应用程序(控制台.Windows Forms 应用.WPF 应用甚至是Wind ...

  9. 人工智能常用 API

    人工智能常用 API 转载  2016年07月13日 19:17:27 2047 机器学习与预测 1.AlchemyAPI  在把数据由非结构化向结构化的转化中运用得较多.用于社交媒体监控.商业智能. ...

  10. 使用Javascript监控前端相关数据

    项目开发完成外发后,没有一个监控系统,我们很难了解到发布出去的代码在用户机器上执行是否正确,所以需要建立前端代码性能相关的监控系统. 所以我们需要做以下的一些模块: 一.收集脚本执行错误 functi ...

随机推荐

  1. windows命令行中java和javac、javap使用详解(java编译命令)

    如题,首先我们在桌面,开始->运行->键入cmd 回车,进入windows命令行.进入如图所示的画面: 可知,当前默认目录为C盘Users文件夹下的Administrator文件夹.一般而 ...

  2. linux 下高精度时间

    今天在公司代码中看到了使用select函数的超时功能作定时器的用法,便整理了如下几个Linux下的微秒级别的定时器.在我的Ubutu10.10 双核环境中,编译通过. /* * @FileName:  ...

  3. hdu 5438(类似拓扑排序)

    Ponds Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Sub ...

  4. LeetCode OJ--Triangle **

    https://oj.leetcode.com/problems/triangle/ 一个三角形,类似于杨辉三角的形状,求从上到下最小的路径和,但走每一步都得是相邻的. 动态规划,从下到上一层层来. ...

  5. spring+jpa+HiKariCP+P6spy SSH HiKariCP P6spy

    =============p6spy准备https://www.cnblogs.com/qgc88===================== 1.简单介绍p6spy,p6spy是一个开源项目,通常使用 ...

  6. JavaScript 中那些关于坐标和距离的属性与方法

    一 前言 在前端开发中总会遇到各种各样需要使用或计算坐标和距离的情况,但是这些属性和方法众多,全部熟练地记下来并非是一件易事,大多只能现查,耗费不少时间精力,于是便有了整理记录的想法,即加深了印象,又 ...

  7. Feign详细使用-Spring Cloud学习第四天(非原创)

    文章大纲 一.Feign是什么二.Feign的基本实现三.Feign的继承特性四.Feign配置详解五.项目源码与参考资料下载六.参考文章   一.Feign是什么 前面几篇文章我们详细的介绍了Rib ...

  8. BT服务器的搭建(tracker-P2P服务器架设)(转)

    文章虽然有点老,但原理差不多. 继上一篇文章(http://www.cnblogs.com/EasonJim/p/6601146.html)介绍了BT的原理,现在来看下BT服务端搭建的原理. 一.BT ...

  9. 阿里云云服务器ubuntu配置nginx+uwsgi+django记录文档

    1 安装ssh 1  sudo apt-get update 2  sudo apt-get install openssh-server 3  sudo ps -e |grep ssh  有sshd ...

  10. python为不同的对象如何分配内存的小知识

    id方法的返回值就是对象的内存地址. python中会为每个出现的对象分配内存,哪怕他们的值完全相等(注意是相等不是相同).如执行a=2.0,b=2.0这两个语句时会先后为2.0这个Float类型对象 ...