2

I have a problem with the web application. I am a student and still learning. This is a simple forum, with login, registration, adding new topics and posts. It is also possible to remove the topic GetMapping method that works without problems. Unfortunately, I got a command to change the GetMapping to Delete and after the change gets an error in the application of the content:   "There was an unexpected error (type = Method Not Allowed, status = 405). Request method 'GET' not supported ' I was looking on the internet to solve this problem, but after checking the various options, it is still the same error. Am not also experienced enough in this topic, therefore a lot of the instructions for me was unclear. So please help.

So this is topic.html view before changes for delete:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Forum - Topic</title>
</head>
<body background="http://2.bp.blogspot.com/-BsL9gRE80Ug/U0OgeWbbxtI/AAAAAAAAF-w/teXrzw-TBcU/s1600/nacre-background-tile.jpg">
<table class="table table-striped">
<a href="http://localhost:8080/forum">Powrot</a>
  <tr>
   <th>Title: </th>
 <th><p th:text="${topicName}" /></th>
  </tr>
  <tr>
 <td th:text="${topicAuthor}" ></td>
 <td th:text="${topicDate}" ></td>
 <table border="1">
 <td th:text="${topicContent}"></td>
 </table>
  </tr>
  <table>
    <br><b>-------------------------------------------------------</b></br>
    <a th:href="@{/new_message(id=${topicId})}">Add new post</a>
    <br><a th:href="@{/delete(id=${topicId})}">Delete this topic</a></br>
    <br><b>-------------------------------------------------------</b></br>
  </table>
</table>
<table class="table table-striped">
  <tr th:each="message,iterStat : ${list}">
    <td th:text="${message.author}"></td>
    <td th:text="${message.date}"></td>
    <table border="1">
     <td th:text="${message.content}"></td>
    </table>
    <table>
     <p> - - - - - - - - </p>
    </table>
  </tr>
</table>
</body>
</html>

and after changes:

...
    <table>
        <br><b>-------------------------------------------------------</b></br>
        <a th:href="@{/new_message(id=${topicId})}">Add new post</a>
        <form action="#" th:action="@{/delete(id=${topicId})}" method="delete">
      <br><a th:href="@{/delete(id=${topicId})}">Delete this topic</a></br>
  </form>
        <br><b>-------------------------------------------------------</b></br>
    </table>
...

Also I edited the controller. This is a previous, working version with getMapping:

@Controller public class TopicController
{
@Autowired
private TopicRepository topicRepository;

@Autowired
private MessageRepository messageRepository;

@Autowired
private UserRepository userRepository;

@GetMapping("/delete")
public String deleteTopic(@CookieValue(value = "userId", defaultValue = "-1") String userId, 
        @RequestParam("id") String topicId, Model model)
{
    if(userId.equals("-1"))
    {
        model.addAttribute("user", new User());
        return "login";           
    }
    else
    {
        Topic topic = topicRepository.findByIdIn(Integer.parseInt(topicId));
        if(topic.getUserId() == Integer.parseInt(userId)) 
        {
            topicRepository.delete(topic);
        }
        return "redirect:/forum";
    }

}

}

And the new version, that does not work:

@RequestMapping(value = "/{delete}", method = RequestMethod.DELETE)
public @ResponseBody String deleteTopic(@CookieValue(value = "userId", defaultValue = "-1") String userId, 
        @RequestParam("id") String topicId, @ModelAttribute Topic topic, Model model)
{
    if(userId.equals("-1"))
    {
        model.addAttribute("user", new User());
        return "login";           
    }
    else
    {
        Topic topicDB = topicRepository.findByIdIn(Integer.parseInt(topicId));
        if(topicDB.getUserId() == Integer.parseInt(userId)) 
        {
            topicRepository.delete(topicDB);
        }
        return "redirect:/forum";
    }
}

1 Answers1

0

The DELETE method is not supported in HTML forms. So when you write the below, your browser just uses a normal GET.

<form action="#" th:action="@{/delete(id=${topicId})}" method="delete">

Use the POST method because you change data on the server. If you want to make the application think a DELETE method was used, use the HiddenHttpMethodFilter with a hidden field like this:

<form action="#" th:action="@{/delete(id=${topicId})}" method="post">
    <input type="hidden" name="_method" value="delete">
    <br><a th:href="@{/delete(id=${topicId})}">Delete this topic</a></br>
</form>

If you use thymeleaf-spring >= 2.0.3 you can use the th:method attribute and thymeleaf will create the hidden field automatically if required.

<form action="#" th:action="@{/delete(id=${topicId})}" th:method="delete">
    <br><a th:href="@{/delete(id=${topicId})}">Delete this topic</a></br>
</form>
René Scheibe
  • 1,970
  • 2
  • 14
  • 20
  • hmm maybe I am doing something wrong, but none of these methods did not help :( – Mastrin1994 Feb 26 '17 at 22:49
  • Did you register the HiddenHttpMethodFilter correctly? Have a look in the documentation (http://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-add-a-servlet-filter-or-listener) for details. This answer (http://stackoverflow.com/a/26157610/2847174) contains an example for another filter. – René Scheibe Feb 27 '17 at 11:48
  • So, i was talking with my teacher and he told me that i have two options. 1. Make javascript and then use delete, or 2. Make new Controller, just delete and then just use Postman to check that controller work correct. I chose the second option and was able to do the job. I got a positive assessment of the subject so you can consider this as part of the solution. – Mastrin1994 Mar 01 '17 at 12:18