[Stream]使用Stream巧妙地拼接url参数

在使用第三方 API 的时候,总是会需要在 url 后面拼接一些请求参数,也就是 ? 符号后面的一串键值对。

看一个具体的例子,比如说要使用高德地图的 api,需要拼接一些参数,比如说出发地 orgin,目的地 destination 的经纬度等参数,在代码中最直接的拼接方法如下:

```java String url = "https://restapi.amap.com/v3/direction/driving" StringBuilder sb = new StringBuilder(); sb.append("?").append("orgin").append("=").append(depLongitude).append(",").append(depLatitude) .append("destination").append("=")..append(destLongitude).append(",").append(destLatitude);

// 下面省略一堆参数拼接...

```

如果使用 StringBuilder 傻瓜式拼接就会导致代码写得非常臃肿,而且如果以后有新的条件那么拼接的代码就会更多,非常不优雅,非常丑陋。所以,需要一个优化的办法。

下面介绍使用 Stream API 来优化参数拼接:

使用一个 Map 来存放查询的参数,使用 @Value 注解来获取编写在 yml 文件中的值,然后让 Map 调用 entrySet 方法之后再转为 Stream。这其中的每一项就是 entry,然后把 entry 通过 map 方法转为 k=v 的形式,这一步完成之后 Stream 中的元素就是一堆字符串集合,最终使用 joining 方法传入参数 & 符号将它们拼接到一起,就得到了查询的参数。

最后一步,就是把原始的第三方 api 和查询参数拼接,中间用 ? 符号分隔。

```java @Service public class MapService {

// https://restapi.amap.com/v3/config/district?keywords=%E5%8D%97%E4%BA%AC&subdistrict=2
@Value("${system.map.path-api}")
private String districtUrl;

@Value("${system.map.key}")
private String userKey;

@Autowired
private RestTemplate restTemplate;


public DirectionResponse direction(String depLongitude, String depLatitude, String destLongitude,
                                   String destLatitude) {
    Map<String, String> conditions = new HashMap<String, String>() {
    
    {
        put("origin", depLongitude + "," + depLatitude);
        put("destination", destLongitude + "," + destLatitude);
        put("key", userKey);
    }};

    String s = conditions.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(joining("&"));
    String url = mapUrl + "?" + s;
    log.info("调用的接口地址: {}", url);

    // 调用高德接口
    ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
    log.info("高德地图路径规划返回信息: {}", response.getBody());

    // 解析接口
    return parseDirectionEntity(response.getBody());
}

} ```

为了方便以后调用,可以封装一个工具类:

```java /** * URL工具类 */ public class UrlUtil {

/**
 * 根据条件拼装url
 * @param api        基准的api地址
 * @param conditions 存放查询条件的map
 * @return 最终的api地址
 */
public static String createQueryParameters(String api, Map<String, String> conditions) {
    String params = conditions.entrySet()
                              .stream()
                              .map(e -> e.getKey() + "=" + e.getValue())
                              .collect(Collectors.joining("&"));
    return api + "?" + params;
}

} ``` 这样就不用写一堆 StringBuilder 的拼接代码了,非常丑陋。高手和菜鸟区别就在这里。

猜你喜欢

转载自blog.csdn.net/weixin_45254062/article/details/129665158
今日推荐