脚本语言和 ArcGIS REST API
在本主题中
ArcGIS REST API 可使用任何能够通过 HTTP 调用 RESTful Web 服务和解析响应的脚本语言。包括 Python、Java、JavaScript、PowerShell、C#、Ruby、Scala、Perl 以及其他语言。
ArcGIS Server 帮助中的 REST API 示例使用的是 Python 语言。但下方示例将演示如何使用各种语言编写等效的脚本。每个脚本都可启动随 ArcGIS Server 一起安装的几何服务。
Python
此脚本使用 Python 语言启动几何服务。
启动服务需要具有管理权限,因此运行此脚本时必须提供一个具有管理员权限的用户名和密码。
# Demonstrates how to start a service by starting the geometry service
# This service is included with every ArcGIS Server and is stopped by default
# For Http calls
import httplib, urllib, json
# For system tools
import sys
# For reading passwords without echoing
import getpass
# Defines the entry point into the script
def main(argv=None):
# Print some info
print
print "This tool is a sample script that starts the Geometry service on a Server."
print
# Ask for admin/publisher user name and password
username = raw_input("Enter user name: ")
password = getpass.getpass("Enter password: ")
# Ask for server name
serverName = raw_input("Enter server name: ")
serverPort = 6080
# Get a token
token = getToken(username, password, serverName, serverPort)
if token == "":
print "Could not generate a token with the username and password provided."
return
# Construct URL to start a service - as an example the Geometry service
serviceStartURL = "/arcgis/admin/services/utilities/Geometry.GeometryServer/start"
# This request only needs the token and the response formatting parameter
params = urllib.urlencode({'token': token, 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = httplib.HTTPConnection(serverName, serverPort)
httpConn.request("POST", serviceStartURL, params, headers)
# Read response
response = httpConn.getresponse()
if (response.status != 200):
httpConn.close()
print "Error while attempting to start the service."
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
print "Error returned by operation. " + data
else:
print "Operation completed successfully!"
return
# A function to generate a token given username, password and the adminURL.
def getToken(username, password, serverName, serverPort):
# Token URL is typically http://server[:port]/arcgis/admin/generateToken
tokenURL = "/arcgis/admin/generateToken"
# URL-encode the token parameters
params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = httplib.HTTPConnection(serverName, serverPort)
httpConn.request("POST", tokenURL, params, headers)
# Read response
response = httpConn.getresponse()
if (response.status != 200):
httpConn.close()
print "Error while fetching tokens from admin URL. Please check the URL and try again."
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
return
# Extract the token from it
token = json.loads(data)
return token["token"]
# A function that checks that the input JSON object
# is not an error object.
def assertJsonSuccess(data):
obj = json.loads(data)
if 'status' in obj and obj['status'] == "error":
print "Error: JSON object returns an error. " + str(obj)
return False
else:
return True
# Script start
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
Windows PowerShell
此脚本使用 Windows PowerShell 语言启动几何服务。旨在演示如何通过 ArcGIS REST API 编写其他 PowerShell 脚本。
# Demonstrates how to start a service by starting the geometry service.# This service is included with every ArcGIS Server
and is stopped by default.
# To run this script, you must set the the appropriate security settings.
# For more information about Powershell security, visit the following URL:
# http://www.windowsecurity.com/articles/PowerShell-Security.html
# provides serialization and deserialization functionality for JSON object
Add-Type -AssemblyName System.Web.Extensions
# Defines the entry point into the script
function main(){
# Print some info
echo "This is a sample script that starts the ArcGIS Server geometry service."
# Ask for admin/publisher user name
$username = read-host "Enter user name"
$securePassword = read-host -AsSecureString "Enter password"
# Ask for Admin/publisher password
# Use Marshal Class to decode the secure string. Reference:
# http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx
$Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($securePassword)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)
[System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)
# Ask for servername
$serverName = read-host "Enter server name"
$serverPort = 6080
# Get a token
$token = token $username $password $serverName $serverPort
if(!$token){
write-warning "Could not generate a token with the username and password provided"
return
}
# construct URL to start a service - as an example the Geometry service
$url = "http://${serverName}:${serverPort}/arcgis/admin/services/Utilities/Geometry.GeometryServer/start"
$parameters = "token=${token}&f=json"
# Construct a HTTP request
$http_request = New-Object -ComObject Msxml2.XMLHTTP
$http_request.open('POST', $url, $false)
$http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
# Connect to URL and post parameters
try{
$http_request.send($parameters)
}
catch{
write-warning 'There were exceptions when sending the request'
return
}
# Read response
if($http_request.status -eq 200){
# Check that data returned is not an error object
if(assertJsonSuccess $http_request.responseText){
echo "Operation completed successfully!"
}
else{
write-warning "Error returned by operation."
write-warning $http_request
}
}
else{
write-warning "Error while attempting to start the service."
}
}
# A function to generate a token given username, password and the adminURL.
function token([string]$username, [string]$password, [string]$serverName, [int]$serverPort){
# Token URL is typically http://server[:port]/arcgis/admin/generateToken
$url = "http://${serverName}:${serverPort}/arcgis/admin/generateToken"
$parameters = "username=${username}&password=${password}&client=requestip&f=json"
# Construct a HTTP request
$http_request = New-Object -ComObject Msxml2.XMLHTTP
$http_request.open('POST', $url, $false)
$http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
# Connect to URL and post parameters
$token = ''
try{
$http_request.send($parameters)
}
catch{
write-warning 'There were exceptions when sending the request'
return $token
}
# Read response
if($http_request.status -eq 200){
# Check that data returned is not an error object
if(assertJsonSuccess $http_request.responseText){
# Extract the token from it
$jsonSerializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer
$jsonObj = $jsonSerializer.DeserializeObject($http_request.responseText)
$token = $jsonObj['token']
}
}
else{
write-warning "Error encountered when retrieving an administrative token. Please check your credentials and try again."
}
$token
}
# A function that checks that the input JSON object
# is not an error object.
function assertJsonSuccess([string]$data){
$jsonSerializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer
$jsonObj = $jsonSerializer.DeserializeObject($data)
if($jsonObj['status'] -eq 'error'){
write-warning "JSON object returns an error. Data => ${data}"
$FALSE
}
else{
$TRUE
}
}
# Script start
main
Perl
此示例脚本使用 Perl 启动几何服务。脚本始终尝试安全登录(加密用户名和密码)。如果 ArcGIS Server 未配置 HTTPS,则安全登录尝试失败,默认情况下,脚本将尝试非安全登录。如果不希望尝试非安全登录,则使用 -e 选项要求安全登录。
此脚本使用所有 Perl 分布通常随附的 LWP 和 HTTP 库。此脚本无需在其运行系统上安装任何 Esri 软件。
如果要更改此脚本以供您自己使用,请注意修改位于“工具”文件夹中的几何服务和脚本中使用的 URL 以配合其他文件夹名称。
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common qw(GET POST);
my $ua = LWP::UserAgent->new;
$ua->timeout(300); #services start within 5 minutes or timeout
my ($user, $password, $serverName, $port, $requireEncryption) = getUserInput();
my $baseUrl ="http://$serverName:$port/arcgis";
my $token = getToken($baseUrl, $user, $password, $requireEncryption);
startService($baseUrl, $token, "Geometry", "GeometryServer");
sub getToken {
# Attempt to login securely.
# If it fails and encryption required, tell user.
# If it fails and encryption not required, try insecure login.
my ($baseUrl, $user, $password, $requireEncryption) = @_;
my $secureUrl = $baseUrl;
$secureUrl =~ s/http/https/;
$secureUrl =~ s/:6080/:6443/;
my $token = makeTokenRequest($secureUrl, $user, $password);
return $token if (defined $token);
if ($requireEncryption) {
print "Unable to login. Either the server doesn't support https, or the server name,\nusername, or password might be incorrect.\n\n";
exit(1);
}
$token = makeTokenRequest($baseUrl, $user, $password);
return $token if (defined $token);
print "Unable to get token. The server name, username, or password might be incorrect.\n";
exit(1);
}
sub makeTokenRequest {
my ($url, $user, $password) = @_;
my $response = makeHttpPost("$url/admin/generateToken", {username=>$user, password=>$password, client=>"requestip", expiration=>30, f=>'json'});
if ($response =~/\{\"token\"\:\"(.*)\",/) {
return $1;
} else {
return undef;
}
}
sub startService {
my($baseUrl, $token, $serviceName, $serviceType) = @_;
my $response = makeHttpPost("$baseUrl/admin/services/Utilities/$serviceName.$serviceType/start", {f=>'json', token=>$token});
if ($response eq "") {
print "ERROR: Unable to start the service. Unable to make http connection to server.\n";
} elsif ($response =~/success/) {
print "Service $serviceName.$serviceType successfully started.\n";
} elsif ($response =~ /"code":404/) {
print "Service $serviceName.$serviceType was not found. Please check for typos.\n";
}
}
sub makeHttpPost {
my $url = $_[0];
my %parameter = %{$_[1]};
my $req = HTTP::Request->new(POST => $url);
$req->content_type('application/x-www-form-urlencoded');
my $requestParameters = "";
foreach my $key ( keys %parameter) {
$requestParameters .= "$key=$parameter{$key}&"
}
$req->content($requestParameters);
my $res = $ua->request($req);
if ($res->is_success) {
return $res->content;
} else {
return "";
}
}
sub getUserInput {
my ($user, $password, $serverName, $port, $requireEncryption);
$serverName = "localhost";
$port = "6080";
$requireEncryption = 0;
if ($#ARGV < 0) {
print "This tool is a sample script that starts the Geometry service on a Server.\n\n";
print "\t-u\tArcGIS Server publisher or admin user. Required\n";
print "\t-p\tPassword for the user. Required.\n";
print "\t-s\tServer machine. Optional, default is localhost.\n";
print "\t-t\tPort. Optional, default is 6080.\n";
print "\t-e\tRequire secure login.\n";
print "\n\n\tExample: startGeometryService -u admin -p password.\n";
print "\tExample: startGeometryService -u admin -p password -s gis1.\n";
print "\tExample: startGeometryService -u admin -p password -e.\n";
print "\tExample: startGeometryService -u admin -p password -s gis1 -t 80.\n\n";
print "Warning: This script always tries to login securely through https (encrypted).\n";
print "If that fails, it tries an insecure login since ArcGIS Server may not be\n";
print "configured for https. Use the -e option to avoid ever using an insecure login.\n\n\n";
exit();
} else {
for my $i (0 .. $#ARGV) {
$user = $ARGV[$i+1] if ($ARGV[$i] eq "-u");
$password = $ARGV[$i+1] if ($ARGV[$i] eq "-p");
$serverName = $ARGV[$i+1] if ($ARGV[$i] eq "-s");
$port = $ARGV[$i+1] if ($ARGV[$i] eq "-t");
$requireEncryption = 1 if ($ARGV[$i] eq "-e");
}
}
if (! defined $user || ! defined $password) {
print "A user was not provided using the correct syntax.\n" if (! defined $user);
print "A password was not provided using the correct syntax.\n" if (! defined $password);
exit(1);
}
return ($user, $password, $serverName, $port, $requireEncryption);
}
Scala
以下示例用 Scala 语言编写。可以停止或启动几何服务。
// Sample usage of the ArcGIS for Server Administrator API
// - Dispatch (http://dispatch.databinder.net)
// - LiftJSON
// ...demonstrates how to START or STOP the Geometry Service in an ArcGIS Server site
import dispatch._
import dispatch.liftjson._
import Http._
import dispatch.liftjson.Js._
import net.liftweb.json.JsonAST._
object StartStopGeometryService {
def main(args: Array[String]){
try{
print("Enter Command (START or STOP): ")
val command = Console.readLine()
print("Enter host name: ")
val host = Console.readLine()
print("Enter port:")
val port = Console.readLine()
print("Enter username: ")
val username = Console.readLine()
print("Enter password (WARNING! Password will show up as clear text): ")
val password = Console.readLine()
// if (!command.equalsIgnoreCase("start") || !command.equalsIgnoreCase("stop")){
// println("Usage: StartGeometryService <START | STOP> <hostname> <port> <username> <password>")
// sys.exit()
// }
// Http Request
val http = new Http
// Request a TOKEN...
val u = url("http://" + host + ":" + port + "/arcgis/admin/generateToken") << Map("f" -> "pjson","username" -> username.toString, "password" -> password.toString,"client" -> "requestip" , "expiration" -> "1000")
val token = http(u ># {json => (json \\ "token").values})
// Use the token to make a call to the Geometry Service to START or STOP (STOP, in this case)
val geomStartURL = url("http://" + host + ":" + port + "/arcgis/admin/services/Utilities/Geometry.GeometryServer/" + command) << Map("f" -> "pjson", "token" -> token.toString)
val response = http(geomStartURL ># {json => json})
println(response)
}catch{
case e: Exception => println(e.getMessage)
}
}
}