Spring Boot 2关于http接口调用(6)

使用自定义HttpClientProxy

这里其实是参考FeignClient的功能,实现自己的代理包装类。因为FeignClient封装的太好,功能很强大,但是有时候想实现一点特殊的功能,改造起来很麻烦。

定义自己的FeignClient注解

@Target(TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface HttpClientEx {
    @AliasFor("hostName")
    String value() default "";

    /**
     * 主机名http://www.baidu.com
     *
     * @return
     */
    @AliasFor("value")
    String hostName() default "";

    /**
     * http请求数据组装
     *
     * @return
     */
    Class<HttpRequestBuilder> config() default HttpRequestBuilder.class;
}

定义自己的RequestMapping注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMappingEx {
    @AliasFor("name")
    String value() default "";

    /**
     * 接口名a/b/c
     *
     * @return
     */
    @AliasFor("value")
    String name() default "";

    /**
     * 请求方法
     *
     * @return
     */
    HttpMethod method() default HttpMethod.GET;

    /**
     * contentType
     *
     * @return
     */
    String contentType() default MediaType.APPLICATION_JSON_UTF8_VALUE;

    /**
     * 请求头a=b
     *
     * @return
     */
    String[] headers() default {};

    /**
     * 扩展参数a=b
     *
     * @return
     */
    String[] params() default {};
}

自定义HttpClientProxy,用于解析自定义的两个注解

public final class HttpClientProxy<T> implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Class clz = method.getDeclaringClass();
        if (clz != null) {
            HttpClientEx typeAnno = (HttpClientEx) (clz.getAnnotation(HttpClientEx.class));
            RequestMappingEx methodAnno = method.getAnnotation(RequestMappingEx.class);
            //......
        }
        return null;
    }
}	

自定义HttpClientFactory,通过Proxy构造一个实例

@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clz) throws IllegalArgumentException {
    return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[]{clz}, new HttpClientProxy<T>());
}

定义接口

@HttpClientEx(hostName = "http://localhost:9999")
public interface IHelloService {
    @RequestMappingEx(name = "demo/hello", method = HttpMethod.GET, headers = {"xxx=123"})
    HttpRspDTO<String> demoHello(@RequestParam(value = "msg") String msg);

    @RequestMappingEx(name = "demo/hello", method = HttpMethod.POST, headers = {"xxx=123"})
    HttpRspDTO<String> demoHello(@RequestBody Map<String, Object> reqMap);
}

单元测试

    @Test
    public void test1() {
        long begin = System.currentTimeMillis();

        IHelloService testService = HttpClientFactory.getBean(IHelloService.class);

        long end = System.currentTimeMillis();
        System.out.println("*****构造对象消耗时间(秒):" + (end - begin) / 1000.0);
        begin = System.currentTimeMillis();

        HttpRspDTO<String> rspDTO = testService.demoHello("张三");

        end = System.currentTimeMillis();
        System.out.println("*****查询数据消耗时间(秒):" + (end - begin) / 1000.0);
        System.out.println(rspDTO);

        begin = System.currentTimeMillis();
        Map<String, Object> paraMap = new HashMap<String, Object>();
        paraMap.put("msg", "这是一条测试数据");

        rspDTO = testService.demoHello(paraMap);
        end = System.currentTimeMillis();
        System.out.println("*****查询数据消耗时间(秒):" + (end - begin) / 1000.0);
        System.out.println(rspDTO);
    }

源码位置
https://gitee.com/ceclar123/spring-boot-demo/tree/master/ch01

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值