【问题标题】:Make asynchronous web service call as synchronous in Java在 Java 中将异步 Web 服务调用设为同步
【发布时间】:2012-11-21 22:55:03
【问题描述】:

我是 Web 服务开发的初学者。 我们正在使用 Spring 3 在 Java 中构建 REST Web 应用程序。

我们正在使用的 Web 服务具有异步登录方法。我们为他们提供了一个回调侦听器 URL,他们的服务会在其中回发响应。

因此,当我们发送登录请求时,我们会收到一个空白响应作为确认。服务会在侦听器 URL 上发送包含实际数据的响应。

请帮忙,我应该如何设计/实现将登录服务调用为同步调用? 谢谢。

编辑: 下面是回发消息的侦听器/控制器,它提取令牌并设置为对象。

@Controller
public class PostbackController {

    @Autowried
    public LoginResponse loginRS;

    @RequestMapping(value = "/callbacklistener", method = RequestMethod.POST)
    @ResponseBody
    public String postbackHandler(@RequestParam("postback") String requestMessage) {
        //We extract the token value from requestMessage.
        String token = requestMessage;
        loginRS.setToken(token);
        return "<Confirm/>";
    }
}

下面是一个调用登录服务并等待 10 秒的线程。它每 2 秒检查一次对象的状态。

public class LoginService extends Thread {

    @Autowried
    public LoginResponse loginRS;

    public LoginService() {
        this.start();
    }

    @Override
    public void run() {
        try {
            System.out.println("Thread Start.");
            this.login();
            System.out.println("Thread Complete.");
        } catch (InterruptedException e) {}
    }

    public LoginResponse login() {
        String loginXML = "";
        String response = "";//by calling REST web service using RESTtemplate we get blank response.

        for(i=0; i < 6; i++) {
            if(loginRS.getToken().length > 0))  {
                //Got the response exit from thread
                break;
            }
            else {
                //Wait for 2 second
                Thread.sleep(2000)
            }
        }
        return loginRS;
    }
}

如果您需要更多信息,请告诉我。谢谢

【问题讨论】:

  • 哦,“可爱”。虽然我不知道这是否直接违反了 REST 的“规则”,但它肯定违反了原则的精神。 (它还要求客户端在某处托管 Web 服务,这很讨厌。)

标签: java web-services rest asynchronous synchronous


【解决方案1】:

一些伪代码给你的想法

Login request sender Thread{

    acknowledgement = sendLoginRequest

    sleep() or wait on some lock

}


ListenerThread{

    response received = listenForResponse

    lock.notifyAll() or interrupt Login Thread

}

这样做会使其同步。

更新:

public class PostbackController {

        @Autowried
        public LoginResponse loginRS;
        //instance 1 injected by Spring where you set the token
}



public class LoginService extends Thread {

    @Autowried
    public LoginResponse loginRS;

    //a NEW instance will be created here also by Spring which will not have that token you set, as this is a new instance. So Thread will keep sleeping always.
}

使PostbackController 嵌套类LoginService 并使用PostbackController 的相同实例

【讨论】:

  • 谢谢!!是的,这可能是可能的解决方案,我们已经对此进行了研究。但它没有按预期工作。我们创建了一个作为监听器的控制器。当侦听器收到回发消息时,它会更新一个对象。有一个服务将登录服务作为线程调用并等待 10 秒,每 2 秒检查一次对象的状态。
  • 是的,这个方法被称为polling,但缺点是当有很多线程时会产生开销。所以你应该使用interrupt()或者notify()机制来唤醒休眠的线程。那会更有效率。如果您可以分享新代码,我可以帮助您。
  • 当我们@Autowired 一个对象时,它不会创建任何新实例,而是共享同一个对象。另外,这里PostbackController 是控制器,所以我不知道嵌套类。
  • @AnkurRaiyani 不知道 :) 不是 Spring 开发人员。由 setToken() 更新的 token 是否声明为 volatile ? Cz 如果@Autowired 共享实例,那么这可能是造成问题的原因。看看吧
  • 我正在使用 Apache GenericObejctPool 来维护会话池。所以池对象的生命周期完全由 Apache Pool 库处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 1970-01-01
  • 2023-03-15
  • 2011-09-03
相关资源
最近更新 更多