9 changed files with 222 additions and 1 deletions
-
2src/main/java/com/example/demo/DemoApplication.java
-
89src/main/java/com/example/demo/Util/ProductRemoteClient.java
-
6src/main/java/com/example/demo/controller/coin/GeneralController.java
-
29src/main/java/com/example/demo/domain/DTO/ProductDTO.java
-
11src/main/java/com/example/demo/mapper/coin/GeneralMapper.java
-
2src/main/java/com/example/demo/service/coin/GeneralService.java
-
48src/main/java/com/example/demo/serviceImpl/coin/GeneralServiceImpl.java
-
3src/main/resources/jindouMapper/BeanConsumeMapper.xml
-
33src/main/resources/mapper/GeneralMapper.xml
@ -0,0 +1,89 @@ |
|||||
|
package com.example.demo.Util; |
||||
|
|
||||
|
import com.example.demo.domain.DTO.ProductDTO; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.http.HttpStatus; |
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.web.client.ResourceAccessException; |
||||
|
import org.springframework.web.client.RestClientException; |
||||
|
import org.springframework.web.client.RestTemplate; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Objects; |
||||
|
import java.util.stream.Collectors; |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
@RequiredArgsConstructor |
||||
|
public class ProductRemoteClient { |
||||
|
|
||||
|
private final RestTemplate restTemplate; |
||||
|
|
||||
|
/** |
||||
|
* 获取远端全部商品(全量) |
||||
|
*/ |
||||
|
public List<ProductDTO> fetchAll() { |
||||
|
// 1. 去掉 url 尾部空格 |
||||
|
String url = "https://api.homilychart.com/live_mall/api/product/all"; |
||||
|
|
||||
|
// 2. 构造日志 |
||||
|
log.info("[ProductRemote] 开始拉取远端全量商品"); |
||||
|
|
||||
|
try { |
||||
|
// 3. 指定返回类型,避免 Map Raw Type 警告 |
||||
|
ResponseEntity<Map> resp = |
||||
|
restTemplate.getForEntity(url, Map.class); |
||||
|
|
||||
|
// 4. 状态码校验 |
||||
|
if (resp.getStatusCode() != HttpStatus.OK || resp.getBody() == null) { |
||||
|
throw new RuntimeException("远端返回异常,状态码:" + resp.getStatusCode()); |
||||
|
} |
||||
|
|
||||
|
// 5. 安全取值 |
||||
|
Object dataObj = resp.getBody().get("data"); |
||||
|
if (!(dataObj instanceof List)) { |
||||
|
throw new RuntimeException("远端 data 字段不是数组"); |
||||
|
} |
||||
|
|
||||
|
List<Map<String, Object>> data = (List<Map<String, Object>>) dataObj; |
||||
|
|
||||
|
// 6. 空数组直接返回,避免 NPE |
||||
|
if (data.isEmpty()) { |
||||
|
log.warn("[ProductRemote] 远端返回空数组"); |
||||
|
return Collections.emptyList(); |
||||
|
} |
||||
|
|
||||
|
// 7. 映射 + 空指针保护 |
||||
|
long now = System.currentTimeMillis(); |
||||
|
return data.stream() |
||||
|
.filter(Objects::nonNull) // 过滤 null 元素 |
||||
|
.map(m -> { |
||||
|
ProductDTO dto = new ProductDTO(); |
||||
|
dto.setId((Integer) m.get("id")); |
||||
|
dto.setName((String) m.get("name")); |
||||
|
dto.setCover((String) m.get("cover")); |
||||
|
Object priceObj = m.get("price"); |
||||
|
dto.setPrice(priceObj != null ? new BigDecimal(priceObj.toString()) : BigDecimal.ZERO); |
||||
|
dto.setUpdatedAt(now); |
||||
|
return dto; |
||||
|
}) |
||||
|
.collect(Collectors.toList()); |
||||
|
|
||||
|
} catch (ResourceAccessException e) { |
||||
|
// 网络/超时异常 |
||||
|
log.error("拉取商品失败,真实原因:", e); |
||||
|
throw new RuntimeException("拉取商品失败:" + e.getMessage(), e); |
||||
|
} catch (RestClientException e) { |
||||
|
// 4xx/5xx/解析异常 |
||||
|
log.error("[ProductRemote] 远端异常:{}", e.getMessage()); |
||||
|
throw new RuntimeException("拉取商品失败:远端返回异常", e); |
||||
|
} catch (Exception e) { |
||||
|
// 兜底 |
||||
|
log.error("[ProductRemote] 未知异常", e); |
||||
|
throw new RuntimeException("拉取商品失败:未知错误", e); |
||||
|
}} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
package com.example.demo.domain.DTO; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Data; |
||||
|
import lombok.NoArgsConstructor; |
||||
|
import org.apache.poi.hpsf.Decimal; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
/** |
||||
|
* @program: gold-java |
||||
|
* @ClassName ProductDTO |
||||
|
* @description: |
||||
|
* @author: Ethan |
||||
|
* @create: 2025−11-21 10:54 |
||||
|
* @Version 1.0 |
||||
|
**/ |
||||
|
|
||||
|
@Data |
||||
|
@AllArgsConstructor |
||||
|
@NoArgsConstructor |
||||
|
public class ProductDTO { |
||||
|
private Integer id; //id |
||||
|
private String name; //商品名 |
||||
|
private String cover; |
||||
|
private BigDecimal price; //价格 |
||||
|
private Long updatedAt; |
||||
|
private Long syncTime; //更新 |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue