首页 > 解决方案 > 如何发送异步 Http 响应?

问题描述

我创建了一个接受请求并响应客户端的 Rest API。但是我的 API 依赖于第三方服务,而不是给出响应,而是给我的另一个端点一个回调。为了发送服务,我需要等待收到回调。我怎样才能实现它?

我需要发送响应的 Rest API。

@POST
//  @Produces(MediaType.TEXT_XML)
//  @Consumes(MediaType.TEXT_XML)
    public ConnectResponse connectAPI(String connectString, @Context HttpHeaders headers) {
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        for (Entry<String, List<String>> entry : headers.getRequestHeaders().entrySet()) {
            logger.info("Key = " + entry.getKey() + ", Value = " + entry.getValue());
            for (String eachEntry : entry.getValue()) {
                logger.info("eachEntry " + eachEntry);
            }
        }
        logger.info("USSD received " + connectString);
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        logger.info("---------- in connect post request ----------------------");
        ConnectRequest requestObj = new ConnectRequest();
        try {
            if (connectString != null && connectString.startsWith("<")) {
                requestObj = marshallConnectRequest(connectString);
            } else {
                requestObj = convertKeyValueToObject(connectString);
            }

            logger.info("Request is " + requestObj);
        } catch (JAXBException e) {
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error("----------------- Error in UnMarshalling ----------");
            logger.error(e.getMessage(), e);
        }
        ConnectResponse connectResponse = new ConnectResponse();
        connectResponse.setSession(requestObj.getSessionid());
        connectResponse.setText("Hello");
        logger.info("---------- returning response ----------------------");
        logger.info("---------- returning response ----------------------");
        logger.info("---------- returning response ----------------------");
        logger.info("---------- returning response ----------------------");
        logger.info("---------- returning response ----------------------");
        logger.info("---------- returning response ----------------------");
        logger.info("---------- returning response ----------------------");
        logger.info("---------- returning response ----------------------");
        return connectResponse;
    }

    public ConnectRequest marshallConnectRequest(String connectString) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(ConnectRequest.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        return (ConnectRequest) jaxbUnmarshaller.unmarshal(new StringReader(connectString));
    }

    public ConnectRequest convertKeyValueToObject(String connectString) {
        return new ConnectRequest();
    }

我不想发送简单的响应对象,而是希望等待回调到达以下 API。

@Path("/rest")
public class RESTWebservice {
    /*
     * @Context private MessageContext messageContext;
     */
    final Logger logger = Logger.getLogger(RESTWebservice.class);

    @POST
    @Path("/sendResponse")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public ResponseJSON postQuestionnaire(RequestJSON requestJson) {
    // performing operations
}

通话流程:-

  1. 客户端将调用 connectAPI,后者将调用第三方 API。
  2. 第三方API处理上述调用后会回调postQuestionnaire。
  3. 只有在收到 postQuestionnaire 的回调时,connectAPI 才会发送响应。

标签: javadesign-patternshttpresponse

解决方案


理想情况下,这应该是您的流程

  1. 客户端将调用 connectAPI,后者将调用第三方 API。
  2. 第三方API处理上述调用后会回调postQuestionnaire。---> 这应该使用CallableTask 使用 executor 服务在单独的线程中完成。然后您Future<ResponseFromPOstQuestionnaire>将从执行器服务submit调用中返回
  3. 只有在收到 postQuestionnaire 的回调时,connectAPI 才会发送响应。---> 一旦你有Future对象,你可以通过调用来等待.get()(这是阻塞调用),所以它会等待响应来,然后你可以将相同的响应或修改后的响应返回给客户端。

此处解释了如何将可调用任务与执行程序服务一起使用的示例-> https://www.journaldev.com/1090/java-callable-future-example


推荐阅读