java – thymeleaf “Attempting to repost information that was already created”

I have created an app to create blog posts. Now I am attempting to update the application to do CRUD functionality. The original application is still working of which I have included a screen shot.

Blog Home screen

From their I can login and logout or I can create a new post. When I select a given username it should list all the post by username. See below:

Blog posts by username

From here I can select a particular blog post of which will pull up that blog post by username and it. Also, in this screen I have modified the thymeleaf to allow me to either edit the blog post or delete the blog post. See below:

Blog post by username and uid

When I click on edit this is the result of that action. What I am trying to do is pass the information from the single post page into a new thymeleaf template and allow the information to be edited. Once the edited information has been done to go ahead and re-save the information. see below:

Blog posts edit by username and uid

I am wondering what I am doing wrong. I will included my postcontroller.java, editpost.html, post.html, postdao.java.

package org.launchcode.blogz.controllers;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.launchcode.blogz.models.Post;
import org.launchcode.blogz.models.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class PostController extends AbstractController {

    @RequestMapping(value = "/blog/newpost", method = RequestMethod.GET)
    public String newPostForm() {
        return "newpost";
    }

    @RequestMapping(value = "/blog/newpost", method = RequestMethod.POST)
    public String newPost(HttpServletRequest request, Model model) {

        // TODO - implement newPost
        // get request parameters
        String title = request.getParameter("title");
        String body = request.getParameter("body");

        // get user from their session
        HttpSession newSession = request.getSession();
        User author = getUserFromSession(newSession);

        // validate parameters
        // if valid, create new Post
        // if not valid, send back to the form, with an error message

        if (title == null || title.isEmpty()) {
            model.addAttribute("error", "The title is missing from this post. Please enter a title.");
            return "newpost";
        }

        if (body == null || body.isEmpty()) {
            model.addAttribute("title", title);
            model.addAttribute("error", "The body of the post needs some content. Please enter some content for this post.");
            return "newpost";
        }

        // save the user's post
        Post post = new Post(title, body, author);
        postDao.save(post);

        // TODO - this redirect should go to the new post's page
        return "redirect:/blog/" + author.getUsername() + "/" + post.getUid();
    }

    @RequestMapping(value = "/blog/{username}/{uid}", method = RequestMethod.GET)
    public String singlePost(@PathVariable String username, @PathVariable int uid, Model model) {

        // TODO - implement singlePost
        // get the given parameters

        Post post = postDao.findByUid(uid);

        // get the given post
        // pass the post into the template

        model.addAttribute("error", "");
        model.addAttribute("post", post);

        return "post";
    }

    @RequestMapping(value = "/blog/{username}", method = RequestMethod.GET)
    public String userPosts(@PathVariable String username, Model model) {

        // TODO - implement userPosts
        // get all of the user's posts

        User user = userDao.findByUsername(username);
        List<Post> posts = user.getPosts();

        // pass the posts into the template

        model.addAttribute("posts", posts);

        return "blog";
    }

    @RequestMapping(value = "/blog/editpost/{username}/{uid}", method = RequestMethod.GET)
    public String editPostForm(@PathVariable String username, @PathVariable int uid, Model model){

        return "editPost";
    }

    @RequestMapping(value = "/blog/editpost/{username}/{uid}", method = RequestMethod.POST)
    public String editPost(HttpServletRequest request, @PathVariable String username, @PathVariable int id, Model model) {

        // TODO - implement newPost
        // get request parameters
        String title = request.getParameter("title");
        String body = request.getParameter("body");

        // get user from their session
        HttpSession newSession = request.getSession();
        User author = getUserFromSession(newSession);

        // validate parameters
        // if valid, create new Post
        // if not valid, send back to the form, with an error message

        if (title == null || title.isEmpty()) {
            model.addAttribute("error", "The title is missing from this post. Please enter a title.");
            return "editPost";
            }

        if (body == null || body.isEmpty()) {
            model.addAttribute("title", title);
            model.addAttribute("error", "The body of the post needs some content. Please enter some content for this post.");
            return "editPost";
            }

        // save the user's post
        Post post = new Post(title, body, author);
        postDao.save(post);

        // TODO - this redirect should go to the new post's page
        return "redirect:/blog/" + author.getUsername() + "/" + post.getUid();
    }

//    @RequestMapping(value = "/blog/deletepost")
//    public String deleteByUid(@PathVariable("uid") long id, Model model) {
//        String deleteSQL = "DELETE post WHERE uid = ${post.uid}";
//        PreparedStatement preparedStatement = dbConnection.prepareStatement(deleteSQL);
//        // execute delete SQL stetement
//        preparedStatement.executeUpdate();
//        return "index";
//    }

}

the above code is my controller

next is my editpost.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org/">
<head th:replace="template :: dochead">
</head>
<body>

    <div th:replace="template :: navigation"></div>

    <h2>Edit Post</h2>

    <form method="post" th:object="$[post}">
        <label>
            <div>title</div>
            <input type="text" name="title" class="post-title" th:text="${post.title}"></input>"post-title" th:text="${post.title}"
        </label>
        <label>
            <div>post</div>
            <textarea name="body" class="post-body" th:text="${post.body}"></textarea>
        </label>
        <div class="error" th:text="${error}"></div>
        <button type="submit">Save</button>
    </form>

</body>
</html>

the next code segment will be my post.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org/">
<head th:replace="template :: dochead">
</head>
<body>

    <div th:replace="template :: navigation"></div>

    <h2>A Single Post</h2>

    <!-- TODO - display a single blog post -->
    <h3 class="post-title" th:text="${post.title}"></h3>
    <p class="post-body" th:text="${post.body}"></p>

    <div class="error" th:text="${error}"></div>

    <a href="@{/blog/editpost/${username}/${uid}">Edit</a>
    <a href="/blog/deletepost">Delete</a>

    <p class="footer">This post was created by <a th:href="'/blog/' + ${post.author.username}" th:text="${post.author.username}"></a> on the date <em><span th:text="${#dates.format(post.modified, 'yyyy-MM-dd hh:mm:ss')}"></span></em></p>

</body>
</html>

the final code segment will be my postdao.java

package org.launchcode.blogz.models.dao;

import java.util.List;

import javax.transaction.Transactional;

import org.launchcode.blogz.models.Post;
import org.launchcode.blogz.models.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Transactional
@Repository
public interface PostDao extends CrudRepository<Post, Integer> {

    List<Post> findByAuthor(User authorId);

    // TODO - add method signatures as needed

    Post findByUid(int uid);
    List<Post> findAll();
    void deleteByUid(int uid);

}

I hope someone can help me with this I would truly appreciate it.

Answer

There is an error at your editpost.html. Notice your browser URL after you press the Edit button, it is

localhost:8080/blog/jfreynolds/@{/blog/editpost/${username}/${uid}

instead of

localhost:8080/blog/editpost/jreynolds/2

Simply add “th:” before your href below so that your expression can work.

<a th:href="@{/blog/editpost/${username}/${uid}">Edit</a>

Leave a Reply

Your email address will not be published. Required fields are marked *