
在现代应用开发中,从第三方API获取数据是常见需求。Spring框架的RestTemplate是一个强大的HTTP客户端,用于同步地进行RESTful服务调用。然而,获取到的数据往往需要进一步处理才能满足业务需求,例如过滤特定条件的数据、去除重复项,或者将原始数据结构转换为更符合内部API或前端展示的格式。
假设我们通过RestTemplate获取了一个包含省份信息的JSON数据,并将其映射到Provinces和ProvincesData等Java对象。原始数据可能包含重复的省份代码(CODPROV)或自治社区代码(CODAUTON),并且我们可能希望只保留不重复的自治社区信息,甚至将这些信息以自定义的字段名呈现。直接操作原始的List<ProvincesData>对象进行过滤和转换,需要一种高效且可读性强的方式。
首先,我们定义了用于映射API响应的Java类:Provinces作为顶层容器,ProvincesData包含具体的省份信息。
// Provinces.java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Provinces {
@JsonProperty("provincial")
private List<ProvincesData> provinces;
public Provinces() {}
public Provinces(List<ProvincesData> provinces) {
this.provinces = provinces;
}
@JsonProperty("provincial")
public List<ProvincesData> getProvinces() { // 注意:方法名已修正为标准Java Bean规范
return provinces;
}
// 注意:原始问题中setter带有 @JsonProperty("Test"),这可能导致非预期行为。
// 在实际开发中,如果JSON字段名为"provincial",则setter不应有不同的@JsonProperty。
// 此处为演示目的,假设setter对应的是"provincial"或无特定注解。
public void setProvinces(List<ProvincesData> provinces) { // 方法名已修正
this.provinces = provinces;
}
}// ProvincesData.java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ProvincesData {
@JsonProperty("CODPROV")
private String codProv;
@JsonProperty("NOMBRE_PROVINCIA")
private String nomeProvincia;
@JsonProperty("CODAUTON")
private String codAuton;
@JsonProperty("COMUNIDAD_CIUDAD_AUTONOMA")
private String comunidadeCidadeAutonoma;
public ProvincesData() {}
public ProvincesData(String codProv, String nomeProvincia, String codAuton, String comunidadeCidadeAutonoma) {
this.codProv = codProv;
this.nomeProvincia = nomeProvincia;
this.codAuton = codAuton;
this.comunidadeCidadeAutonoma = comunidadeCidadeAutonoma;
}
@JsonProperty("CODPROV")
public String getCodProv() {
return codProv;
}
// 注意:原始问题中setter带有 @JsonProperty("Test"),此处修正为标准setter。
public void setCodProv(String codProv) {
this.codProv = codProv;
}
@JsonProperty("NOMBRE_PROVINCIA")
public String getNomeProvincia() {
return nomeProvincia;
}
public void setNomeProvincia(String nomeProvincia) {
this.nomeProvincia = nomeProvincia;
}
@JsonProperty("CODAUTON")
public String getCodAuton() {
return codAuton;
}
public void setCodAuton(String codAuton) {
this.codAuton = codAuton;
}
@JsonProperty("COMUNIDAD_CIUDAD_AUTONOMA")
public String getComunidadeCidadeAutonoma() {
return comunidadeCidadeAutonoma;
}
public void setComunidadeCidadeAutonoma(String comunidadeCidadeAutonoma) {
this.comunidadeCidadeAutonoma = comunidadeCidadeAutonoma;
}
}接下来是RestTemplate的调用以及服务层和控制器层的基本结构:
// Templates.java (或一个工具类)
import org.springframework.web.client.RestTemplate;
public class Templates {
public static Provinces restTemplateProvince(RestTemplate restTemplate) {
String ProvinceCommunityURL = "https://www.el-tiempo.net/api/json/v2/provincias";
Provinces province = restTemplate.getForObject(ProvinceCommunityURL, Provinces.class);
return province;
}
}
// ProvinceService.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class ProvinceService {
@Autowired
private RestTemplate restTemplate; // 确保 RestTemplate 已在配置中定义为 Bean
public Provinces getAllProvinces() {
Provinces listOfProvinces = Templates.restTemplateProvince(restTemplate);
return listOfProvinces;
}
}
// ShowcaseController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ShowcaseController {
@Autowired
private ProvinceService provinceService;
@GetMapping("/provinces")
public Provinces getAllProvinces() {
return provinceService.getAllProvinces();
}
}我们的目标是过滤掉ProvincesData列表中codAuton重复的项,只保留每个codAuton的第一个出现实例。这可以通过Java Stream API结合一个辅助集合来实现。
修改Templates.restTemplateProvince方法,在获取到原始数据后立即进行过滤:
// Templates.java (更新后的版本)
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Templates {
public static Provinces restTemplateProvince(RestTemplate restTemplate) {
String ProvinceCommunityURL = "https://www.el-tiempo.net/api/json/v2/provincias";
Provinces province = restTemplate.getForObject(ProvinceCommunityURL, Provinces.class);
// 如果获取到的数据或其内部列表为空,则直接返回
if (province == null || province.getProvinces() == null) {
return new Provinces(new ArrayList<>()); // 返回一个空的Provinces对象
}
List<String> includedCodAutons = new ArrayList<>(); // 用于跟踪已包含的codAuton
List<ProvincesData> filteredProvinces = province.getProvinces()
.stream()
.filter(p -> {
// 如果 includedCodAutons 中已包含当前 codAuton,则过滤掉
if (includedCodAutons.contains(p.getCodAuton())) {
return false;
} else {
// 否则,将其添加到 includedCodAutons 并保留该元素
includedCodAutons.add(p.getCodAuton());
return true;
}
})
.collect(Collectors.toList());
// 将过滤后的列表设置回 Provinces 对象
province.setProvinces(filteredProvinces);
return province;
}
}代码解析:
注意事项:
仅仅过滤去重可能不足以满足所有需求。有时我们还需要将数据转换为一个全新的结构,例如只包含特定字段、字段名称不同,或者完全映射为List<String>。
假设我们希望最终API返回的数据是一个包含自治社区代码和名称的简化列表,并且字段名更具可读性。我们可以定义一个新的DTO(Data Transfer Object)来表示这种简化结构。
// SimplifiedCommunityInfo.java
public class SimplifiedCommunityInfo {
private String communityCode;
private String communityName;
public SimplifiedCommunityInfo(String communityCode, String communityName) {
this.communityCode = communityCode;
this.communityName = communityName;
}
// Getters and Setters
public String getCommunityCode() {
return communityCode;
}
public void setCommunityCode(String communityCode) {
this.communityCode = communityCode;
}
public String getCommunityName() {
return communityName;
}
public void setCommunityName(String communityName) {
this.communityName = communityName;
}
}现在,我们可以在ProvinceService中对从Templates.restTemplateProvince获取到的数据进行进一步的转换:
// ProvinceService.java (更新后的版本,包含转换逻辑)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ProvinceService {
@Autowired
private RestTemplate restTemplate;
// 返回原始Provinces对象(已过滤)
public Provinces getFilteredProvinces() {
return Templates.restTemplateProvince(restTemplate);
}
// 返回自定义DTO列表
public List<SimplifiedCommunityInfo> getSimplifiedCommunityInfo() {
Provinces filteredProvinces = Templates.restTemplateProvince(restTemplate);
if (filteredProvinces == null || filteredProvinces.getProvinces() == null) {
return List.of(); // 返回空列表
}
return filteredProvinces.getProvinces()
.stream()
.map(p -> new SimplifiedCommunityInfo(p.getCodAuton(), p.getComunidadeCidadeAutonoma()))
.collect(Collectors.toList());
}
// 如果需要返回 List<String>
public List<String> getCommunityNamesAsStringList() {
Provinces filteredProvinces = Templates.restTemplateProvince(restTemplate);
if (filteredProvinces == null || filteredProvinces.getProvinces() == null) {
return List.of(); // 返回空列表
}
return filteredProvinces.getProvinces()
.stream()
.map(p -> p.getComunidadeCidadeAutonoma() + " (" + p.getCodAuton() + ")")
.collect(Collectors.toList());
}
}相应的,ShowcaseController也需要更新以调用新的服务方法并返回期望的类型:
// ShowcaseController.java (更新后的版本)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class ShowcaseController {
@Autowired
private ProvinceService provinceService;
@GetMapping("/provinces/filtered")
public Provinces getFilteredProvinces() {
return provinceService.getFilteredProvinces();
}
@GetMapping("/provinces/simplified")
public List<SimplifiedCommunityInfo> getSimplifiedCommunityInfo() {
return provinceService.getSimplifiedCommunityInfo();
}
@GetMapping("/provinces/names")
public List<String> getCommunityNames() {
return provinceService.getCommunityNamesAsStringList();
}
}代码解析:
通过本文,我们学习了如何利用RestTemplate获取外部API数据,并结合Java Stream API对数据进行高效的过滤、去重和转换。
关键点总结:
进一步的考虑:
以上就是使用RestTemplate获取并处理API数据:过滤、去重与自定义转换的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号