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我觉得你应该用StringEntityclass。您可以创建一个 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...

Link

创建一个 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 对象类型。