如何在没有共享接口的情况下处理等效对象
How to handle equivalent objects without a shared interface
我有一段代码想概括,但我不确定如何实现。
我的程序处理许多具有相同 getter/setter 但不共享接口的 JAXBElement 类,并且在将它们发送到 Web 服务之前需要设置 属性。
类 相同类型的数量在不久的将来可能会增加。
这可以通过泛型泛化吗?还是我需要动态代理?
public class ServiceClient1 {
public Response getResponse(ReqObject1 req1) {
req1.getValue().setConfig("john","doe");
return client.target(endpoint).request(MediaType.TEXT_XML).post(Entity.entity(req1, MediaType.TEXT_XML);
}
public RespObject1 readResponse(Response resp1) {
return resp1.readEntity(RespObject1.class);
}
}
变成类似
的东西
public class ServiceClient {
public <T> Response getResponse(T req) {
req.getValue().setConfig("john","doe");
return client.target(endpoint).request(MediaType.TEXT_XML).post(Entity.entity(req, MediaType.TEXT_XML);
}
public <T> T readResponse(Response resp) {
return resp.readEntity(T.class);// ???
}
}
处理 getResponse()
选项 1:
如果您的请求 类 可以实现通用接口,则可以使用 Generics.
完全处理此方法
接口和类定义:
interface Configurable {
void setConfig(String s1, String s2);
}
public class Req1 implements Configurable {
@Override
public void setConfig(String s1, String s2) {
}
}
public class Req2 implements Configurable {
@Override
public void setConfig(String s1, String s2) {
}
}
getResponse() 实施:
public <T extends Configurable> Response getResponse(JAXBElement<T> req) {
req.getValue()
.setConfig("john", "doe");
return client.target(endpoint)
.request(MediaType.TEXT_XML)
.post(Entity.entity(req, MediaType.TEXT_XML));
}
注意: 根据您的示例,看起来输入参数始终是 JAXBElement
.
类型
选项 2:
如果您无法让所有请求 类 实现 Configurable
,我们需要使用反射来泛化该方法。
public Response getResponse(JAXBElement<?> req) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object instance = req.getValue();
Method m = instance.getClass()
.getMethod("setConfig", String.class, String.class);
m.invoke(instance, "john", "doe");
return client.target(endpoint)
.request(MediaType.TEXT_XML)
.post(Entity.entity(req, MediaType.TEXT_XML));
}
注意:为了简洁起见,我已经让方法重新抛出异常。我们可以使用自定义异常并适当处理它。
处理 readResponse()
此方法完全可以使用 泛型 处理。只需要为 return 类型再传递 1 个参数。
public <T> T readResponse(Response response, Class<T> cls) {
return response.readEntity(cls);
}
谢谢普拉萨纳。
反射解决方案可能是实现共享接口的包装器 类 的一个很好的替代方案。
我有一段代码想概括,但我不确定如何实现。 我的程序处理许多具有相同 getter/setter 但不共享接口的 JAXBElement 类,并且在将它们发送到 Web 服务之前需要设置 属性。 类 相同类型的数量在不久的将来可能会增加。 这可以通过泛型泛化吗?还是我需要动态代理?
public class ServiceClient1 {
public Response getResponse(ReqObject1 req1) {
req1.getValue().setConfig("john","doe");
return client.target(endpoint).request(MediaType.TEXT_XML).post(Entity.entity(req1, MediaType.TEXT_XML);
}
public RespObject1 readResponse(Response resp1) {
return resp1.readEntity(RespObject1.class);
}
}
变成类似
的东西public class ServiceClient {
public <T> Response getResponse(T req) {
req.getValue().setConfig("john","doe");
return client.target(endpoint).request(MediaType.TEXT_XML).post(Entity.entity(req, MediaType.TEXT_XML);
}
public <T> T readResponse(Response resp) {
return resp.readEntity(T.class);// ???
}
}
处理 getResponse()
选项 1:
如果您的请求 类 可以实现通用接口,则可以使用 Generics.
接口和类定义:
interface Configurable {
void setConfig(String s1, String s2);
}
public class Req1 implements Configurable {
@Override
public void setConfig(String s1, String s2) {
}
}
public class Req2 implements Configurable {
@Override
public void setConfig(String s1, String s2) {
}
}
getResponse() 实施:
public <T extends Configurable> Response getResponse(JAXBElement<T> req) {
req.getValue()
.setConfig("john", "doe");
return client.target(endpoint)
.request(MediaType.TEXT_XML)
.post(Entity.entity(req, MediaType.TEXT_XML));
}
注意: 根据您的示例,看起来输入参数始终是 JAXBElement
.
选项 2:
如果您无法让所有请求 类 实现 Configurable
,我们需要使用反射来泛化该方法。
public Response getResponse(JAXBElement<?> req) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object instance = req.getValue();
Method m = instance.getClass()
.getMethod("setConfig", String.class, String.class);
m.invoke(instance, "john", "doe");
return client.target(endpoint)
.request(MediaType.TEXT_XML)
.post(Entity.entity(req, MediaType.TEXT_XML));
}
注意:为了简洁起见,我已经让方法重新抛出异常。我们可以使用自定义异常并适当处理它。
处理 readResponse()
此方法完全可以使用 泛型 处理。只需要为 return 类型再传递 1 个参数。
public <T> T readResponse(Response response, Class<T> cls) {
return response.readEntity(cls);
}
谢谢普拉萨纳。 反射解决方案可能是实现共享接口的包装器 类 的一个很好的替代方案。