Java Intro to Java Web Development with Spark Bells and Whistles Build Your Own Flash Messages

Ben Foster
Ben Foster
7,697 Points

My get request is executing twice for "/", any ideas why?

Here is my get request code for the path "/":

get("/", (req, res) -> { Map<String, String> model = new HashMap<>(); model.put("username", req.cookie("username")); model.put("flashMessage", captureFlashMessage(req)); System.out.println("flash message added to model"); return new ModelAndView(model, "index.hbs"); }, new HandlebarsTemplateEngine());

When I run this and navigate to http://localhost:4567/, the console prints "flash message added to model twice. So my capture is executing twice and thus deleting my message once it displays. Any ideas here? Been beating my head against the wall on this one.

Here is my complete 'Main.java' for reference:

public class Main { private static final String FLASH_MESSAGE_KEY = "flash_message";

public static void main(String[] args) {
    staticFileLocation("/public");
    CourseIdeaDAO dao = new SimpleCourseIdeaDAO();

    before((req, res) -> {
        if(req.cookie("username") != null){
            req.attribute("username", req.cookie("username"));
        }
    });

    before("/ideas", (req, res) -> {
       if(req.attribute("username") == null) {
           setFlashMessage(req, "Oops, you're not signed in! Please sign in to see this page.");
           res.redirect("/");
           halt();
       }
    });

    get("/", (req, res) -> {
        Map<String, String> model = new HashMap<>();
        model.put("username", req.cookie("username"));
        model.put("flashMessage", getFlashMessage(req));
        System.out.println("flash message added to model");
        return new ModelAndView(model, "index.hbs");
    }, new HandlebarsTemplateEngine());

    post("/sign-in", (req, res) -> {
        Map<String, String> model = new HashMap<>();
        String username = req.queryParams("username");
        res.cookie("username", username);
        model.put("username", username);
        res.redirect("/");
        return null;
    });

    get("/ideas", (req, res) -> {
        Map<String, Object> model = new HashMap<>();
        model.put("ideas", dao.findAll());
        model.put("flashMessage", captureFlashMessage(req));
        return new ModelAndView(model, "ideas.hbs");
    }, new HandlebarsTemplateEngine());

    post("/ideas", (req, res) -> {
        String title = req.queryParams("title");
        CourseIdea idea = new CourseIdea(title, req.attribute("username"));
        dao.add(idea);
        res.redirect("/ideas");
        return null;
    });

    post("/ideas/:slug/vote", (req, res) -> {
        CourseIdea idea = dao.findBySlug(req.params("slug"));
        boolean added = idea.addVoter(req.attribute("username"));
        if(added) {
            setFlashMessage(req, "Thanks for voting! Your vote has been added to " + idea.getTitle() + ".");
        }else{
            setFlashMessage(req, "Not so fast, my friend! You already voted for " + idea.getTitle() + ".");
        }
        res.redirect("/ideas");
        return null;
    });

    get("/ideas/:slug", (req, res) -> {
        Map<String, Object> model = new HashMap<>();
        model.put("idea", dao.findBySlug(req.params("slug")));
        return new ModelAndView(model, "idea.hbs");
    }, new HandlebarsTemplateEngine());

    exception(NotFoundException.class, (exc, req, res) -> {
        res.status(404);
        HandlebarsTemplateEngine engine = new HandlebarsTemplateEngine();
        String html = engine.render(new ModelAndView(null, "not-found.hbs"));
        res.body(html);
    });
}

private static void setFlashMessage(Request req, String message) {
    req.session().attribute(FLASH_MESSAGE_KEY, message);
}

private static String getFlashMessage(Request req){
    if(req.session(false) == null)
        return null;

    if(!req.session().attributes().contains(FLASH_MESSAGE_KEY))
        return null;

    System.out.println("get executed");
    return (String) req.session().attribute(FLASH_MESSAGE_KEY);
}

private static String captureFlashMessage(Request req){
    String message = getFlashMessage(req);

    if(message != null)
        req.session().removeAttribute(FLASH_MESSAGE_KEY);

    System.out.println("capture executed");
    return message;
}

}

1 Answer

Ben Foster
Ben Foster
7,697 Points

Well I have no idea what I did to fix it, but now it's working.

Kareem Jeiroudi
Kareem Jeiroudi
14,981 Points

I'm sorry, I couldn't reproduce your issue. I took your main method code and did the following:

  1. Delete the username attribute in my browser
  2. Restart the server
  3. Head to localhost:4567/ideas without having logged in The flash message would show up, however, when looking at the system output, it shows only one call for get("/")

get method output

One remark I'd like to make - and I hope you've resolved this already - but when running this main code, the flash message isn't properly captured. E.g. When trying to login, after it shows up in step 3, the old message remains there.

Flash Message Prompt