Ответ 1
Здесь что-то, что я использовал в моем Apex Trigger
System.URL.getSalesforceBaseUrl().getHost().remove('-api' );
Это дает мне правильный URL
На странице visualforce мне нужно получить URL-адрес экземпляра нашей организации salesforce, а не URL-адрес визуальной силы.
Например, мне нужно https://cs1.salesforce.com
вместо https://c.cs1.visual.force.com
Вот что я пробовал до сих пор и результат, который я получил:
Доступ к глобальной переменной сайта с страницы VF:
<apex:outputText value="{!$Site.Domain}" />
возвращает null
Sidenote: Кажется, что все в $Site.xxx
возвращает null
.
От контроллера Apex:
public String getSfInstance() { return ApexPages.currentPage().getHeaders().get('Host'); }
и
public String getSfInstance() { return URL.getSalesforceBaseUrl().toExternalForm(); }
возвращает c.cs1.visual.force.com
и https://c.cs1.visual.force.com
соответственно.
Вопрос: Как получить то, что я хочу: https://cs1.salesforce.com
?
Здесь что-то, что я использовал в моем Apex Trigger
System.URL.getSalesforceBaseUrl().getHost().remove('-api' );
Это дает мне правильный URL
Это известная проблема, URL.getSalesforceBaseUrl()
должна предоставить эту информацию, но это не так. Однако на самом деле это имеет очень ограниченное функциональное воздействие.
Их экземпляры и вершинные домены взаимозаменяемы в том смысле, что запрос URL-адреса, который не принадлежит одному, перенаправляется на другой.
например, если вы ищете /apex/myPage из cs1.salesforce.com, вы получите перенаправление на c.cs1... и запрос/идентификатор vise versa/ID из домена apex перенаправит вас в домен экземпляра (если только подробное действие был отменен)
Если это не поможет вам, есть одно обходное решение, хотя и очень уродливое: создать пользовательский объект для хранения базового url и создать перед триггером insert/update, который установит поле baseURL в URL.getSalesforceBaseUrl().toExternalForm()
. Очевидно, триггер - это единственное место на платформе, где это будет работать (кроме анонимного исполнения, которое не очень полезно). При настройке приложения вставьте что-то в эту таблицу, а затем используйте SOQL для извлечения базового url.
Вот свойство Apex, которое вы можете ввести в класс Utility, который будет надежно возвращать экземпляр для вашей организации. Используя это, вы можете легко создать свою URL-адрес Salesforce вашей организации, добавив ".salesforce.com" в экземпляр:
public class Utils {
// Returns the Salesforce Instance that is currently being run on,
// e.g. na12, cs5, etc.
public static String Instance {
public get {
if (Instance == null) {
//
// Possible Scenarios:
//
// (1) ion--test1--nexus.cs0.visual.force.com --- 5 parts, Instance is 2nd part
// (2) na12.salesforce.com --- 3 parts, Instance is 1st part
// (3) ion.my.salesforce.com --- 4 parts, Instance is not determinable
// Split up the hostname using the period as a delimiter
List<String> parts = System.URL.getSalesforceBaseUrl().getHost().replace('-api','').split('\\.');
if (parts.size() == 3) Instance = parts[0];
else if (parts.size() == 5) Instance = parts[1];
else Instance = null;
} return Instance;
} private set;
}
// And you can then get the Salesforce base URL like this:
public static String GetBaseUrlForInstance() {
return 'https://' + Instance + '.salesforce.com';
}
FYI: для сценария (1) первое имя хоста из 4 частей может стать очень сложным, но вы всегда сможете найти имя экземпляра в качестве второй части. Для тех, кто заинтересован, синтаксис сценария 1 следует этому шаблону:
<MyDomain>--<SandboxName>--<Namespace>.<Instance>.visual.force.com
Здесь у вас есть довольно хороший и небольшой фрагмент, который делает, что нужно для VisualforcePages: -)
String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
// Example: c.cs7.visual.force.com
sUrlRewrite = 'https://'
+ sUrlRewrite.substring(2,6)
+ 'salesforce.com'
+ '/'
+ recordId;
//Возвращает: https://cs7.salesforce.com/00kM00000050jFMIAY
Это неудачный недостаток платформы. GetSalesforceBaseUrl()
содержит оговорки, включая:
Единственный надежный способ получить истинную конечную точку pod/instance - использовать API идентификации Salesforce.
Здесь memoized static, который можно использовать, что смягчает все перечисленные выше факторы:
/**
* Determines the true API hostname for a Salesforce org using the Identity API.
* eg 'https://pod.salesforce.com' (most orgs)
* eg 'https://custom.my.salesforce.com' (my domain)
* eg 'https://custom--dev.pod.my.salesforce.com' (sandbox orgs)
*/
static public String protocolAndHost {
get {
if (protocolAndHost == null) {
//memoize
String uid = UserInfo.getUserId();
String sid = UserInfo.getSessionId();
String oid = UserInfo.getOrganizationId();
String base = Url.getSalesforceBaseUrl().toExternalForm();
//use getSalesforceBaseUrl within batches and schedules (not Visualforce), and fix inconsistent protocol
if (sid == null) return base.replaceFirst('http:', 'https:');
//within test context use url class, else derive from identity response
PageReference api = new PageReference('/id/' + oid + '/' + uid + '?access_token=' + sid);
String content = Test.isRunningTest() ? '{"urls":{"profile":"' + base + '"}}' : api.getContent().toString();
Url profile = new Url(content.substringBetween('"profile":"', '"'));
protocolAndHost = profile.getProtocol() + '://' + profile.getHost();
}
return protocolAndHost;
}
}
Исправление к фрагменту Alex_E:
String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
String sfBaseProtocol = System.URL.getSalesforceBaseUrl().getProtocol();
//remove namespace
integer firstDotPos = sUrlRewrite.indexOf('.');
sURlRewrite = sURlRewrite.substring(firstDotPos+1);
//replace visual.force with salesforce
sURlRewrite = sURlRewrite.replace('visual.force', 'salesforce');
sUrlRewrite = sfBaseProtocol+'://'+sURlRewrite;
serverURL = sUrlRewrite;
Это работает для меня:
String sUrlRewrite = System.URL.getSalesforceBaseUrl().getProtocol()
+ '://' + System.URL.getSalesforceBaseUrl().getHost()
+ '/' + record.Id;
Вот как это сделать с regex
public String getURL() {
return String.format(
'https://{0}.salesforce.com',
new String[]{
URL.getSalesforceBaseUrl().getHost().substringAfter('.').substringBefore('.')
});
}