A problem occurs when I try to make POST request by an html page using thymeleaf. A controller should receive an input as an enum, but it throws an error:
java.lang.NoSuchMethodException: com.trade_analysis.model.StockSymbol.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3427) ~[na:na]"
I don't know what's not ok. I have seen some examples and have tried many things but I can't make it work as it should.
HTML:
<select class="form-item" th:field="${symbol}" required>
<option value="" selected disabled hidden id="default-symbol">Symbol</option>
<option class="dropdown-menu-button" th:each="symbolOption: ${symbols}" th:value="${symbolOption}" th:text="${symbolOption}"></option>
</select>
Java controler:
@GetMapping(value = "/stocks")
@PreAuthorize(value = "isAuthenticated()")
public String getStockPrices(Model model) throws UserNotFoundException {
User user = userService.getUserByUsername(getUsername());
String apiKey = user.getApiKey() == null ? "" : user.getApiKey();
model.addAttribute("apiKey", apiKey);
model.addAttribute("symbol", "");
model.addAttribute("symbols", asList(StockSymbol.values()));
return "stock-prices-preview";
}
@PostMapping(value = "/stocks")
@PreAuthorize(value = "isAuthenticated()")
public String stockPrices(@ModelAttribute String apiKey, @ModelAttribute StockSymbol symbol, Model model) {
model.addAttribute("apiKey", apiKey);
model.addAttribute("symbol", symbol);
model.addAttribute("symbols", asList(StockSymbol.values()));
return "stock-prices-preview";
}
'StockSymbol' enum:
public enum StockSymbol {
GOOGL("GOOGL"),
MSFT("MSFT"),
AMZN("AMZN"),
IBM("IBM"),
CSCO("CSCO"),
AAPL("AAPL");
String sys;
StockSymbol(String sys) {
this.sys = sys;
}
}
First few lines of error (full error is on: https://pastebin.com/kg8RR7G6)
java.lang.NoSuchMethodException: com.trade_analysis.model.StockSymbol.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3427) ~[na:na]
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2631) ~[na:na]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:216) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
In your POST
handler you have this line:
public String stockPrices(@ModelAttribute String apiKey, @ModelAttribute StockSymbol symbol, Model model) {
Remove the @ModelAttribute
annotation. Your problem is that Spring tries to instantiate the enum when it runs the controller method.
Use @RequestParam
to obtain the incoming POST
parameter by name. You might need to specify the parameter name in the annotation if your compiler doesn't use the -parameters
switch.