[英]HTTP POST in java throws an error - no suitable HttpMessageConverter found to read request body into object of type class
I have a java process which is listening to ActiveMQ messages and when the status is COMPLETE, I am calling HTTP POST as shown in the code below.我有一个 java 进程正在侦听 ActiveMQ 消息,当状态为 COMPLETE 时,我正在调用 HTTP POST,如下面的代码所示。 I'm referring to the following article for sending POST().
我指的是以下文章发送 POST()。 However, I'm running into following issue:
但是,我遇到了以下问题:
In the eclipse console, I am getting the following error:在 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"}
When I used POSTMAN, the request worked fine but I had to make following changes in the POSTMAN (as shown in the screenshot below - encircled in red).当我使用 POSTMAN 时,请求工作正常,但我必须在 POSTMAN 中进行以下更改(如下面的屏幕截图所示 - 以红色圈出)。
1) Put my parameters inside Body section of POSTMAN 1)把我的参数放在POSTMAN的Body部分
2) Changed the type to JSON. 2) 将类型更改为 JSON。
My relevant code below:我的相关代码如下:
// 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);
}
What am I doing wrong inside the sendPost()
method while calling HTTP POST?在调用 HTTP POST 时,我在
sendPost()
方法中做错了什么? Do I need to take care of JSON thing just like I did in POSTMAN.我是否需要像在 POSTMAN 中那样处理 JSON 的事情。 If yes, then how?
如果是,那么如何? Please advise.
请指教。 Thanks !
谢谢 !
EDIT [Testing Results after referring Ananthapadmanabhan's answer]编辑 [参考 Ananthapadmanabhan 的答案后的测试结果]
This time I didn't get any error but the record didn't get inserted into the database.这次我没有收到任何错误,但记录没有插入数据库。 The following is what I got in my eclipse after printing 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]}}
And here is my modified method that I used this time:这是我这次使用的修改方法:
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();
}
Question:问题:
1) What wrong I might be doing? 1)我可能做错了什么? 2) Is it mandatory to specify
details
in the json string? 2) 是否必须在 json 字符串中指定
details
? I noticed that if I didn't do that eclipse complains about deleting tokens.我注意到,如果我不这样做,eclipse 会抱怨删除令牌。
From my observation, I could understand that in your postman call, you are sending the post request with application/json
as the content-type
and a json in the request body, which is working fine.根据我的观察,我可以理解,在您的 postman 调用中,您发送的 post 请求的
content-type
为application/json
,请求正文中的 json 工作正常。 But in your code, you are setting it like:但是在您的代码中,您将其设置为:
post.setEntity(new UrlEncodedFormEntity(urlParameters));
try setting the content type as application/json
in your code as well for the post request instead of url-encoded one and it should work.For sending json I think you should use the StringEntity
class.尝试在您的代码中将内容类型设置为
application/json
,而不是 url 编码的请求,它应该可以工作。对于发送 json,我认为您应该使用StringEntity
class。 You could create a pojo class to map the data to be in the request and then use a json library like Gson to convert it to the appropriate format or you could do it manually like for example like: You could create a pojo class to map the data to be in the request and then use a json library like Gson to convert it to the appropriate format or you could do it manually like for example like:
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...
Create a json String to pass to Your API.创建一个 json 字符串以传递给您的 API。 Then call the below function with your JSON String and URL.
然后使用您的 JSON 字符串和 URL 调用以下 function。
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;
}
It will first send the Request to the API, setting all the necessary parameters.它将首先将请求发送到 API,设置所有必要的参数。 It will then accept a String response in "res", which IF NEEDED can be converted to JSONObject type.
然后它将接受“res”中的字符串响应,如果需要,可以将其转换为 JSONObject 类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.