Add an author

Now, let's implement a new view to facilitate adding authors. Add the following route to Server.main:

get("/addauthor", (req, res) -> {
Map<String, Object> model = new HashMap<String, Object>();
return new ModelAndView(model, "public/templates/addauthor.vm");
}, new VelocityTemplateEngine());

Next, we need to implement a http post endpoint for the /addauthor route:

post("/addauthor", (req, res) -> {
Map<String, Object> model = new HashMap<String, Object>();
String name = req.queryParams("name");
int numOfBooks = Integer.parseInt(req.queryParams("numOfBooks"));
String nationality = req.queryParams("nationality");
Author author = new Author(name, numOfBooks, nationality);
try {
int id = new Sql2oAuthorDao(sql2o).add(author);
if (id > 0) {
model.put("added", "true");
}
else {
model.put("failedAdd", "true");
}
}
catch (DaoException ex) {
model.put("failedAdd", "true");
}
ModelAndView mdl = new ModelAndView(model, "public/templates/addauthor.vm");
return new VelocityTemplateEngine().render(mdl);
});

On this endpoint, we first parse the query parameters to create an author object which we insert into Authors table using our Sql2oAuthorDao.add. Then, we check if the author was inserted successfully in which case, in our model, we set added flag to ture. Otherwise, we set failedAdd to true. These flags are then used in src/main/resources/templates/addauthor.vm to show appropriate messages to the user. The following is the content of addauthor.vm file:

#set($title = "Add Author")
#parse("public/templates/top.vm")
#if($added)
<h2>Author was successfully added!</h2>
<br />
#end
#if($failedAdd)
<h2>Failed to add the Author!</h2>
<br />
#end
<h2>Add a new Author</h2>
<form action="/addauthor" method="post" class="content" id="formAddAuthor">
<div>
<label for="name">Name: </label>
<input type="text" name="name" placeholder="name" id="name" required>
</div>
<div>
<label for="nationality">Nationality: </label>
<input type="text" name="nationality" placeholder="nationality" id="nationality" />
</div>
<div>
<label for="numOfBooks">Number of books: </label>
<input type="number" name="numOfBooks" placeholder="1" id="numOfBooks" min="1" max="200"/>
</div>
<br />
<input type="submit" value="Add" id="submitAddAuthor" />
</form>
#parse("public/templates/bottom.vm")

Now, point your browser to /addauthor route and try to add an author.

Controller Code

You might have noticed our Server.main() is getting very long. In general, Server.main() is not the best place to receive http requests and process them. It would be sensible to move the "controller" code somewhere else. One viable approach is to introduce a new Java package named controller under src/main/java and create class(es) that contain controller code. Then, we just receive http requests in the Server class, but then we route those requests to suitable function(s) in the controller classes.

info

To get more details on Apache Velocity, refer to the user guide.