泛型方法的简单应用

一、一个常见场景

有时候 我们的系统需要对接第三方的系统,其返回一般都会有一个比较统一的格式,如下所示:

{
	code : ...,
	message : ...,
	data : ...
}

具体返回的数据,可能是这样的:

{
	code : 0,
	message : success,
	data : {
		userId : "001",
		userName : "nep"
	}
}
{
	code : 0,
	message : success,
	data :
	[
	{
		bookNum : "XCN003",
		bookName : "小说",
		price : 29.9
	}

	{
		bookNum : "XCN004",
		bookName : "诗歌",
		price : 69.9
	}

	]
}

观察data部分,可以看到,最外层json 格式是固定的,而data里边的数据,是每个接口返回是不同的。
那么,对于数据的返回类型的构建,顺理成章地成了这样:

首先,data部分的实体类 User、Book

public class User{
	private String userId;
	private String userName;

	// get、set
}

public class Book{
	private String bookNum;
	private String bookName;
	private BigDecimal price;

	// get、set
}

然后就是最外层:

  • 公共的基类
public class AppHttpResponse {

    private String code;
    private String message;

	// get、set
}
  • 里层data,根据接口类型来
//第一个接口,查询user的
QueryUserResponse extends AppHttpResponse{

	private User data;

	// get、set
}

//第二个接口,查询book的
QueryBookResponse extends AppHttpResponse{
	private List<Book> data;

	// get、set
}

现在,我们需要一个请求方法。在springboot工程中,我们可以这样写:

// 这是公共的请求方法
@Component
public class AppHttpClient {

	@Value("${http.baseUrl}")
	private String baseUrl;

    public String sendPostRequest(String code,Map<String, Object> params){

		// 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

		// 构建请求体(参数)
		MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        for (Map.Entry entry : params.entrySet()) {
            multiValueMap.add(entry.getKey().toString(),entry.getValue());
        }

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multiValueMap, headers);

		// 请求类型。这里用 post 请求
		HttpMethod method = HttpMethod.POST;

		RestTemplate client = new RestTemplate();
        ResponseEntity<String> response = client.exchange(baseUrl + code, method, requestEntity,String.class);

        return response.getBody();
    }

}

然后,在controller中的调用:

controller{

	Map<String,Object> params_queryUser = new HashMap();
	params_queryUser.put("userId", "1");

	String result = client.sendPostRequest("queryUser",params_queryUser);

	// 转换
	QueryUserResponse queryUserResponse = JSON.parseObject(result,QueryUserResponse.class);




	Map<String,Object> params_queryBook = new HashMap();
	params_queryBook.put("bookNum", "1");

	String result2 = client.sendPostRequest("queryBook",params_queryBook);

	// 转换
	QueryBookResponse queryBookResponse = JSON.parseObject(result2,QueryBookResponse.class);

}

二、使用泛型,优化代码

上面的代码其实也没什么问题,功能上都ok。但是,这里数据获取与数据转换,分为了2步。我们知道,代码讲求简洁高效,那么能不能一步到位呢?我们将“获取数据”与“转化数据”合成一个整体,获取来的数据直接转化为对应的数据类型。这里可以考虑使用泛型。下面看代码:

// 修改统一请求方法,直接返回对应数据类型
@Component
public class AppHttpClient {

	@Value("${http.baseUrl}")
	private String baseUrl;

    public <T>T sendPostRequest(String code,Map<String, Object> params, Class<T> clz){

		// 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

		// 构建请求体(参数)
		MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        for (Map.Entry entry : params.entrySet()) {
            multiValueMap.add(entry.getKey().toString(),entry.getValue());
        }

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multiValueMap, headers);

		// 请求类型。这里用 post 请求
		HttpMethod method = HttpMethod.POST;

		RestTemplate client = new RestTemplate();
        ResponseEntity<String> response = client.exchange(baseUrl + code, method, requestEntity,String.class);

		// 根据 clz 转换成对应类,并返回
        T t = JSON.parseObject(response.getBody(),clz);

        return t;
    }

}

其实,最后一步转化 JSON.parseObject 可以省掉,RestTemplate提供类似方法,如下:

@Component
public class AppHttpClient {

	@Value("${http.baseUrl}")
	private String baseUrl;

    public <T>T sendPostRequest(String code,Map<String, Object> params, Class<T> clz){

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity requestEntity = new HttpEntity<>(params, headers);

		RestTemplate client = new RestTemplate();
		T t = client.postForObject(gridUrl+code,requestEntity,clz);

        return t;
    }

}

再看controller中的代码,是不是简洁清晰了点呢

controller{

	Map<String,Object> params_queryUser = new HashMap();
	params_queryUser.put("userId", "1");

	QueryUserResponse queryUserResponse = client.sendPostRequest("queryUser",params_queryUser,QueryUserResponse.class);

	Map<String,Object> params_queryBook = new HashMap();
	params_queryBook.put("bookNum", "1");

	QueryBookResponse queryBookResponse = client.sendPostRequest("queryBook",params_queryBook,QueryBookResponse.class);

}

三、泛型方法

简单了解下泛型方法的定义:

public <T>T method(Class<T> clz){
	T t = clz.newInstance();
	return t;
}

这里 T 即代表所传入的 clz 。泛型方法的入参中,必有一个Class clz。方法的返回类型为T,且前面带有,是不可少的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值