首页 > 解决方案 > 错误 java.lang.IllegalArgumentException:无效的开始或结束

问题描述

我正在尝试测试来自 Salesforce 的 Rest API Callout,它通过 Apex 代码进行 OAuth 身份验证并运行到以下错误 Line: 12, Column: 1 System.UnexpectedException: java.lang.IllegalArgumentException: invalid start or end

public with sharing class RetrieveD365Data {
    //@future (callout=true)
    public void getD365Data() {
        RetrieveAzureToken atz = new RetrieveAzureToken();
        String bearer = atz.getAzureData();
        Http http = new Http();
        HttpRequest req1 = new HttpRequest();
        req1.setEndpoint('https://dev-xyz.com/data/Customers');
        req1.setMethod('GET');
        req1.setHeader('Authorization','Bearer '+bearer);
        HttpResponse res1 = http.send(req1);           //Error is thrown in this line
        System.debug('Response Body=========' + res1.getBody());
    }
}

RetrieveAzureToken如下所示,并且按预期工作,我可以使用不记名令牌取回响应

global class RetrieveAzureToken {

    private final String clientId = 'xxxxxxxxx';
    private final String clientSecret = 'xxxxxxxxxx';

    public String getAzureData()
    {
        String reqbody = 'grant_type=client_credentials&client_id='+clientId+'&client_secret='+clientSecret;
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setBody(reqbody);
        req.setMethod('POST');
        req.setEndpoint('https://login.microsoftonline.com/tenant/oauth2/token');
        HttpResponse res = h.send(req);
        deserializeResponse resp1 = (deserializeResponse)JSON.deserialize(res.getbody(),deserializeResponse.class);
        system.debug('Token from Azure :' + resp1.access_token);  
        return  resp1.access_token;
    }

    public class deserializeResponse
    {
        public String token_type;
        public String expires_in;
        public String ext_expires_in;
        public String expires_on;
        public String not_before;
        public String resource;
        public String access_token;
    }
}

请帮助我弄清楚我在这里缺少什么。

标签: javarestoauth-2.0salesforceapex

解决方案


使用基于 Jersey 的 REST 服务和使用 HttpURLConnection 的客户端,我可以观察到相同的 IllegalArgumentException。

场景是这样的:

REST 服务定义了一个资源函数

@GET
public void throw401() {
  throw new javax.ws.rs.NotAuthorizedException("");
}

此资源由客户端调用为

HttpURLConncection c = (HttpURLConnection)url.openConnection();
int status = c.getResponseCode(); // throws IllegalArgumentException: invalid start or end

我的解决方案是将资源更改为:

@GET
public void throw401() {
  throw new javax.ws.rs.NotAuthorizedException(Response.status(Response.UNAUTHORIZED));
}

我认为 - 没有证明 - 构造函数 NotAuthorizedException(String) 在没有身份验证模式的情况下生成 WWW-Authenitcate 标头。当 HttpURLConnection 尝试解析它时,这会导致抛出 IllegalArgumentExcption。构造函数 NotAuthorizedException(Resonse) 只是发送一个没有 WWW-Authentication 标头的状态 401。


推荐阅读