REST API 的目标天气 API 未在邮递员中返回 JSON 数据
Destination Weather API for REST API not returning JSON data in postman
我正在 java 中创建一个 REST API 并在邮递员和数据库中测试它有纬度和经度,我正在尝试使用 OpenWeather API 到 return 基于经纬度的天气数据。然而,当在邮递员中测试它时,它 returning 一个 HTML 而不是我请求的 JSON 数据。
我要测试的路径是
http://localhost:8080/Assignment2C/map/weather/4
我控制器中的代码是
@GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWeather(@PathVariable("id") int id) {
BreweriesGeocode geocode = geocode_service.getGeocode(id);
Breweries brewerie = breweries_service.getBrewerieById(id);
double latitude = geocode.getLatitude();
double longitude = geocode.getLongitude();
String output = "https://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&appid=4a1f5501b2798f409961c62d384a1c74";
return output;
使用 Postman 时,return是这个
https: //api.openweathermap.org/data/2.5/weather?lat=59.74509811401367&lon=10.213500022888184&appid=4a1f5501b2798f409961c62d384a1c74
但是当我测试 postman 在浏览器中生成的路径时
https://api.openweathermap.org/data/2.5/weather?lat=59.74509811401367&lon=10.213500022888184&appid=4a1f5501b2798f409961c62d384a1c74
它 return 是正确的 JSON 数据
也就是
{"coord":{"lon":10.21,"lat":59.75},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":291.36,"feels_like":289.49,"temp_min":288.71,"temp_max":294.26,"pressure":1028,"humidity":40},"wind":{"speed":0.89,"deg":190},"clouds":{"all":1},"dt":1587551663,"sys":{"type":3,"id":2006615,"country":"NO","sunrise":1587526916,"sunset":1587581574},"timezone":7200,"id":6453372,"name":"Drammen","cod":200}
如何在测试时让 JSON 数据出现在 postman 中?
我在 postman 中测试了 URL,它 returns 的响应是正确的。
检查下面的屏幕,也许您正在做一些不同的事情。
确保 url 中没有 space,我看到你在 Postman 中使用的 url 在“:”之后有 space
]
Postman 是 parsing/showing 正确的值,因为您在响应中发送 url。
要在您的代码中调用 API,您需要使用 HTTP Client/Handler。如果您只是将 URL 分配给一个变量,它只会将其存储为一个字符串,并且永远不会调用 given url。
RestTemplate class(默认情况下在 Spring 中可用,不需要其他依赖项)是一个简单的 HTTP 客户端,它允许 API 从您的代码中调用。
您可以使用 RestTemplate 调用 OpenWeather API 并获得 JSON 响应,可以返回相同的响应并在 Postman 中查看。
如果您确定只进行 HTTP 调用而不进行 HTTPS,则遵循方法 1,否则遵循方法 2 -
方法 1:
@RestController
public class WeatherController{
@Autowired
RestTemplate restTemplate;
@GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWeather(@PathVariable("id") int id) {
BreweriesGeocode geocode = geocode_service.getGeocode(id);
Breweries brewerie = breweries_service.getBrewerieById(id);
double latitude = geocode.getLatitude();
double longitude = geocode.getLongitude();
String url = "http://api.openweathermap.org/data/2.5/weather?lat="+latitude+"&lon="+longitude+"&appid=4a1f5501b2798f409961c62d384a1c74";
//Calling OpenWeather API
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
String output = response.getBody();
return output;
}
}
方法 2:
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class CustomRestTemplate {
/**
* @param isHttpsRequired - pass true if you need to call a https url, otherwise pass false
*/
public RestTemplate getRestTemplate(boolean isHttpsRequired)
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
// if https is not required,
if (!isHttpsRequired) {
return new RestTemplate();
}
// else below code adds key ignoring logic for https calls
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
}
然后在控制器中class你可以做如下-
@RestController
public class WeatherController{
@Autowired
CustomRestTemplate customRestTemplate;
@GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWeather(@PathVariable("id") int id) {
BreweriesGeocode geocode = geocode_service.getGeocode(id);
Breweries brewerie = breweries_service.getBrewerieById(id);
double latitude = geocode.getLatitude();
double longitude = geocode.getLongitude();
String url = "https://api.openweathermap.org/data/2.5/weather?lat="+latitude+"&lon="+longitude+"&appid=4a1f5501b2798f409961c62d384a1c74";
// Getting instance of Rest Template
// Passing true becuase the url is a HTTPS url
RestTemplate restTemplate = customRestTemplate.getRestTemplate(true);
//Calling OpenWeather API
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
String output = response.getBody();
return output;
}
}
如果响应代码不是成功代码,您可以为 RestTemplate 响应编写一个 Http 错误处理程序。
我正在 java 中创建一个 REST API 并在邮递员和数据库中测试它有纬度和经度,我正在尝试使用 OpenWeather API 到 return 基于经纬度的天气数据。然而,当在邮递员中测试它时,它 returning 一个 HTML 而不是我请求的 JSON 数据。
我要测试的路径是
http://localhost:8080/Assignment2C/map/weather/4
我控制器中的代码是
@GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWeather(@PathVariable("id") int id) {
BreweriesGeocode geocode = geocode_service.getGeocode(id);
Breweries brewerie = breweries_service.getBrewerieById(id);
double latitude = geocode.getLatitude();
double longitude = geocode.getLongitude();
String output = "https://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&appid=4a1f5501b2798f409961c62d384a1c74";
return output;
使用 Postman 时,return是这个
https: //api.openweathermap.org/data/2.5/weather?lat=59.74509811401367&lon=10.213500022888184&appid=4a1f5501b2798f409961c62d384a1c74
但是当我测试 postman 在浏览器中生成的路径时
https://api.openweathermap.org/data/2.5/weather?lat=59.74509811401367&lon=10.213500022888184&appid=4a1f5501b2798f409961c62d384a1c74
它 return 是正确的 JSON 数据
也就是
{"coord":{"lon":10.21,"lat":59.75},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":291.36,"feels_like":289.49,"temp_min":288.71,"temp_max":294.26,"pressure":1028,"humidity":40},"wind":{"speed":0.89,"deg":190},"clouds":{"all":1},"dt":1587551663,"sys":{"type":3,"id":2006615,"country":"NO","sunrise":1587526916,"sunset":1587581574},"timezone":7200,"id":6453372,"name":"Drammen","cod":200}
如何在测试时让 JSON 数据出现在 postman 中?
我在 postman 中测试了 URL,它 returns 的响应是正确的。
检查下面的屏幕,也许您正在做一些不同的事情。
确保 url 中没有 space,我看到你在 Postman 中使用的 url 在“:”之后有 space
]Postman 是 parsing/showing 正确的值,因为您在响应中发送 url。
要在您的代码中调用 API,您需要使用 HTTP Client/Handler。如果您只是将 URL 分配给一个变量,它只会将其存储为一个字符串,并且永远不会调用 given url。
RestTemplate class(默认情况下在 Spring 中可用,不需要其他依赖项)是一个简单的 HTTP 客户端,它允许 API 从您的代码中调用。
您可以使用 RestTemplate 调用 OpenWeather API 并获得 JSON 响应,可以返回相同的响应并在 Postman 中查看。
如果您确定只进行 HTTP 调用而不进行 HTTPS,则遵循方法 1,否则遵循方法 2 -
方法 1:
@RestController
public class WeatherController{
@Autowired
RestTemplate restTemplate;
@GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWeather(@PathVariable("id") int id) {
BreweriesGeocode geocode = geocode_service.getGeocode(id);
Breweries brewerie = breweries_service.getBrewerieById(id);
double latitude = geocode.getLatitude();
double longitude = geocode.getLongitude();
String url = "http://api.openweathermap.org/data/2.5/weather?lat="+latitude+"&lon="+longitude+"&appid=4a1f5501b2798f409961c62d384a1c74";
//Calling OpenWeather API
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
String output = response.getBody();
return output;
}
}
方法 2:
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class CustomRestTemplate {
/**
* @param isHttpsRequired - pass true if you need to call a https url, otherwise pass false
*/
public RestTemplate getRestTemplate(boolean isHttpsRequired)
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
// if https is not required,
if (!isHttpsRequired) {
return new RestTemplate();
}
// else below code adds key ignoring logic for https calls
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
}
然后在控制器中class你可以做如下-
@RestController
public class WeatherController{
@Autowired
CustomRestTemplate customRestTemplate;
@GetMapping(value = "weather/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWeather(@PathVariable("id") int id) {
BreweriesGeocode geocode = geocode_service.getGeocode(id);
Breweries brewerie = breweries_service.getBrewerieById(id);
double latitude = geocode.getLatitude();
double longitude = geocode.getLongitude();
String url = "https://api.openweathermap.org/data/2.5/weather?lat="+latitude+"&lon="+longitude+"&appid=4a1f5501b2798f409961c62d384a1c74";
// Getting instance of Rest Template
// Passing true becuase the url is a HTTPS url
RestTemplate restTemplate = customRestTemplate.getRestTemplate(true);
//Calling OpenWeather API
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
String output = response.getBody();
return output;
}
}
如果响应代码不是成功代码,您可以为 RestTemplate 响应编写一个 Http 错误处理程序。