I'm using Spring and Rest Template to access and get data json
this is my code:
@RequestMapping(value = "/api/v1/forecast", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<ReturnMessage> getForecast(@RequestParam Map<String, Object> params, ModelMap model) {
final Logger LOGGER = LoggerFactory.getLogger(ForecastController.class);
ReturnMessage message = new ReturnMessage();
RestTemplate restTemplate = new RestTemplate();
String url = "https://api.golde.gov";
System.out.println("loggg=======");
LOGGER.info("link part " + url);
HttpEntity<String> entity = new HttpEntity<String>(jsonObject.toString(), headers);
String result = restTemplate.postForObject(url, entity, String.class);
System.out.println(result);
return ResponseEntity.ok(message);
}
I have included a User-Agent header in my request but when i send to request to weather.gov to response an exception error:
org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: "<HTML><HEAD><EOL><TITLE>Access Denied</TITLE><EOL></HEAD><BODY><EOL><H1>Access Denied</H1><EOL> <EOL>You don't have permission to access "http://api.weather.gov/gridpoints/OKX/33,35/forecast" on this server.<P><EOL>Reference #18.177c2117.1685609346.4b1d971<EOL></BODY><EOL></HTML><EOL>"
at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:109) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:183) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:137) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:915) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:864) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:764) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:481) ~[spring-web-6.0.9.jar:6.0.9]
at com.forecast.veriserve.controller.ForecastController.getForecast(ForecastController.java:105) ~[classes/:na]
How to fix the problem ? many thank
One problem could be:
User-Agent: (myweatherapp.com, contact@myweatherapp.com)
..when reading the "Pricing" and "Authentication" sections.
I could reproduce the issue immediately with HTTP POST! (-> 403), so don't use that (unless API changes).
Here is the working mvc version with comments:
// import java.util.*, org.spr..fr..*
@RestController
static class WeatherController {
@Autowired
RestTemplateBuilder rtplB;
@GetMapping("/forecast")
public Map getForecast() {
// customize your api call(+response) from here:
HttpHeaders headers = new HttpHeaders();
headers.put("User-Agent",
List.of(UUID.randomUUID().toString(), // <- until API changes
"contact@my.funky.website.com")); // <- *your* contact, if you like
headers.setAccept(List.of(MediaType.valueOf("application/geo+json")));
HttpEntity<Void> ent = new HttpEntity<>(headers);
return rtplB
.build()
.exchange(
"https://api.weather.gov/gridpoints/OKX/33,35/forecast", // customize, parametrize, call dynamically
HttpMethod.GET, // <- POST works not well (->403), didn't try the others..
ent, // <- request headers (+ body)
Map.class // response type
/* , uriVars/... */
).getBody(); // <- returning ResponseEntity directly gave "strange" issues, "referencing" the body performs better (in browser).
}
}
Here the webflux version:
@Autowired
WebClient.Builder wcB;
@GetMapping("/forecast")
public Mono<Map> getForecast(/*...*/) {
return wcB.build()
.get()
.uri("https://api.weather.gov/gridpoints/OKX/33,35/forecast")
.headers(
h -> {
h.put("User-Agent", List.of(UUID.randomUUID().toString(), "contact@my.funky.website.com"));
h.setAccept(List.of(MediaType.valueOf("application/geo+json")));
}
)
.retrieve().bodyToMono(Map.class);
}
I had the "strange issues" (browser loading behavior) only on the mvc version, when directly returning resttemplate response, a "hold of the body" improves/fixes this. And a minimalist version:
return rtplB.build()
.getForObject(
"https://api.weather.gov/gridpoints/OKX/33,35/forecast",
Map.class
); // #
... "seems to work just fine".