什么是API,怎样使用网站福利电影免费提供网站的API

2014年6月 .NET技术大版内专家分月排行榜第二2014年1月 .NET技术大版内专家分月排行榜第二
2014年2月 .NET技术大版内专家分月排行榜第三2013年4月 .NET技术大版内专家分月排行榜第三
2014年6月 .NET技术大版内专家分月排行榜第二2014年1月 .NET技术大版内专家分月排行榜第二
2014年2月 .NET技术大版内专家分月排行榜第三2013年4月 .NET技术大版内专家分月排行榜第三
2016年1月 总版技术专家分月排行榜第二2015年11月 总版技术专家分月排行榜第二2015年10月 总版技术专家分月排行榜第二
优秀小版主
2017年2月 总版技术专家分月排行榜第三
2017年5月 .NET技术大版内专家分月排行榜第一2017年4月 .NET技术大版内专家分月排行榜第一2017年3月 .NET技术大版内专家分月排行榜第一2017年2月 .NET技术大版内专家分月排行榜第一2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2017年2月 总版技术专家分月排行榜第三
2017年5月 .NET技术大版内专家分月排行榜第一2017年4月 .NET技术大版内专家分月排行榜第一2017年3月 .NET技术大版内专家分月排行榜第一2017年2月 .NET技术大版内专家分月排行榜第一2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2017年2月 总版技术专家分月排行榜第三
2017年5月 .NET技术大版内专家分月排行榜第一2017年4月 .NET技术大版内专家分月排行榜第一2017年3月 .NET技术大版内专家分月排行榜第一2017年2月 .NET技术大版内专家分月排行榜第一2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2015年9月 总版技术专家分月排行榜第二
2015年8月 总版技术专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。Subversion&API&使用简介
使用Subversion库API开发应用看起来相当的直接,所有的公共头文件放在源文件的subversion/include目录,从源代码编译和安装Subversion本身,需要这些头文件拷贝到系统位置。这些头文件包括了所有用户和Subversion库可以访问的功能和类型。Subversion开发者社区仔细的确保所有的公共API有完好的文档—直接引用头文件的文档。
你首先应该注意Subversion的数据类型和方法是命名空间保护的,每一个公共Subversion对象名以svn_开头,然后紧跟一个这个对象定义(如wc、client和fs等等)所在的库的简短编码,然后是一个下划线(_)和后面的对象名称。半公开的方法(库使用,但是但库之外代码不可以使用并且只可以在库自己的目录看到)与这个命名模式不同,并不是库代码之后紧跟一个下划线,他们是用两个下划线(__)。给定源文件的私有方法没有特殊前缀,使用static声明。当然,一个编译器不会关心命名习惯,只是用来区分给定方法或数据类型的应用范围。
关于Subversion的API编程的另一个好的资源是hacking指南,可以在http://subversion.tigris.org/hacking.html找到,这个文档包含了有用的信息,同时满足Subversion本身的开发者和将Subversion作为第三方库的开发者。[]
Apache 可移植运行库
伴随Subversion自己的数据类型,你会看到许多apr开头的数据类型引用—来自Apache可移植运行库(APR)的对象。APR是Apache可移植运行库,源自为了服务器代码的多平台性,尝试将不同的操作系统特定字节与操作系统无关代码隔离。结果就提供了一个基础API的库,只有一些适度区别—或者是广泛的—来自各个操作系统。Apache
HTTP服务器很明显是APR库的第一个用户,Subversion开发者立刻发现了使用APR库的价值。意味着Subversion没有操作系统特定的代码,也意味着Subversion客户端可以在Server存在的平台编译和运行。当前这个列表包括,各种类型的Unix、Win32、OS/2和Mac
除了提供了跨平台一致的系统调用, []APR给Subversion对多种数据类型有快速的访问,如动态数组和哈希表。Subversion在代码中广泛使用这些类型,但是Subversion的API原型中最常见的APR类型是apr_pool_t—APR内存池,Subversion使用内部缓冲池用来进行内存分配(除非外部库在API传递参数时需要一个不同的内存管理模式),
[]而且一个人如果针对Subversion的API编码不需要做同样的事情,他们可以在需要时给API提供缓冲池,这意味着Subversion的API使用者也必须链接到APR,必须调用apr_initialize()来初始化APR子系统,而且在使用Subversion
API时必须创建和管理池,通常是使用svn_pool_create()、svn_pool_clear()和svn_pool_destroy()。
使用内存池编程
几乎每一个使用过C语言的开发者曾经感叹令人畏缩的内存管理,分配足够的内存,并且追踪内存的分配,在不需要时释放内存—这个任务会非常复杂。当然,如果没有正确地做到这一点会导致程序毁掉自己,或者更加严重一点,把电脑搞瘫。
另一方面高级语言使开发者完全摆脱了内存管理,[]Java和Python之类的语言使用垃圾收集原理,在需要的时候分配对象内存,在不使用时进行清理。
APR提供了一种叫做池基础的中等的内存管理方法,允许开发者以一种低分辨率的方式控制内存—每块(或池“pool”)的内存,而不是每个对象。不是使用malloc()和其他按照对象分配内存的方式,你要求APR从内存创建一段内存池,当你结束使用在池中创建的对象,你销毁池,可以有效地取消其中的对象消耗的内存。通过池,你不需要跟踪每个对象的内存释放,你的程序只需要跟踪这些对象,将对象分配到池中,而池的生命周期(池的创建和删除之间的时间)满足所有对象的需要。
URL 和路径需求
因为分布式版本控制操作是Subversion存在的重点,有意义来关注一下国际化(i18n)支持。毕竟,当“分布式”或许意味着“横跨办公室”,它也意味着“横跨全球”。为了更容易一点,Subversion的所有公共接口只接受路径参数,这些参数是传统的,使用UTF-8编码。这意味着,举个例子,任何新的使用libsvn_client接口客户端库,在把这些参数传递给Subversion库前,需要首先将路径从本地代码转化为UTF-8代码,然后将Subversion传递回来的路径转换为本地代码,很幸运,Subversion提供了一组任何程序可以使用的转化方法(见subversion/include/svn_utf.h)。
同样,Subversion的API需要所有的URL参数是正确的URI编码,所以,我们不会传递file:///home/username/My
File.txt作为My
File.txt的URL,而要传递file:///home/username/My%20File.txt。再次,Subversion提供了一些你可以使用的助手方法—svn_path_uri_encode()和svn_path_uri_decode(),分别用来URI的编码和解码。
使用 C 和 C++ 以外的语言
除C语言以外,如果你对使用其他语言结合Subversion库感兴趣—如Python脚本或是Java应用—Subversion通过简单包裹生成器(SWIG)提供了最初的支持。Subversion的SWIG绑定位于subversion/bindings/swig,并且慢慢的走向成熟进入可用状态。这个绑定允许你直接调用Subversion的API方法,使用包裹器会把脚本数据类型转化为Subversion需要的C语言库类型。
非常不幸,Subversion的语言绑定缺乏对核心Subversion模块的关注,但是,花了很多力气处理创建针对Python、Perl和Ruby的功能绑定,在一定程度上,在这些接口上的工作量可以在其他语言的SWIG(包括C#、Guile、Java、MzScheme、OCaml、PHP、Tcl等等)接口上得到重用。然而,为了完成复杂的API,一些SWIG接口仍然需要额外的编程工作,关于SWIG本身的更多信息可以看项目的网站http://www.swig.org/。
Subversion也有Java的语言绑定,JavaJL绑定(位于Subversion源目录树的subversion/bindings/java)不是基于SWIG的,而是javah和手写JNI的混合,JavaHL几乎覆盖Subversion客户端的API,目标是作为Java基础的Subversion客户端和集成IDE的实现。
Subversion的语言绑定缺乏Subversion核心模块的关注,但是通常可以作为一个产品信赖。大量脚本、应用、Subversion的GUI客户端和其他第三方工具现在已经成功地运用了Subversion语言绑定来完成Subversion的集成。
这里使用其它语言的方法来与Subversion交互没有任何意义:Subversion开发社区没有提供其他的绑定,你可以在Subversion项目链接页里(http://subversion.tigris.org/links.html)找到其他绑定的链接,但是有一些流行的绑定我觉得应该特别留意。首先是Python的流行绑定,Barry
Scott的PySVN(http://pysvn.tigris.org/)。PySVN鼓吹它们提供了更多Python样式的接口,而不像Subversion自己的Python绑定的C样式接口。对于希望寻求Subversion纯Java实现的人,可以看看SVNKit(http://svnkit.com/),也就是从头使用Java编写的Subversion。你必须要小心,SVNKit没有采用Subversion的核心库,其行为方式没有确保与Subversion匹配。
“使用版本库层”包含了一段C代码(C编写)描述了我们讨论的概念,它使用了版本库和文件系统接口(可以通过方法名svn_repos_和svn_fs_分辨)创建了一个添加目录的修订版本。你可以看到APR库的使用,为了内存分配而传递,这些代码也揭开了一些关于Subversion错误处理的晦涩事实—所有的Subversion错误必须需要明确的处理以防止内存泄露(在某些情况下,应用失败)。
例&8.1.&使用版本库层
#define INT_ERR(expr)
svn_error_t *__temperr = (expr);
if (__temperr)
svn_error_clear(__temperr);
} while (0)
static int
make_new_directory(const char *repos_path,
const char *new_directory,
apr_pool_t *pool)
svn_error_t *
svn_repos_t *
svn_fs_t *
svn_revnum_t youngest_
svn_fs_txn_t *
svn_fs_root_t *txn_
const char *conflict_
INT_ERR(svn_repos_open(&repos, repos_path, pool));
fs = svn_repos_fs(repos);
INT_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
INT_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
INT_ERR(svn_fs_txn_root(&txn_root, txn, pool));
INT_ERR(svn_fs_make_dir(txn_root, new_directory, pool));
err = svn_repos_fs_commit_txn(&conflict_str, repos,
&youngest_rev, txn, pool);
if (! err)
printf("Directory '%s' was successfully added as new revision "
"'%ld'.\n", new_directory, youngest_rev);
else if (err-&apr_err == SVN_ERR_FS_CONFLICT)
printf("A conflict occurred at path '%s' while attempting "
"to add directory '%s' to the repository at '%s'.\n",
conflict_str, new_directory, repos_path);
printf("An error occurred while attempting to add directory '%s' "
"to the repository at '%s'.\n",
new_directory, repos_path);
INT_ERR(err);
请注意在例&8.1
“使用版本库层”中,代码可以非常容易使用svn_fs_commit_txn()提交事务。但是文件系统的API对版本库库的钩子一无所知,如果你希望你的Subversion版本库在每次提交一个事务时自动执行一些非Subversion的任务(例如,给开发者邮件组发送一个描述事务修改的邮件),你需要使用libsvn_repos包裹的功能版本—这个功能会实际上首先运行一个如果存在的pre-commit钩子脚本,然后提交事务,最后会运行一个post-commit钩子脚本。钩子提供了一种特别的报告机制,不是真的属于核心文件系统库本身。(关于Subversion版本库钩子的更多信息,见。)
现在我们转换一下语言,例&8.2
“使用 Python 处理版本库层”使用Subversion
SWIG的Python绑定实现了从版本库取得最新的版本,并且打印了取出时访问的目录。
例&8.2.&使用 Python
处理版本库层
#!/usr/bin/python
"""Crawl a repository, printing versioned object path names."""
import sys
import os.path
import svn.fs, svn.core, svn.repos
def crawl_filesystem_dir(root, directory):
"""Recursively crawl DIRECTORY under ROOT in the filesystem, and return
a list of all the paths at or below DIRECTORY."""
# Print the name of this path.
print directory + "/"
# Get the directory entries for DIRECTORY.
entries = svn.fs.svn_fs_dir_entries(root, directory)
# Loop over the entries.
names = entries.keys()
for name in names:
# Calculate the entry's full path.
full_path = directory + '/' + name
# If the entry is a directory, recurse.
The recursion will return
# a list with the entry and all its children, which we will add to
# our running list of paths.
if svn.fs.svn_fs_is_dir(root, full_path):
crawl_filesystem_dir(root, full_path)
# Else it's a file, so print its path here.
print full_path
def crawl_youngest(repos_path):
"""Open the repository at REPOS_PATH, and recursively crawl its
youngest revision."""
# Open the repository at REPOS_PATH, and get a reference to its
# versioning filesystem.
repos_obj = svn.repos.svn_repos_open(repos_path)
fs_obj = svn.repos.svn_repos_fs(repos_obj)
# Query the current youngest revision.
youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj)
# Open a root object representing the youngest (HEAD) revision.
root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev)
# Do the recursive crawl.
crawl_filesystem_dir(root_obj, "")
if __name__ == "__main__":
# Check for sane usage.
if len(sys.argv) != 2:
sys.stderr.write("Usage: %s REPOS_PATH\n"
% (os.path.basename(sys.argv[0])))
sys.exit(1)
# Canonicalize the repository path.
repos_path = svn.core.svn_path_canonicalize(sys.argv[1])
# Do the real work.
crawl_youngest(repos_path)
同样的C程序需要处理APR内存池系统,但是Python自己处理内存,Subversion的Python绑定也遵循这种习惯。在C语言中,为表示路径和条目的hash需要处理自定义的数据类型(例如APR提供的库),但是Python有hash(叫做“dictionaries”),并且是内置数据类型,而且还提供了一系列操作这些类型的函数,所以SWIG(通过Subversion的语言绑定层的自定义帮助)要小心的将这些自定义数据类型映射到目标语言的数据类型,这为目标语言的用户提供了一个更加直观的接口。
Subversion的Python绑定也可以用来进行工作拷贝的操作,在本章前面的小节中,我们提到过libsvn_client接口,它存在的目的就是简化编写Subversion客户端的难度,例&8.3
“一个Python状态爬虫”是一个例子,讲的是如何使用SWIG绑定创建一个扩展版本的svn
status命令。
例&8.3.&一个Python状态爬虫
#!/usr/bin/env python
"""Crawl a working copy directory, printing status information."""
import sys
import os.path
import getopt
import svn.core, svn.client, svn.wc
def generate_status_code(status):
"""Translate a status value into a single-character status code,
using the same logic as the Subversion command-line client."""
code_map = { svn.wc.svn_wc_status_none
svn.wc.svn_wc_status_normal
svn.wc.svn_wc_status_added
svn.wc.svn_wc_status_missing
svn.wc.svn_wc_status_incomplete
svn.wc.svn_wc_status_deleted
svn.wc.svn_wc_status_replaced
svn.wc.svn_wc_status_modified
svn.wc.svn_wc_status_merged
svn.wc.svn_wc_status_conflicted
svn.wc.svn_wc_status_obstructed
svn.wc.svn_wc_status_ignored
svn.wc.svn_wc_status_external
svn.wc.svn_wc_status_unversioned : '?',
return code_map.get(status, '?')
def do_status(wc_path, verbose):
# Calculate the length of the input working copy path.
wc_path_len = len(wc_path)
# Build a client context baton.
ctx = svn.client.svn_client_ctx_t()
def _status_callback(path, status, root_path_len=wc_path_len):
"""A callback function for svn_client_status."""
# Print the path, minus the bit that overlaps with the root of
# the status crawl
text_status = generate_status_code(status.text_status)
prop_status = generate_status_code(status.prop_status)
print '%s%s
%s' % (text_status, prop_status, path[wc_path_len + 1:])
# Do the status crawl, using _status_callback() as our callback function.
svn.client.svn_client_status(wc_path, None, _status_callback,
1, verbose, 0, 0, ctx)
def usage_and_exit(errorcode):
"""Print usage message, and exit with ERRORCODE."""
stream = errorcode and sys.stderr or sys.stdout
stream.write("""Usage: %s OPTIONS WC-PATH
--help, -h
: Show this usage message
--verbose, -v : Show all statuses, even uninteresting ones
""" % (os.path.basename(sys.argv[0])))
sys.exit(errorcode)
if __name__ == '__main__':
# Parse command-line options.
opts, args = getopt.getopt(sys.argv[1:], "hv", ["help", "verbose"])
except getopt.GetoptError:
usage_and_exit(1)
verbose = 0
for opt, arg in opts:
if opt in ("-h", "--help"):
usage_and_exit(0)
if opt in ("-v", "--verbose"):
verbose = 1
if len(args) != 1:
usage_and_exit(2)
# Canonicalize the repository path.
wc_path = svn.core.svn_path_canonicalize(args[0])
# Do the real work.
do_status(wc_path, verbose)
except svn.core.SubversionException, e:
sys.stderr.write("Error (%d): %s\n" % (e[1], e[0]))
sys.exit(1)
就像例&8.2
“使用 Python
处理版本库层”中的例子,这个程序是池自由的,而且最重要的是使用Python的数据类型。svn_client_ctx_t()是欺骗,因为Subversion的API没有这个方法—这仅仅是SWIG自动语言生成中的一点问题(这是对应复杂C结构的一种工厂方法)。也需要注意传递给程序的路径(象最后一个)是通过
svn_path_canonicalize()执行的,因为要防止触发Subversion底层C库的断言,也就是防止导致程序立刻随意退出。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。随笔 - 709&
文章 - 8&评论 - 883&trackbacks - 19
在上篇文章中,我对的基本功能进行了一些介绍,今天在这里介绍一下如何在WebAPI中集成Swagger-UI。这里以一个简单的CRUD的REST服务为例。&
/// &summary&
/// 用户管理
/// &/summary&
public class UserController : ApiController
static List&User& _users = new List&Controllers.User&();
static int _idSeed = 0;
/// &summary&
/// 添加用户
/// &/summary&
/// &param name="user"&用户数据&/param&
/// &returns&&/returns&
public User Post(User user)
user.Id = ++_idS
_users.Add(user);
/// &summary&
/// 修改用户
/// &/summary&
/// &param name="id"&用户编号&/param&
/// &param name="user"&新用户信息&/param&
/// &returns&&/returns&
public IHttpActionResult Put(int id, User user)
var current = Get(id);
if (current == null)
return NotFound();
user.Id = current.Id;
_users.Remove(current);
_users.Add(user);
return Ok();
/// &summary&
/// 删除用户
/// &/summary&
/// &param name="id"&用户编号&/param&
public void Delete(int id)
var current = Get(id);
_users.Remove(current);
/// &summary&
/// 获取用户列表
/// &/summary&
/// &returns&FFF&/returns&
public IEnumerable&User& GetAll()
/// &summary&
/// 获取指定用户
/// &/summary&
/// &param name="id"&编号&/param&
/// &returns&&/returns&
public User Get(int id)
return _users.Find(i =& i.Id == id);
/// &summary&
/// &/summary&
public class User
/// &summary&
/// &/summary&
public int Id { get; set; }
/// &summary&
/// &/summary&
public string Name { get; set; }
/// &summary&
/// &/summary&
public string Address { get; set; }
使用Swashbuckle集成Swagger-UI
Swagger-UI本身只提供在线测试功能,要集成它还需要告诉它本项目提供的各种服务和参数信息。这里就需要一些工作量了,不过好在许多第三方库已经给我们完成了这一工作。我这里用的是Swashbuckle,使用它也比较简单,直接使用Nuget添加其程序包即可:
&&&&PM& Install-Package Swashbuckle
增加该程序包时,它本身会把自己相应的一些注册的代码添加到项目中,虽然我们可以不太关心这些操作,但有的时候还是需要修改一些相关的配置的。
重新编译并运行项目,我们就可以在项目地址后面加一个 "/swagger"来访问swagger测试页面了。
此时就可以进行API的测试操作了。不过,这里介绍的方法仅仅适用于IIS承载的WebAPI项目,对于Self Host或Owin承载的方式还有一些额外工作要做,具体请参看Swashbuckle的主页说明文档
默认的标题是项目名称(我这里的"WebApplication1"),我们常常需要把它改成一个更加友好的名称,修改的这个操作在前面的SwaggerConfig.cs文件中进行,找到如下代码:
前面一个参数是Swagger-UI的版本,好像目前支持v1和v2两种,后面就是标题了,直接修改即可。
集成XML注释
前面的测试页面虽然可以正常工作,但是接口说明和参数说明都是空着的,显得不够友好,但这些实际是可以从代码的XML注释中读取出来的。要实现这一效果,需要进行如下两步:
首先,开放注释的XML文档的输出:
然后,在SwaggerConfig.cs的EnableSwagger回调函数函数中,使用IncludeXmlComments函数指定XML文档的路径。
这样,我们的测试页面就能显示各种注释了(貌似不支持Controller的说明)。
更多高级的操作这里就不介绍了,有需要的朋友可以参考一下Swashbuckle的主页说明文档:
阅读(...) 评论()

我要回帖

更多关于 由人工编辑并提供网站 的文章

 

随机推荐