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);
    }

}

 

posted @ 2018-06-06 16:12  Garcia11  阅读(1271)  评论(0)    收藏  举报