java - 带有 HttpURLConnection 的 PostRequest 的 401
问题描述
更新 我的问题原来是由于一些超类的怪异。但是,此示例中的 urlEncode 是错误的。在这种情况下,它也是不必要的。如果需要,应该通过每个键和值来完成,而不需要编码 & 或 =。除此之外,此代码是正确的。
下面的(scala)代码失败,因为服务器似乎没有收到正文。服务器日志上的警告是:
警告 *** OAuthTokenProcessor 捕获了带有消息 OAuthProblemException{error='invalid_request', description='Missing grant_type parameter value', uri='null', state='null', scope='null', redirectUri='null' 的 OAuthRequestProblemException ,响应状态=0,参数={}}
我确信参数是正确的。url 正确,标题正确(此调用已在 Postman 和 Python 中有效)
任何提示都非常感谢!
private def doPostRequest(): Unit ={
try {
val connectionforPost = (new URL(url)).openConnection.asInstanceOf[HttpURLConnection]
val params = "grant_type=password&client_id=xxxx&client_secret=seccret&username=admin&password=xxxx"
val encodedString = URLEncoder.encode(params,"UTF-8")
import java.nio.charset.StandardCharsets
val postData = encodedString.getBytes(StandardCharsets.UTF_8)
val contentlength = Integer.toString(encodedString.length)
connectionforPost.setConnectTimeout(50000)
connectionforPost.setReadTimeout(50000)
connectionforPost.setRequestMethod("POST")
connectionforPost.setDoOutput(true)
connectionforPost.setDoInput(true)
connectionforPost.setInstanceFollowRedirects(false)
connectionforPost.setRequestProperty("User-agent", "test bot")
connectionforPost.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
connectionforPost.setRequestProperty("Accept", "*/*")
connectionforPost.setRequestProperty("Connection", "keep-alive")
connectionforPost.setRequestProperty("Content-Length", contentlength)
connectionforPost.setRequestProperty("Accept-Encoding", "gzip, deflate")
connectionforPost.setUseCaches(false)
import java.io.DataOutputStream
val wr = new DataOutputStream(connectionforPost.getOutputStream)
wr.write(postData)
if (wr != null) wr.close()
} catch{
case e:Exception => logger.error(e.getMessage,e)
throw e
}
}
解决方案
似乎服务器抱怨您没有登录。您收到身份验证问题异常。它通常的工作方式是您向服务器发送请求以使用用户名和密码登录。如果服务器对您进行身份验证(将您的用户名和密码识别为有效的),它会向您发送一个响应,其中包含标头中的身份验证令牌。您可能会在成功登录的响应中看到这 2 个标题:
access-control-expose-headers=[Authorization], Authorization=[Bearer ....]
这意味着在您的所有后续请求中,您将需要添加一个标头“授权”,该标头将包含值“Bearer ....”。然后服务器会将此请求识别为来自经过身份验证的用户。另外,我建议您可以使用 3d 方 HTTP 客户端。一些著名的客户端是Appache HTTP 客户端和OK HTTP 客户端。我使用自己编写的 Http 客户端。它也可作为 MgntUtils 开源库的一部分使用。这是Maven 工件的链接,它也可以在Github上找到,带有源代码和 JavaDoc。这是HttpClient的 javadoc 页面。以下是有关如何获取和使用令牌的代码示例:
try {
HttpClient loginClient = new HttpClient();
loginClient.setConnectionUrl("http://your_url/login");
loginClient.setRequestProperty("accept", "application/json;charset=UTF-8");
loginClient.setContentType("application/json");
String result = loginClient.sendHttpRequest(HttpMethod.POST, "{ \"username\": \"your_user_name\", \"password\": \"Your_password\"}");
System.out.println(result);
System.out.println("HTTP " + loginClient.getLastResponseCode() + " " + loginClient.getLastResponseMessage());
System.out.println("Response headers: " + loginClient.getLastResponseHeaders());
String accessControlExposeHeader = loginClient.getLastResponseHeader("access-control-expose-headers").get(0);
String accessKey = loginClient.getLastResponseHeader(accessControlExposeHeader).get(0);
HttpClient workingClient = new HttpClient();
workingClient.setRequestProperty("accept", "application/json;charset=UTF-8");
workingClient.setContentType("application/json");
workingClient.setRequestProperty(accessControlExposeHeader, accessKey);
workingClient.setConnectionUrl("http://yourUrl/yourPath");
System.out.println(workingClient.sendHttpRequest(HttpMethod.GET));
} catch (IOException e) {
System.out.println(TextUtils.getStacktrace(e));
}
推荐阅读
- c# - 内容管理器未检测到 Monogame 自定义导入器/处理器
- snowflake-cloud-data-platform - 如何检查是否为雪花表启用了 CHANGE_TRACKING?
- r - predict.coxph 在类型为“风险”时有效,但在类型为“预期”或“生存”时无效
- android-studio - 在 RSS 提要标签内显示数据
- c# - 如何处理 XML 元素上的缺失字段
- deep-learning - PyTorch:目标 1 超出范围
- java - JPA 中的后续查询执行
- javascript - 如何自动对齐网格项目?[购物]
- javascript - IF 语句中的 jQuery OR 运算符检查任一文本字段是否为空
- python-3.x - JSONDecodeError:额外数据:第 2 行第 1 列