我的Spring Boot应用程序无法正常运行。主要思想是用户选择他想知道温度的城市。温度值保存到txt文件中,城市名称作为文件名。然后我想安排Cron,因此,同一个城市的每个小时新温度值将保存到同一个文件中。目前一切正常,除了CronManager类。我不明白如何将城市名称传递给它。以下是我的代码部分:
ApplicationLoader
package com.boris2barak.samplemvc.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
public class ApplicationLoader extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ApplicationLoader.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(ApplicationLoader.class, args);
}
}
控制器
package com.boris2barak.samplemvc.app;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.IOException;
@Controller
public class myFirstController {
@RequestMapping("/hello")
public String hello(Model model, @RequestParam(value = "name", required = false, defaultValue = "World") String name) {
model.addAttribute("name", name);
return "hello";
}
@RequestMapping("/temperature")
public String whatIsTheTemperature(Model model, @RequestParam(value = "city", required = false, defaultValue = "World") String city) throws IOException {
model.addAttribute("city", city);
WeatherApp data = new WeatherApp();
return data.getTemperatureForCity(city);
}
}
WeatherApp
package com.boris2barak.samplemvc.app;
import com.google.gson.Gson;
import org.springframework.web.client.RestTemplate;
import java.io.*;
public class WeatherApp {
public String getTemperatureForCity(String city) throws IOException {
String URL = "http://api.openweathermap.org/data/2.5/weather?q="+city+"&APPID=9fff4e627587b84fca1ed835321da768";
RestTemplate restTemplate = new RestTemplate();
String json = restTemplate.getForObject(URL, String.class);
WeatherData weatherData = new Gson().fromJson(json, WeatherData.class);
////......... (here i have the code to get the other data like coordinates of the city, humidity, etc which is not relevant to my problem)
String theTemperature = weatherData.getTemperature();
FileManager myFile = new FileManager();
myFile.saveTheFile(theTemperature, city);
return theTemperature;
}
}
文件管理
package com.boris2barak.samplemvc.app;
import org.apache.commons.io.IOUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static org.apache.commons.io.IOUtils.toInputStream;
public class FileManager {
public void saveTheFile(String theTemperature, String cityName) throws IOException {
InputStream streamIn = toInputStream(theTemperature, "UTF-8");
OutputStream streamOut = new FileOutputStream(cityName + ".txt", true);
try {
IOUtils.copy(streamIn, streamOut);
} finally {
IOUtils.closeQuietly(streamIn);
IOUtils.closeQuietly(streamOut);
}
}
}
CronManager
package com.boris2barak.samplemvc.app;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class CronManager {
@Scheduled(cron = "0 * * ? * *")
public void cronTask() throws IOException {
WeatherApp data = new WeatherApp();
data.getTemperatureForCity(city <<<< how to instantiate this??);
}
}
我已经有2天时间试图解决这个问题了。非常感谢你的帮助!
问题解决了。这是答案: https://stackoverflow.com/a/45287683/8258820
答案 0 :(得分:0)
@Component
public class CronManager {
private Set<String> cities = new HashSet();// or CopyOnWriteArraySet/ConcurrentSkipListSet
public void addCity(String cityName){
cities.add(cityName);
}
@Scheduled(cron = "0 * * ? * *")
public void cronTask() throws IOException {
//iterate cities and execute logic in parallel no not block
WeatherApp data = new WeatherApp();
data.getTemperatureForCity(city <<<< how to instantiate this??);
}
}
将CronManager作为一个组件注入服务/控制器,并在添加新城市时将新城市添加到CronManager.cities中。如果你需要停止写城市温度,只需将其从城市集中删除即可。更好地创建一个新的组件CityHolder并将城市合二为一,在这种情况下,您需要将其注入cronManager和服务/控制器,但服务/控制器将不依赖于cron管理器。 由于所有文件都有一个cron,因此最好通过某些线程执行程序或@Async服务/方法并行执行此代码。
您也可以使用春季活动。在conroller / service中使用发送自定义事件AddNewCity并在CronManager中为此事件添加侦听器,并将城市从事件源放入城市集。
@Controller
public class myFirstController {
@Autowired
private CronManager cron;
@RequestMapping("/temperature")
public String whatIsTheTemperature(Model model,
@RequestParam(value = "city",required = false,defaultValue = "World") String city)
throws IOException {
model.addAttribute("city", city);
WeatherApp data = new WeatherApp();
myCron.addCity(city);
return data.getTemperatureForCity(city);
}
}