spring boot web 在 Heroku 上最重要的功能,但在本地主机上运行良好
springboot web lost important function on Heroku, but work well in localhost
在我的本地主机上,我的网络工作正常,如下所示:
view run on localhost
控制器可以正常绑定货币列表到select框。
但是当我部署到 Heroku 时,控制器似乎永远找不到正确的列表来绑定到 thymeleaf。所以 selection 框留空:
view run on heroku
这是我的控制器:
@Autowired MoneyConverter moneyConverter;
@GetMapping("/")
public String renderForm(Model model) {
model.addAttribute("moneyConvertRequest", new MoneyConvertRequest());
List<CurrencyRate> currencies = moneyConverter.mapCurrencyRates();
model.addAttribute("currencies", currencies);
return "form";
}
并且在服务中,我的程序从 JSON 和 CSV 中读取文件以将数据解析为散列映射 link 到货币数据对象,如下所示:
private JsonNode masterNode;
private HashMap<String, CurrencyRate> mapCurrencyRates;
public MoneyConverter() {
loadExchangeRateFromJSON();
loadCurrencyCodeFromCSV();
}
private void loadExchangeRateFromJSON() {
try {
File file = new ClassPathResource("static/exchange_rate.json").getFile();
FileReader reader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(reader);
ObjectMapper objectMapper = new ObjectMapper();
masterNode = objectMapper.readTree(bufferedReader);
} catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
public void loadCurrencyCodeFromCSV() {
mapCurrencyRates = new HashMap<>();
try {
File file = new ClassPathResource("static/currency.csv").getFile();
CsvMapper mapper = new CsvMapper();
CsvSchema schema = CsvSchema.emptySchema().withHeader();
ObjectReader oReader = mapper.readerFor(CurrencyRate.class).with(schema);
Reader reader = new FileReader(file);
MappingIterator<CurrencyRate> mi = oReader.readValues(reader);
while (mi.hasNext()) {
CurrencyRate currencyRate = mi.next();
String currencyCode = currencyRate.getCode();
if (mapCurrencyRates.get(currencyCode) == null) {
float rate = getExchangeRate(currencyCode); JSON
if (rate > 0.0f) {
currencyRate.setRate(rate);
mapCurrencyRates.put(currencyCode, currencyRate);
}
}
}
} catch (IOException e) {
System.out.println(e);
}
}
我猜测可能是 heroku 环境和我的本地主机之间的依赖版本不匹配
这是我的 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>vn.techmaster</groupId>
<artifactId>money</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>money</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.18.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
关于如何在 Heroku 上修复此错误的任何建议。谢谢!
您不应该将资源作为文件读取,因为当它们被打包在一个 jar 文件中时(就像 运行 在 Heroku 上的情况一样)这将不再有效。
作为替代方案,将文件作为流读取:
InputStream inputStream = getClass().getResourceAsStream(...)
在我的本地主机上,我的网络工作正常,如下所示: view run on localhost
控制器可以正常绑定货币列表到select框。 但是当我部署到 Heroku 时,控制器似乎永远找不到正确的列表来绑定到 thymeleaf。所以 selection 框留空: view run on heroku
这是我的控制器:
@Autowired MoneyConverter moneyConverter;
@GetMapping("/")
public String renderForm(Model model) {
model.addAttribute("moneyConvertRequest", new MoneyConvertRequest());
List<CurrencyRate> currencies = moneyConverter.mapCurrencyRates();
model.addAttribute("currencies", currencies);
return "form";
}
并且在服务中,我的程序从 JSON 和 CSV 中读取文件以将数据解析为散列映射 link 到货币数据对象,如下所示:
private JsonNode masterNode;
private HashMap<String, CurrencyRate> mapCurrencyRates;
public MoneyConverter() {
loadExchangeRateFromJSON();
loadCurrencyCodeFromCSV();
}
private void loadExchangeRateFromJSON() {
try {
File file = new ClassPathResource("static/exchange_rate.json").getFile();
FileReader reader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(reader);
ObjectMapper objectMapper = new ObjectMapper();
masterNode = objectMapper.readTree(bufferedReader);
} catch (FileNotFoundException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
public void loadCurrencyCodeFromCSV() {
mapCurrencyRates = new HashMap<>();
try {
File file = new ClassPathResource("static/currency.csv").getFile();
CsvMapper mapper = new CsvMapper();
CsvSchema schema = CsvSchema.emptySchema().withHeader();
ObjectReader oReader = mapper.readerFor(CurrencyRate.class).with(schema);
Reader reader = new FileReader(file);
MappingIterator<CurrencyRate> mi = oReader.readValues(reader);
while (mi.hasNext()) {
CurrencyRate currencyRate = mi.next();
String currencyCode = currencyRate.getCode();
if (mapCurrencyRates.get(currencyCode) == null) {
float rate = getExchangeRate(currencyCode); JSON
if (rate > 0.0f) {
currencyRate.setRate(rate);
mapCurrencyRates.put(currencyCode, currencyRate);
}
}
}
} catch (IOException e) {
System.out.println(e);
}
}
我猜测可能是 heroku 环境和我的本地主机之间的依赖版本不匹配 这是我的 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>vn.techmaster</groupId>
<artifactId>money</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>money</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.18.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
关于如何在 Heroku 上修复此错误的任何建议。谢谢!
您不应该将资源作为文件读取,因为当它们被打包在一个 jar 文件中时(就像 运行 在 Heroku 上的情况一样)这将不再有效。
作为替代方案,将文件作为流读取:
InputStream inputStream = getClass().getResourceAsStream(...)