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