如何使用 SpringMVC 调用外部 API

How to call an external API with SpringMVC

我正在尝试创建一个 Spring MVC 网络应用程序,它通过从“https://api.weather.gov/points 调用外部 API 检查当前天气/{纬度},{经度}”。纬度和经度需要是您从 html 表单中获取的用户输入,将其传递到您的控制器,然后在您进行外部调用时使用该纬度和经度。 来自 api 调用的 json 包含网格点,这再次需要进行另一个外部 API 调用“https://api.weather.gov/gridpoints/{gridX },{gridY}/forecast”然后提取结果显示在前端。

我的 html 表格看起来像这样。(homepage.html)

    <div class="call-logs-info" id="call-logs-id">
    <div class="logs-container" id="logs-container-id">
        <form id="my-form" action="/getLatitude" method="post">
            <div class="date-content">
                <h1>Weather Checker</h1>

                <div class="columns">
                    <div class="col col-1">
                        <p>Latitude:</p>
                        <input type="text" class="inputbox" name="latitude" id="lat" />
                    </div>
                    <div class="col col-2">
                        <p>Longitude:</p>
                        <input type="text" class="inputbox" name="longitude" id="lon" />
                    </div>
                </div>

                <div class="columns">
                    <div class="col col-2">
                        <button class="btn btn-primary" type="submit">Submit</button>
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>

我有一个模型 class 看起来像这样。(Paths.java)

@Data
public class Paths {

    @SerializedName("latitude")
    public double latitude;

    @SerializedName("longitude")
    public double longitude;

}

我的@Controller class 从我调用 @RestController class 调用外部 API 看起来像 this.I 已经从中提取了纬度和经度class 使用 @ModelAttribute 并尝试将其传递给 getGridPoints() 方法。 (APIFetchController.java)

@Log4j2
@Controller
public class APIFetcherController {

    @Autowired
    private ExternalApiFetchController externalApiFetchController;

    @GetMapping("/home")
    public String showHomePage(){
                return "homepage";
    }



    @PostMapping("/getLatitude")
    public void formSubmit(@ModelAttribute Paths paths){
        Double latitude = paths.getLatitude();
        Double longitude = paths.getLongitude();
        log.info("Latitude: {}", latitude);
        log.info("Longitude: {}", longitude);
        externalApiFetchController.getGridPoints(latitude,longitude);
    }

    }

最后但同样重要的是,我尝试调用外部 API 的 @RestController class 看起来像这样。我已经尝试使用 restTempelate 来做到这一点。(ExternalApiFetchController.java)

@Log4j2
@RestController
public class ExternalApiFetchController {

    @GetMapping("/grids")
    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    public List<Object> getGridPoints(Double latitude, Double longitude) {
        log.info("Lat :{}", latitude);
        log.info("Long :{}", longitude);
        String url = "https://api.weather.gov/points/"+latitude + "," +longitude;
        log.info("URL: {}", url);

        RestTemplate restTemplate = new RestTemplate();
        Object[] grids = restTemplate.getForObject(url, Object[].class);

        return Arrays.asList(grids);
    }

出于某种原因,这会在尝试检查 Postman 时抛出一个错误

“无法从对象值(标记 JsonToken.START_OBJECT)反序列化类型 [Ljava.lang.Object; 的值”和其他一些错误。“

当我检查日志时,由于某种原因,从 Postman 中点击 API 后的纬度和经度值变为空值。

我知道这可以通过单独的前端完成,但我手头的任务是通过 springMVC 完成,我不知道这是否是完成任务的正确方法。现在任何帮助都是如此宝贵。

天气 API return 一个 json 对象作为结果。您告诉 spring 将其转换为对象数组。该错误指出您不能这样做,因为它期望 json 响应是 json 个对象的数组。

替换

Object[] grids = restTemplate.getForObject(url, Object[].class);

Object grid = restTemplate.getForObject(url, Object.class);

(https://www.weather.gov/documentation/services-web-api#/default/point)