0

我不确定我想做的事情是否不可能,或者可能是长周末前的星期五,我的大脑已经检查过了。我尝试了几种方法,但似乎没有什么能让我得到我想要的。

背景

我编写了一个小型包装框架,它使用 Apache HTTP Commons lib 将我的门户应用程序与外部 REST API 连接起来。我创建了一个如下所示的层次结构(对于请求和响应——客户端是我在这里用来抽象我的实际最终客户端的术语)。

ClientRequest (abstract)
    BaseClientRequest (abstract)
        RequestA
        RequestB
        ...
        RequestN

我想要做的是用同样的响应来反映请求——

ClientResponse (abstract)
    BaseClientResponse (abstract)
        ResponseA
        ResponseB
        ...
        ResponseN

到目前为止,一切都很好。问题逼近。我创建了一个名为的实用程序类ClientServiceUtil,并实现了一个名为的方法,该方法post()接受一个ClientRequest参数,同样返回一个 ClientResponse类型。所有服务调用都使用相同的逻辑。我创建的模型甚至使用通用键值对作为参数,所以从技术上讲,我可以只使用基本级别的类,但它还处于早期阶段,我确信逻辑将开始因服务而异——因此具体实现.

在我的 post 方法中,我运行逻辑并作为流程的一部分,我创建一个ClientResponse对象来存储结果并返回它。现在的问题。

我有一个portlet。portlet 创建一个RequestA对象并用它调用ClientServiceUtil。它想要一个ResponseA响应,但它得到的是一个ClientResponse所以我有一个分配错误。

ResponseA response = ClientServiceUtil.post( new RequestA() );

...如果我尝试通过强制转换来解决这个问题,那么显然,我最终会遇到运行时强制转换异常

ResponseA response = (ResponseA)clientServiceUtil.post( new RequestA() );

现在我开始认为为每个请求重复服务调用逻辑(在我的 post 方法中找到)或将其拆分为部分调用等是我唯一的选择。我真的不想这样做,所以我希望那里的其他人对我有一个想法。

4

2 回答 2

0

您可以使用泛型,例如:

public <T, R extends ClientResponse<T>> R post(ClientRequest<T> request) {
    ...
}
于 2013-08-30T19:04:10.467 回答
0

我建议使用请求作为一种工厂来创建相关的响应。例子:

public interface ClientRequest {
    ...
    public ClientResponse createResponseInstance();
    ...
}

然后,在 ClientServiceUtil 中,

public ClientResponse post(ClientRequest req) {
    ...send the request...
    ClientResponse resp = req.createResponseInstance();
    ...initialize values in resp...
    return resp;
}

因此,如果您有以下情况:

public class RequestA extends BaseClientRequest {
    ...
    public ClientResponse createResponseInstance() {
        return new ResponseA();
    }
    ...
}

当 a作为参数传递时, thenpost()将返回一个ResponseA对象。RequestA

这使您可以安全地将响应转换为 ResponseA。

于 2013-08-30T19:17:14.687 回答