java 中的 HTTP POST 抛出错误 - 找不到合适的 HttpMessageConverter 将请求正文读入 class 类型的对象
HTTP POST in java throws an error - no suitable HttpMessageConverter found to read request body into object of type class
我有一个 java 进程正在侦听 ActiveMQ 消息,当状态为 COMPLETE 时,我正在调用 HTTP POST,如下面的代码所示。我指的是 以下内容
article 用于发送 POST()。但是,我 运行 遇到以下问题:
在 eclipse 控制台中,我收到以下错误:
Testing 1 - Send Http POST request
{"timestamp":"2020-05-15T01:00:59.232+0000","status":401,"error":"Unauthorized","message":"Authentication Failed : No suitable HttpMessageConverter found to read request body into object of type class com.abc.tpms.mxnf.entities.DataDeliveryAction from request with content type of application/x-www-form-urlencoded;charset=UTF-8!","path":"/CompanyServices/api/dataDeliveryActions"}
当我使用 POSTMAN 时,请求工作正常,但我必须在 POSTMAN 中进行以下更改(如下面的屏幕截图所示 - 红色圆圈)。
1) 将我的参数放入 POSTMAN
的 Body 部分
2) 将类型更改为 JSON。
我的相关代码如下:
// All imports goes here
@Component
public class DownloadConsumer {
@Autowired
private JavaMailSender javaMailSender;
// one instance, reuse
private final CloseableHttpClient httpClient = HttpClients.createDefault();
// Working Code with JMS 2.0
@JmsListener(destination = "MessageProducer")
public void processBrokerQueues(String message) throws DaoException {
System.out.println("Message Retrieved is:" +message);
try {
RequestDao requestDao = (RequestDao) context.getBean("requestDao");
String receivedStatus = requestDao.getRequestStatus(message);
//Before sending this message, do the check for COMPLETE or ERROR etc
if(receivedStatus.equals("COMPLETE")) {
/*****************************************************\
// START: Calling webservices
*******************************************************/
DownloadConsumer obj = new DownloadConsumer();
try {
System.out.println("Testing 1 - Send Http POST request");
obj.sendPost();
} finally {
obj.close();
}
}
else {
}
}
catch(Throwable th){
th.printStackTrace();
}
}
private void close() throws IOException {
httpClient.close();
}
private void sendPost() throws Exception {
HttpPost post = new HttpPost("https://myservername.com/CompanyServices/api/dataDeliveryActions");
// add request parameter, form parameters
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("requestId", "123456"));
urlParameters.add(new BasicNameValuePair("projectId", "71"));
urlParameters.add(new BasicNameValuePair("assetId", "4"));
urlParameters.add(new BasicNameValuePair("assetName", "Test at PM By User"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
try (CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(post)) {
System.out.println(EntityUtils.toString(response.getEntity()));
}
}
// URL of the JMS server. DEFAULT_BROKER_URL will just mean that JMS server is on localhost
private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private static String subject = "MessageProducer"; //Queue Name
// default broker URL is : tcp://localhost:61616"
private static ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
private static final Logger logger = LoggerFactory.getLogger(DownloadConsumer.class);
}
调用 HTTP POST 时,我在 sendPost()
方法中做错了什么?我是否需要像在 POSTMAN 中那样处理 JSON 事情。如果是,那么如何?请指教。谢谢!
编辑[参考 Ananthapadmanabhan 的回答后的测试结果]
这次我没有收到任何错误,但记录没有插入到数据库中。以下是我打印response后在我的eclipse中得到的。
Testing 1 - Send Http POST request
Printing Response in Eclipse HttpResponseProxy{HTTP/1.1 401 [Date: Fri, 15 May 2020 15:23:31 GMT, Server: Apache/2.4.6 () OpenSSL/1.0.2k-fips mod_fcgid/2.3.9, Cache-Control: private, max-age=0, must-revalidate, Vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers, X-Content-Type-Options: nosniff, X-XSS-Protection: 1; mode=block, Cache-Control: no-cache, no-store, max-age=0, must-revalidate, Pragma: no-cache, Expires: 0, Strict-Transport-Security: max-age=31536000 ; includeSubDomains, X-Frame-Options: DENY, Content-Type: application/json, Keep-Alive: timeout=5, max=100, Connection: Keep-Alive, Transfer-Encoding: chunked] ResponseEntityProxy{[Content-Type: application/json,Chunked: true]}}
这是我这次使用的修改方法:
private void sendPost() throws Exception {
HttpPost post = new HttpPost("https://myservername.com/CompanyServices/api/dataDeliveryActions");
StringEntity params =new StringEntity("details={\"requestId\":\"123456\",\"projectId\":\"71\",\"assetId\":\"4\",\"assetName\":\"test at AM by User\"} ");
post.setHeader("Content-type", "application/json");
post.setEntity(params);
CloseableHttpResponse response = httpClient.execute(post);
System.out.println("Printing Response in Eclipse "+response);
//assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
httpClient.close();
}
问题:
1) 我可能做错了什么?
2) 是否必须在 json 字符串中指定 details
?我注意到如果我不这样做,eclipse 会抱怨删除令牌。
根据我的观察,我可以理解,在您的 postman 调用中,您正在发送 post 请求,其中 application/json
作为 content-type
和 json 在请求正文中,工作正常。但是在您的代码中,您将其设置为:
post.setEntity(new UrlEncodedFormEntity(urlParameters));
尝试在您的代码中将内容类型设置为 application/json
以及 post 请求而不是 url 编码的请求,它应该 work.For 发送 json我觉得你应该用StringEntity
class。您可以创建一个 pojo class 来将数据映射到请求中,然后使用 json 库(如 Gson)将其转换为适当的格式,或者您可以手动执行此操作,例如:
HttpPost request = new HttpPost("http://yoururl");
StringEntity params =new StringEntity("{\"name\":\"myname\",\"age\":\"20\"} ");
request.setHeader("Content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
//handle response here...
创建一个 json 字符串以传递给您的 API。然后使用 JSON 字符串和 URL.
调用以下函数
public JSONObject httpPOSTClient(String json, String url) {
JSONObject jobj = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPost request = new HttpPost(url);
StringEntity params = new StringEntity(json);
request.addHeader("content-type", "application/json");
request.addHeader("Accept", "application/json");
request.setEntity(params);
CloseableHttpResponse response = httpClient.execute(request);
String res = org.apache.http.util.EntityUtils.toString(response.getEntity());
jobj = new JSONObject(res);
org.apache.http.util.EntityUtils.consume(response.getEntity());
} catch (Exception ex) {
}
return jobj;
}
它将首先发送请求到API,设置所有必要的参数。然后它将接受 "res" 中的字符串响应,如果需要,可以将其转换为 JSON 对象类型。
我有一个 java 进程正在侦听 ActiveMQ 消息,当状态为 COMPLETE 时,我正在调用 HTTP POST,如下面的代码所示。我指的是 以下内容 article 用于发送 POST()。但是,我 运行 遇到以下问题:
在 eclipse 控制台中,我收到以下错误:
Testing 1 - Send Http POST request
{"timestamp":"2020-05-15T01:00:59.232+0000","status":401,"error":"Unauthorized","message":"Authentication Failed : No suitable HttpMessageConverter found to read request body into object of type class com.abc.tpms.mxnf.entities.DataDeliveryAction from request with content type of application/x-www-form-urlencoded;charset=UTF-8!","path":"/CompanyServices/api/dataDeliveryActions"}
当我使用 POSTMAN 时,请求工作正常,但我必须在 POSTMAN 中进行以下更改(如下面的屏幕截图所示 - 红色圆圈)。
1) 将我的参数放入 POSTMAN
的 Body 部分2) 将类型更改为 JSON。
我的相关代码如下:
// All imports goes here
@Component
public class DownloadConsumer {
@Autowired
private JavaMailSender javaMailSender;
// one instance, reuse
private final CloseableHttpClient httpClient = HttpClients.createDefault();
// Working Code with JMS 2.0
@JmsListener(destination = "MessageProducer")
public void processBrokerQueues(String message) throws DaoException {
System.out.println("Message Retrieved is:" +message);
try {
RequestDao requestDao = (RequestDao) context.getBean("requestDao");
String receivedStatus = requestDao.getRequestStatus(message);
//Before sending this message, do the check for COMPLETE or ERROR etc
if(receivedStatus.equals("COMPLETE")) {
/*****************************************************\
// START: Calling webservices
*******************************************************/
DownloadConsumer obj = new DownloadConsumer();
try {
System.out.println("Testing 1 - Send Http POST request");
obj.sendPost();
} finally {
obj.close();
}
}
else {
}
}
catch(Throwable th){
th.printStackTrace();
}
}
private void close() throws IOException {
httpClient.close();
}
private void sendPost() throws Exception {
HttpPost post = new HttpPost("https://myservername.com/CompanyServices/api/dataDeliveryActions");
// add request parameter, form parameters
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("requestId", "123456"));
urlParameters.add(new BasicNameValuePair("projectId", "71"));
urlParameters.add(new BasicNameValuePair("assetId", "4"));
urlParameters.add(new BasicNameValuePair("assetName", "Test at PM By User"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
try (CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(post)) {
System.out.println(EntityUtils.toString(response.getEntity()));
}
}
// URL of the JMS server. DEFAULT_BROKER_URL will just mean that JMS server is on localhost
private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private static String subject = "MessageProducer"; //Queue Name
// default broker URL is : tcp://localhost:61616"
private static ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
private static final Logger logger = LoggerFactory.getLogger(DownloadConsumer.class);
}
调用 HTTP POST 时,我在 sendPost()
方法中做错了什么?我是否需要像在 POSTMAN 中那样处理 JSON 事情。如果是,那么如何?请指教。谢谢!
编辑[参考 Ananthapadmanabhan 的回答后的测试结果]
这次我没有收到任何错误,但记录没有插入到数据库中。以下是我打印response后在我的eclipse中得到的。
Testing 1 - Send Http POST request
Printing Response in Eclipse HttpResponseProxy{HTTP/1.1 401 [Date: Fri, 15 May 2020 15:23:31 GMT, Server: Apache/2.4.6 () OpenSSL/1.0.2k-fips mod_fcgid/2.3.9, Cache-Control: private, max-age=0, must-revalidate, Vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers, X-Content-Type-Options: nosniff, X-XSS-Protection: 1; mode=block, Cache-Control: no-cache, no-store, max-age=0, must-revalidate, Pragma: no-cache, Expires: 0, Strict-Transport-Security: max-age=31536000 ; includeSubDomains, X-Frame-Options: DENY, Content-Type: application/json, Keep-Alive: timeout=5, max=100, Connection: Keep-Alive, Transfer-Encoding: chunked] ResponseEntityProxy{[Content-Type: application/json,Chunked: true]}}
这是我这次使用的修改方法:
private void sendPost() throws Exception {
HttpPost post = new HttpPost("https://myservername.com/CompanyServices/api/dataDeliveryActions");
StringEntity params =new StringEntity("details={\"requestId\":\"123456\",\"projectId\":\"71\",\"assetId\":\"4\",\"assetName\":\"test at AM by User\"} ");
post.setHeader("Content-type", "application/json");
post.setEntity(params);
CloseableHttpResponse response = httpClient.execute(post);
System.out.println("Printing Response in Eclipse "+response);
//assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
httpClient.close();
}
问题:
1) 我可能做错了什么?
2) 是否必须在 json 字符串中指定 details
?我注意到如果我不这样做,eclipse 会抱怨删除令牌。
根据我的观察,我可以理解,在您的 postman 调用中,您正在发送 post 请求,其中 application/json
作为 content-type
和 json 在请求正文中,工作正常。但是在您的代码中,您将其设置为:
post.setEntity(new UrlEncodedFormEntity(urlParameters));
尝试在您的代码中将内容类型设置为 application/json
以及 post 请求而不是 url 编码的请求,它应该 work.For 发送 json我觉得你应该用StringEntity
class。您可以创建一个 pojo class 来将数据映射到请求中,然后使用 json 库(如 Gson)将其转换为适当的格式,或者您可以手动执行此操作,例如:
HttpPost request = new HttpPost("http://yoururl");
StringEntity params =new StringEntity("{\"name\":\"myname\",\"age\":\"20\"} ");
request.setHeader("Content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
//handle response here...
创建一个 json 字符串以传递给您的 API。然后使用 JSON 字符串和 URL.
调用以下函数public JSONObject httpPOSTClient(String json, String url) {
JSONObject jobj = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPost request = new HttpPost(url);
StringEntity params = new StringEntity(json);
request.addHeader("content-type", "application/json");
request.addHeader("Accept", "application/json");
request.setEntity(params);
CloseableHttpResponse response = httpClient.execute(request);
String res = org.apache.http.util.EntityUtils.toString(response.getEntity());
jobj = new JSONObject(res);
org.apache.http.util.EntityUtils.consume(response.getEntity());
} catch (Exception ex) {
}
return jobj;
}
它将首先发送请求到API,设置所有必要的参数。然后它将接受 "res" 中的字符串响应,如果需要,可以将其转换为 JSON 对象类型。