springMvc使用client实现服务之间的调用
在做项目的时候,发现别人编写服务框架的时候创建了client来实现服务之间的相互调用,这样就不用导入其他项目的jar包。分析了下其实底层还是使用的restTemplate,不过人家封装的比较好,放到这里分析下。
调用其他服务
public abstract class ApiHandler<T> { private String api; //要调用的uri的api地址 private String requestUrl; //请求地址:serverUrl+api private TypeReference<BaseResponse<T>> responseType; //返回的响应类型
//构造函数为api和responseType赋值 public ApiHandler(String api, TypeReference<BaseResponse<T>> responseType) { Assert.notNull(responseType); if (StringUtils.isEmpty(api)) { throw new IllegalArgumentException("api不能为空"); } else { this.api = api; this.responseType = responseType; } } public void setServerUrl(String serverUrl) { if (StringUtils.isEmpty(serverUrl)) { throw new IllegalArgumentException("serverUrl不能为空"); } else { this.requestUrl = serverUrl + this.api; } }
//CheckableParameter为所有request都需要实现的接口,其内部只有一个check()方法,所有的request类都需要实现check()方法用来判断request
//请求是否合理,如果合理则发送post请求 protected String postForStringResult(CheckableParameter request) throws ClientException { request.check(); return (String)RestTemplateUtil.post(this.requestUrl, request, String.class); }
//使用Jackson对返回的相应转换为想要的responseType类型,外层用BaseResponse包一层 protected BaseResponse<T> postForBaseResponse(CheckableParameter request) throws ClientException { String strResponse = this.postForStringResult(request); try { return (BaseResponse)JacksonUtil.fromJson(strResponse, this.responseType); } catch (CommonException var4) { throw new ClientException("解析返回值发生错误", var4); } }
//使用Jackson对返回的相应转换为想要的responseType类型,外层没有用BaseResponse包装 protected T post(CheckableParameter request) throws ClientException { BaseResponse<T> response = this.postForBaseResponse(request); if (!response.isSuccessful()) { throw new ClientException("接口返回结果为失败,信息:" + response.getMessage()); } else { return response.getBody(); } } }
具体的使用类:
public class ImagesDownloadPiccHandler extends ApiHandler<ImagesDownloadPiccResponse> { private static final String API = "/v345/piccdata/piccimagesdownload"; public ImagesDownloadPiccHandler() { super(API, new TypeReference<BaseResponse<ImagesDownloadPiccResponse>>() { }); } public ImagesDownloadPiccResponse handle(ImagesDownloadPiccRequst imagesDownloadPiccRequst) throws ClientException { CheckableParameter request = getRequest(imagesDownloadPiccRequst); return post(request); }
//将request对象转换为接口类型,以方便ApiHandler中进行多态的使用 private CheckableParameter getRequest(ImagesDownloadPiccRequst imagesDownloadPiccRequst) { return imagesDownloadPiccRequst; } }
自己提供Client供其他服务调用:主要就是自己提供一个Handler接口,使得其他服务可以通过此接口调用ApiHandler的post方法向自己发送请求。
public class BusinessClient { private Map<Class, ApiHandler> map = new HashMap(); private String serverUrl; public BusinessClient() { } public void setServerUrl(String serverUrl) { this.serverUrl = serverUrl; } protected <T extends ApiHandler> T getHandler(Class<T> handlerClass) throws ClientException { Assert.notNull(this.serverUrl); try { T handler = (ApiHandler)this.map.get(handlerClass); if (handler == null) { handler = (ApiHandler)handlerClass.newInstance();//如果map中没有存储Handler实例就使用反射实例化一个Handler handler.setServerUrl(this.serverUrl); this.map.put(handlerClass, handler); } return handler; } catch (Exception var3) { throw new ClientException("找不到消息处理器", var3); } } }
public class PiccDataTempClient extends BusinessClient { public ImagesDownloadAliyunResponse downloadImagesFromAliyun(ImagesDownloadAliyunRequest imagesDownloadAliyunRequest) throws ClientException { return getHandler(ImagesDownloadAliyunHandler.class).handle(imagesDownloadAliyunRequest); } }

浙公网安备 33010602011771号