当前位置: 首页 > news >正文

第三方接口请求

实体类 

package com.yu.cloudpicturebackend.model.entity;import lombok.Data;import java.io.Serializable;@Data
public class DailyWord implements Serializable {private static final long serialVersionUID = 2539265557480005492L;private String content;private String author;
}

服务层 Service

package com.yu.cloudpicturebackend.service;import com.yu.cloudpicturebackend.model.entity.DailyWord;import java.util.List;public interface ThirdPartyService {/*** 获取每日一句*/List<DailyWord> getDailyWord(Integer count);}

服务层 ServiceImpl

package com.yu.cloudpicturebackend.service.impl;import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yu.cloudpicturebackend.exception.BusinessException;
import com.yu.cloudpicturebackend.exception.ErrorCode;
import com.yu.cloudpicturebackend.model.entity.DailyWord;
import com.yu.cloudpicturebackend.service.ThirdPartyService;
import com.yu.cloudpicturebackend.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;@Service
@Slf4j
public class ThirdPartyServiceImpl implements ThirdPartyService {@Resourceprivate RestTemplate restTemplate;@Resourceprivate RedisUtil redisUtil;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Value("${thirdParty.appId}")private String appId;@Value("${thirdParty.appSecret}")private String appSecret;@Value("${thirdParty.dailyWordUrl}")private String baseUrl;private static final String REDIS_KEY = "daily_word";@Overridepublic List<DailyWord> getDailyWord(Integer count) {try {// 参数验证if (count < 1 || count > 20) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "count参数范围应为1-20");}// 使用 UriComponentsBuilder 安全构建URLString url = UriComponentsBuilder.fromHttpUrl(baseUrl).queryParam("count", count).queryParam("app_id", appId).queryParam("app_secret", appSecret).toUriString();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);HttpEntity<String> entity = new HttpEntity<>(headers);// 优先从缓存获取List<DailyWord> dailyWords = getFromRedis(REDIS_KEY);if (dailyWords != null) {log.info("从 redis 缓存获取每日一句数据");return dailyWords;}// 发送请求ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);log.info("每日一句接口调用成功,响应体: {}", response.getBody());// 解析响应体String body = response.getBody();JSONObject jsonObject = JSONUtil.parseObj(body);int code = (int) jsonObject.get("code");JSONArray jsonArray = jsonObject.getJSONArray("data");dailyWords = JSONUtil.toList(jsonArray, DailyWord.class);List<DailyWord> words = dailyWords.stream().map(dailyWord -> {DailyWord word = new DailyWord();word.setContent(dailyWord.getContent());word.setAuthor(StrUtil.isBlank(dailyWord.getAuthor()) ? "佚名" : dailyWord.getAuthor());return word;}).collect(Collectors.toList());// 数据存入 redissaveWithDailyExpire(REDIS_KEY, JSONUtil.toJsonStr(words));if (code == 1) {return words;} else {throw new BusinessException(ErrorCode.TOO_MANY_REQUEST);}} catch (Exception e) {log.error("调用每日一句接口失败: ", e);throw new BusinessException(ErrorCode.SYSTEM_ERROR, "请求第三方接口失败: " + e.getMessage());}}/*** 从 redis 获取数据** @param key* @return*/private List<DailyWord> getFromRedis(String key) {String jsonStr = stringRedisTemplate.opsForValue().get(key);if (StrUtil.isNotBlank(jsonStr)) {return JSONUtil.toList(jsonStr, DailyWord.class);}return null;}/*** 存储数据并设置过期时间为当天24点*/private void saveWithDailyExpire(String key, String value) {try {stringRedisTemplate.opsForValue().set(key, value);// 设置过期时间为当天24点long expireSeconds = getSecondsUntilMidnight();stringRedisTemplate.expire(key, expireSeconds, TimeUnit.SECONDS);log.info("存储数据成功, key: {}, 过期时间: {}秒后", key, expireSeconds);} catch (Exception e) {log.error("存储数据失败, key: {}, 错误: {}", key, e.getMessage());}}/*** 计算当前时间到当天24点的秒数*/private long getSecondsUntilMidnight() {LocalDateTime now = LocalDateTime.now();LocalDateTime midnight = now.toLocalDate().atTime(23, 59, 59).plusSeconds(1); // 次日00:00:00return Duration.between(now, midnight).getSeconds();}}

接口层 Controller

package com.yu.cloudpicturebackend.controller;import com.yu.cloudpicturebackend.common.ResultUtils;
import com.yu.cloudpicturebackend.exception.BaseResponse;
import com.yu.cloudpicturebackend.model.entity.DailyWord;
import com.yu.cloudpicturebackend.service.ThirdPartyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;@RestController
@RequestMapping("/thirdParty")
@Api(tags = "第三方接口")
@Slf4j
public class ThirdPartyController {@Resourceprivate ThirdPartyService thirdPartyService;/*** 获取每日一句*/@GetMapping("/dailyWord")@ApiOperation("每日一句")public BaseResponse<?> getDailyWord(@RequestParam(defaultValue = "1") Integer count) {List<DailyWord> dailyWords = thirdPartyService.getDailyWord(count);return ResultUtils.success(dailyWords);}
}
http://www.dtcms.com/a/561765.html

相关文章:

  • 个人网站做装修可以吗网页游戏网站排名
  • C语言字符串及其函数
  • 网站设计公司-信科网络有什么免费建网站
  • Nestjs框架: 微服务容器化部署与网络通信解决方案
  • 北京网络网站建设公司手机必备app
  • 苏州网站建设公司电话网站无法连接mysql
  • 五.docker环境搭建实例
  • 网工错题笔记
  • 龙之向导外贸网站集团公司手机站网站
  • 电商网站竞价推广策略财务网站建设
  • spring boot 启动过程
  • SpringCloud——Docker基础
  • 计算机网络自顶向下方法27——运输层 拥塞控制原理 拥塞原因与代价及控制方法
  • 佛山茶叶网站建设网站上线流程图
  • 第四天学习总结:C++ 文件系统 × Linux 自动化 × Makefile 工程化
  • 闸北区网站设计网站建设的分项报价
  • 分治思想用于SAT求解的应用(ToSC2025-3)
  • 深圳自助网站建设去国外做外卖网站好
  • C++ 多线程与 Linux 进程创建详解
  • 【C语言基础案例】经典C语言程序设计100例附源码解析(91-100例)
  • 子目录创建网站wordpress html5视频播放插件
  • 武夷山网站设计沈阳网站seo排名优化
  • 湘潭市建设路学校网站拍卖网站功能需求文档
  • 优秀北京网站建设深圳龙华区龙华街道高坳新村
  • 计算机网络自顶向下方法26——运输层 SYN洪泛攻击 SYNCookie
  • 【RL】以信息熵的角度理解RL
  • linux下讲解基础IO
  • 乌兰察布网站建设桂林漓江图片高清
  • Docker革命:软件开发的集装箱时代
  • 北京移动官网网站建设商务网站建设注意事项