Issue
I've been trying to submit an html form to spring boot but can't get it working.
I have this in my pom.xml
<!-- Enable JSP with Spring Boot -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
I have this in my application.properties file:
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
I have created a jsp page in <project-name>/src/main/webapp/WEB-INF/views/index.jsp
At the very top of that page, I put
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
I also have a similar html file called index.html located in
<project-name>/src/main/resources/static/index.html
But the code doesn't seem to be recognizing the taglib because I see this in the web page:
Notice how the taglib is not recognized and just prints it at the top of the page?
So I delete the index.html page to force it to find the index.jsp file instead. In that case I see the following error in the web page:
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Oct 18 11:11:20 MDT 2020 There was an unexpected error (type=Internal Server Error, status=500). Neither BindingResult nor plain target object for bean name 'watchlist' available as request attribute
Here is the part of the jsp file that sends the form:
<dialog id="favDialog">
<form:form method="POST" action="/api/v1/AddSymbolToWatchlist" modelAttribute="watchlist">
<form:label path="symbol">Enter Symbol:</form:label>
<form:input path="symbol"/><br><br>
<form:button>Add</form:button>
</form:form>
</dialog>
My spring boot controller looks like this:
@RequestMapping(value = "/AddSymbolToWatchlist", method = RequestMethod.POST)
public String addSymbolToWatchlist(@Valid @ModelAttribute("watchlist") Watchlist watchlist,
BindingResult result, ModelMap modelMap) {
if (result.hasErrors()) {
return "error";
}
System.out.println("symbol="+watchlist.getSymbol());
return watchlistService.addSymbolToWatchlist(watchlist);
}
The error seems to imply that I have already clicked the button that posts the request, but I haven't.
What am I doing wrong?
EDIT Per gtiwari333 response I changed the controller to look like this:
@RequestMapping(value = "/AddSymbolToWatchlist", method = RequestMethod.POST)
public String addSymbolToWatchlist(@ModelAttribute("watchlist") Watchlist watchlist, Model m){
String symbol = watchlist.getSymbol();
System.out.println("symbol=" +symbol);
Watchlist wlist = new Watchlist();
wlist.setSymbol(symbol);
m.addAttribute("msg", symbol +" was submitted.");
m.addAttribute("watchlist", wlist);
return "index";
}
class Watchlist {
String symbol;
public String getSymbol() {
return symbol;
}
public void setSymbol(String sym) {
this.symbol = sym;
}
}
And the popup form in index.jsp looks like this:
<dialog id="favDialog">
<h2>Message: ${msg}</h2>
<form:form method="POST" action="/api/v1/AddSymbolToWatchlist" modelAttribute="watchlist">
<form:label path="symbol">Enter Symbol:</form:label>
<form:input path="symbol"/><br><br>
<form:button>Add</form:button>
</form:form>
</dialog>
Solution
If you use modelAttribute="watchlist"
on your jsp, you must return the Model with attribute watchlist
as following
@GetMapping("/")
String index(Model m) {
// you should have this so that modelAttribute="watchlist" on jsp renders
m.addAttribute("watchlist", new Watchlist());
return "myjspform";
}
Here's working code:
package soquestion64416269;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Controller
@RequiredArgsConstructor
class Ctrl {
@GetMapping("/")
String index(Model m) {
m.addAttribute("msg", "Enter symbol and click Add");
m.addAttribute("watchlist", new Watchlist());
return "myjspform";
}
@PostMapping(value = "/AddSymbolToWatchlist")
public String addSymbolToWatchlist(@ModelAttribute("watchlist") Watchlist watchlist, Model m) {
m.addAttribute("msg", watchlist.getSymbol() + " was submitted. Now enter new symbol and click Add");
m.addAttribute("watchlist", new Watchlist());
return "myjspform";
}
}
@Data
class Watchlist {
String symbol;
}
myjspform.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html lang="en">
<body>
<h2>Message: ${msg}</h2>
<form:form method="POST" action="/AddSymbolToWatchlist" modelAttribute="watchlist">
<form:label path="symbol">Enter Symbol:</form:label>
<form:input path="symbol"/><br><br>
<form:button>Add</form:button>
</form:form>
</body>
</html>
Answered By - gtiwari333
Answer Checked By - Clifford M. (JavaFixing Volunteer)