我正在用Spring Boot编写一个后端应用程序,它从第三方调用另一个应用程序接口。
我对这个特定的调用有一个问题,它检索一个包含承载令牌的令牌对象,然后我在它们的其他endpoint中使用它。当调用其他终结点时,检索到的令牌有时工作,但大多数情况下不工作,从而导致未经授权的响应。
@RestController
public class CotizacionController {
Logger logger = LoggerFactory.getLogger(CotizacionController.class);
@Value("${service.credentials.tokenServer}")
private String tokenServer;
@Value("${service.credentials.grantType}")
private String grantType;
@Value("${service.credentials.username}")
private String username;
@Value("${service.credentials.password}")
private String password;
HttpClient client = HttpClient.newHttpClient();
@RequestMapping("/create")
public Object Create() throws IOException, InterruptedException {
HashMap<String, String> parameters = new HashMap<>();
parameters.put("grant_type", grantType);
parameters.put("username", username);
parameters.put("password", password);
String form = parameters.keySet().stream()
.map(key -> key + "="
+ URLEncoder.encode(parameters.get(key),
StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(tokenServer))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(BodyPublishers.ofString(form)).build();
HttpResponse<?> response = client.send(request, BodyHandlers.ofString());
TokenResponse result = new ObjectMapper().readValue(response
.body().toString(), TokenResponse.class);
return result;
}
}
下面是一个示例令牌对象:
{
"access_token": "z-bu-Pde6M2dlPiaRzd5XpTrT7ohpFQZe157HHVLfdKJWsdmKCloK7AYGEw7SLCe28tjYAxo8MZOE_3W00HEa-bqgUvcrAKfxIubAq0UGXv7jLPWbRwWzhAUCDon3kdstUrJ_OKRN2y26W6qyDBGDqlP5NRSF4unH_pD_ShmpDlSxZdYUqD0da5Y2_uO6YRs5GuWA7XhI9sPa98SxuXN_dwiDJVif418xK646fUgWR8",
"token_type": "bearer",
"expires_in": "3599"
}
使用postman检索令牌工作得非常好,因此第三方API不会有问题。我在中也实现了相同的服务。NET核心3,它在那里也工作得很好。
最让我困惑的是,实际的HttpClient调用是有效的,我确实得到了一个正确的Json,它映射到了我的TokenResponse对象。只是令牌值无效。。。有时
我还尝试使用了RestTemboard和WebClient Spring库,但结果是相同的。调用工作,但检索令牌无效。
起初,我认为我有一个竞争条件,因为最初我有另一个HttpClient在那里,另一个endpoint使用令牌调用的响应。因此,我将其简化为只调用令牌,并将令牌值手动复制到邮递员请求中。没有工作。
然后我想也许我的HttpClient授权头格式错误,但这是不被证明的,因为简单地使用邮递员请求将令牌复制到受保护的endpoint显示令牌不起作用。
还有我尝试过的其他事情:
在这一点上,我很迷茫,唯一想到的是,也许HttpClient.send()方法可能会以可能影响内容的方式解析主体?我对此表示怀疑,但我看不出还会发生什么。
解决方案与cookies有关!
令牌服务器响应发送2set-cookie
标头,其中在Postman和.NET Core被自动处理并设置为后续的HTTP请求。第三方API支持负载均衡器并生成这些会话cookie。
我在main
方法中使用以下代码实现了一个系统范围的CookieHandler,从而解决了这个问题。
public static void main(String[] args) {
CookieHandler.setDefault(new CookieManager());
SpringApplication.run(Main.class, args);
}
然后像这样构建我的HttpClient对象:
...
HttpClient client = HttpClient.newBuilder().cookieHandler(CookieHandler.getDefault()).build();
...
这样,响应set-cookie
和请求cookie
标头将被自动处理,并在该HttpClient进行的所有调用中工作。
默认情况下,CookieHandler是使用CookiePolicy创建的。接受原始服务器
参数。我的理解是,只有在同一主机设置并请求cookie时,cookie才能工作。有关CookiePolicy的更多选项,请查看文档
我尝试通过Java执行一个SOAP请求并获得SOAP响应,然后从JSP页面调用它。我研究了许多网站,尝试了许多方法,但似乎无法让它工作。 我使用一些wsdl来测试http://www.webservicex.net/australianpostcode.asmx?wsdl 我一直收到这个错误 java.io.ioException:服务器返回HTTP响应代码:500的URL:HTTP://www.
对于反应式编程和SpringWebClient来说,这是一个相当新的概念,所以我正在尝试了解它,本质上,我有一个分页的结果列表,可以从一个REST服务中使用,该服务使用一个链接响应头进行响应,该响应头带有一个与下一页结果(如果存在)相关的URI。我想把所有的页面都收集到一个通量中。默认情况下,生成的ApicClient具有如下内容 那么,我是否需要对结果的每一页进行某种递归调用,将每一页合并成一个
事情是这样的: 我正在为我的论文创建一个完全定制的服务器。在客户端,我希望能够请求服务器处理的数据库调用。然后,它以HTTP给出响应,以JSON提供查询结果。 我现在调用的方式是:使用JQuery的“getJSON()”方法。 虚拟示例: 在浏览器中运行带有此脚本的网页会在服务器端生成以下HTTP标头: 我的问题是:为了从浏览器上javascript的“result”参数中的响应中获得JSON负载
我需要使用Spring MVC重定向到一个外部服务,使用一个带有构建的对象的POST。 HttpClientHelper.java 我可以看到目标服务正被POST请求成功命中,我需要从MCV控制器读取响应的输出作为返回值,因为它当前只返回一个404。
在我的项目中,我创建了一个py函数,用于检查和修改我的谷歌日历,如下所示: 当我在lambda上测试它时,一切都完成了,但是当我从lambda创建API时: 并对其进行测试,结果是: 2017年12月20日星期三13:35:58 UTC:由于配置错误,执行失败:Lambda代理响应格式错误2017年12月20日星期三13:35:58 UTC:方法已完成,状态为:502 提前谢谢
问题内容: 我的网络服务返回一个JSON对象,如下所示 即,当我将此地址放入chrome浏览器中时,我可以到达上面。 我正在尝试在浏览器中阅读此内容,以便可以创建一个下拉选项…但是从以下代码开始我一无所获: 我总是在警报框中。我用fiddler2再次检查了Web服务请求/响应是否正常,我什至可以拦截Web服务和浏览器之间的json对象。 我也试过 我又得到了空。 我已经看过Ajax要求的json响